1
2
3
4
5 package moreland
6
7 import (
8 "fmt"
9 "image/color"
10 "testing"
11
12 "golang.org/x/exp/rand"
13
14 "gonum.org/v1/gonum/floats/scalar"
15 )
16
17 func TestCreateLuminance(t *testing.T) {
18 type testHolder struct {
19 controlColors []color.Color
20 want *luminance
21 name string
22 }
23 tests := []testHolder{
24 {
25 name: "BlackBody",
26 controlColors: []color.Color{
27 color.NRGBA{0, 0, 0, 255},
28 color.NRGBA{178, 34, 34, 255},
29 color.NRGBA{227, 105, 5, 255},
30 color.NRGBA{238, 210, 20, 255},
31 color.NRGBA{255, 255, 255, 255},
32 },
33 want: BlackBody().(*luminance),
34 },
35 {
36 name: "ExtendedBlackBody",
37 controlColors: []color.Color{
38 color.NRGBA{0, 0, 0, 255},
39 color.NRGBA{0, 24, 168, 255},
40 color.NRGBA{99, 0, 228, 255},
41 color.NRGBA{220, 20, 60, 255},
42 color.NRGBA{255, 117, 56, 255},
43 color.NRGBA{238, 210, 20, 255},
44 color.NRGBA{255, 255, 255, 255},
45 },
46 want: ExtendedBlackBody().(*luminance),
47 },
48 {
49 name: "Kindlmann",
50 controlColors: []color.Color{
51 color.NRGBA{0, 0, 0, 255},
52 color.NRGBA{46, 4, 76, 255},
53 color.NRGBA{63, 7, 145, 255},
54 color.NRGBA{8, 66, 165, 255},
55 color.NRGBA{5, 106, 106, 255},
56 color.NRGBA{7, 137, 169, 255},
57 color.NRGBA{8, 168, 26, 255},
58 color.NRGBA{84, 194, 9, 255},
59 color.NRGBA{196, 206, 10, 255},
60 color.NRGBA{252, 220, 197, 255},
61 color.NRGBA{255, 255, 255, 255},
62 },
63 want: Kindlmann().(*luminance),
64 },
65 {
66 name: "ExtendedKindlmann",
67 controlColors: []color.Color{
68 color.NRGBA{0, 0, 0, 255},
69 color.NRGBA{44, 5, 103, 255},
70 color.NRGBA{3, 67, 67, 255},
71 color.NRGBA{5, 103, 13, 255},
72 color.NRGBA{117, 124, 6, 255},
73 color.NRGBA{246, 104, 74, 255},
74 color.NRGBA{250, 149, 241, 255},
75 color.NRGBA{232, 212, 253, 255},
76 color.NRGBA{255, 255, 255, 255},
77 },
78 want: ExtendedKindlmann().(*luminance),
79 },
80 }
81 for _, test := range tests {
82 cmap, err := NewLuminance(test.controlColors)
83 if err != nil {
84 t.Fatal(err)
85 }
86 if !luminanceEqualWithin(cmap.(*luminance), test.want, 1.0e-14) {
87 t.Errorf("%s: have %#v, want %#v", test.name, cmap, test.want)
88 }
89 }
90 }
91
92 func luminanceEqualWithin(a, b *luminance, tol float64) bool {
93 if len(a.colors) != len(b.colors) {
94 return false
95 }
96 if len(a.scalars) != len(b.scalars) {
97 return false
98 }
99 for i, ac := range a.colors {
100 if !cieLABEqualWithin(ac, b.colors[i], tol) {
101 return false
102 }
103 }
104 for i, av := range a.scalars {
105 if !scalar.EqualWithinAbsOrRel(av, b.scalars[i], tol, tol) {
106 return false
107 }
108 }
109 return scalar.EqualWithinAbsOrRel(a.alpha, b.alpha, tol, tol) &&
110 scalar.EqualWithinAbsOrRel(a.max, b.max, tol, tol) &&
111 scalar.EqualWithinAbsOrRel(a.min, b.min, tol, tol)
112 }
113
114 func cieLABEqualWithin(a, b cieLAB, tol float64) bool {
115 return scalar.EqualWithinAbsOrRel(a.L, b.L, tol, tol) &&
116 scalar.EqualWithinAbsOrRel(a.A, b.A, tol, tol) &&
117 scalar.EqualWithinAbsOrRel(a.B, b.B, tol, tol)
118 }
119
120 func TestExtendedBlackBody(t *testing.T) {
121 scalars := []float64{0, 0.21873483862751875, 0.34506542513775906, 0.4702980511087303, 0.6517482203230537, 0.8413253643355525, 1}
122 want := []color.Color{
123 color.NRGBA{0, 0, 0, 255},
124 color.NRGBA{0, 24, 168, 255},
125 color.NRGBA{99, 0, 228, 255},
126 color.NRGBA{220, 20, 60, 255},
127 color.NRGBA{255, 117, 56, 255},
128 color.NRGBA{238, 210, 20, 255},
129 color.NRGBA{255, 255, 255, 255},
130 }
131
132 colors := ExtendedBlackBody()
133 colors.SetMax(1)
134
135 for i, scalar := range scalars {
136 c, err := colors.At(scalar)
137 if err != nil {
138 t.Fatal(err)
139 }
140 if !similar(c, want[i], bitTolerance) {
141 t.Errorf("color %d: have %+v, want %+v", i, c, want[i])
142 }
143 }
144 }
145
146 func BenchmarkLuminance_At(b *testing.B) {
147 pBase := ExtendedBlackBody()
148 for n := 2; n < 12; n += 2 {
149 p, err := NewLuminance(pBase.Palette(n).Colors())
150 if err != nil {
151 b.Fatal(err)
152 }
153 p.SetMax(1)
154 rand.Seed(1)
155 b.Run(fmt.Sprintf("%d controls", n), func(b *testing.B) {
156 for i := 0; i < b.N; i++ {
157 if _, err := p.At(rand.Float64()); err != nil {
158 b.Fatal(err)
159 }
160 }
161 })
162 }
163 }
164
View as plain text