color/internal/helper/distance.go
2025-03-06 13:01:21 -05:00

47 lines
1.3 KiB
Go

package helper
import (
"image/color"
"math"
"slices"
)
func TestDistance[T tester[T], C color.Color](t T, alpha bool, midpoint func(c0, c1 C) C, f func(c0, c1 C) float64, m color.Model) {
colors := slices.Collect(EnumColor[C](alpha, false, m))
for i, c0 := range colors {
// a colour should have a distance of zero to itself.
if d := f(c0, c0); !EqFloat64Fuzzy(d, 0) {
t.Errorf("Distance(%#+v, %#+v) = %f, want 0", c0, c0, d)
return
}
for j := i + 1; j < len(colors); j++ {
c1 := colors[j]
d, d2 := f(c0, c1), f(c1, c0)
switch {
case math.IsNaN(d) || math.IsInf(d, 0):
t.Errorf("Distance(%#+v, %#+v) = %f, want finite", c0, c1, d)
return
case d < 0 || EqFloat64Fuzzy(d, 0):
t.Errorf("Distance(%#+v, %#+v) = %f, want > 0", c0, c1, d)
return
case !EqFloat64Fuzzy(d, d2):
t.Errorf("Distance(%#+v, %#+v) != Distance(%#+v, %#+v), want %f == %f", c1, c0, c0, c1, d, d2)
return
}
// traveling from c0 to c1 via mid can't possibly be
// shorter than traveling from c0 to c1 directly.
mid := midpoint(c0, c1)
if cumulative := f(c0, mid) + f(mid, c1); !(d < cumulative || EqFloat64Fuzzy(d, cumulative)) {
t.Errorf("Distance(%#+v, %#+v)+Distance(%#+v, %#+v) < Distance(%#+v, %#+v), want %f >= %f", c0, mid, mid, c1, c0, c1, cumulative, d)
return
}
}
}
}