diff --git a/math/math32.go b/math/math32.go index e3595618..2453a6cb 100644 --- a/math/math32.go +++ b/math/math32.go @@ -175,3 +175,46 @@ func Snap(f, multiple float32) float32 { func Pow(f, x float32) float32 { return float32(math.Pow(float64(f), float64(x))) } + +// NextPow2 returns the next power of 2 greater than n, or n if its a power of 2. +func NextPow2(n uint) uint { + n-- + n |= n >> 1 + n |= n >> 2 + n |= n >> 4 + n |= n >> 8 + n |= n >> 16 + n++ + return n +} + +// Ilog2 returns the uint32 value that is log2(v). +func Ilog2(v uint32) uint32 { + boolToUInt32 := func(b bool) uint32 { + if b { + return 1 + } + return 0 + } + + var r, shift uint32 + r = boolToUInt32(v > 0xffff) << 4 + v >>= r + shift = boolToUInt32(v > 0xff) << 3 + v >>= shift + r |= shift + shift = boolToUInt32(v > 0xf) << 2 + v >>= shift + r |= shift + shift = boolToUInt32(v > 0x3) << 1 + v >>= shift + r |= shift + r |= (v >> 1) + return r +} + +func ApproxEqual[F constraints.Float](v, v2 F) bool { + epsilon := F(0.0001) + d := v - v2 + return d*d < epsilon*epsilon +} diff --git a/math/vec2/operations.go b/math/vec2/operations.go index 46ef1b85..6cedcf75 100644 --- a/math/vec2/operations.go +++ b/math/vec2/operations.go @@ -22,6 +22,11 @@ func Distance(a, b T) float32 { return a.Sub(b).Length() } +// DistanceSqr returns the squared euclidian distance between two points. +func DistanceSqr(a, b T) float32 { + return a.Sub(b).LengthSqr() +} + func Min(a, b T) T { return T{ X: math.Min(a.X, b.X), diff --git a/math/vec2/vec2.go b/math/vec2/vec2.go index 789d9852..60036669 100644 --- a/math/vec2/vec2.go +++ b/math/vec2/vec2.go @@ -116,7 +116,7 @@ func (v T) Div(v2 T) T { func (v T) ApproxEqual(v2 T) bool { epsilon := float32(0.0001) - return Distance(v, v2) < epsilon + return DistanceSqr(v, v2) < epsilon*epsilon } func (v T) String() string { diff --git a/math/vec3/operations.go b/math/vec3/operations.go index 0b10548c..4508d329 100644 --- a/math/vec3/operations.go +++ b/math/vec3/operations.go @@ -55,6 +55,11 @@ func Distance(a, b T) float32 { return a.Sub(b).Length() } +// DistanceSqr returns the squared euclidian distance between two points. +func DistanceSqr(a, b T) float32 { + return a.Sub(b).LengthSqr() +} + func Mid(a, b T) T { return a.Add(b).Scaled(0.5) } diff --git a/math/vec3/vec3.go b/math/vec3/vec3.go index d0cd497a..88e30f38 100644 --- a/math/vec3/vec3.go +++ b/math/vec3/vec3.go @@ -197,7 +197,7 @@ func (v T) WithZ(z float32) T { func (v T) ApproxEqual(v2 T) bool { epsilon := float32(0.0001) - return Distance(v, v2) < epsilon + return DistanceSqr(v, v2) < epsilon*epsilon } func (v T) String() string {