Idea
Inspired by @ShubhamSrivastava comment, the idea is:
float32
coordinates would be rounded to a specific decimal point
Rationale
Since exact ==
and !=
comparisons (required by map key) are NOT proper for float, such comparisons make more sense when float32
is rounded consistently to a limited decimal point.
Implementation
I round my float32 fields inside Vertex
type by these methods to a specific decimal point:
// round floating point fields of my type to a specific decimal point
func vertRoundTo(vi Vertex, decimals uint32) (vo Vertex, err error) {
if vo.X, err = roundTo(vi.X, decimals); err != nil {
return Vertex{}, err
}
if vo.Y, err = roundTo(vi.Y, decimals); err != nil {
return Vertex{}, err
}
if vo.Z, err = roundTo(vi.Z, decimals); err != nil {
return Vertex{}, err
}
return
}
// round float32 to a specific decimal point
// https://stackoverflow.com/a/52048478/3405291
func roundTo(fi float32, decimals uint32) (fo float32, err error) {
if decimals < 1 {
err = errors.New("minimum decimal point is exceeded")
return
}
fo = float32(math.Round(float64(fi)*float64(decimals)) / float64(decimals))
return
}
I use the above methods like this:
// "cluster" is already filled with rounded floats
func (c *cluster) DoesClusterContainVertex(v Vertex) (does bool, err error) {
// coordinates would be rounded to a specific decimal point
// since exact == and != comparison is NOT proper for float
// such comparisons are required for map key
var vRound Vertex
if vRound, err = vertRoundTo(v, 4); err != nil {
return
}
if _, ok := c.verts[vRound]; ok {
// cluster contains vertex
does = true
}
return
}