1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package s1
16
17 import (
18 "math"
19 "testing"
20 )
21
22
23
24
25
26
27
28
29
30 var (
31 empty = EmptyInterval()
32 full = FullInterval()
33
34 zero = IntervalFromEndpoints(0, 0)
35 pi2 = IntervalFromEndpoints(math.Pi/2, math.Pi/2)
36 pi = IntervalFromEndpoints(math.Pi, math.Pi)
37 mipi = IntervalFromEndpoints(-math.Pi, -math.Pi)
38 mipi2 = IntervalFromEndpoints(-math.Pi/2, -math.Pi/2)
39
40 quad1 = IntervalFromEndpoints(0, math.Pi/2)
41 quad2 = IntervalFromEndpoints(math.Pi/2, -math.Pi)
42 quad3 = IntervalFromEndpoints(math.Pi, -math.Pi/2)
43 quad4 = IntervalFromEndpoints(-math.Pi/2, 0)
44
45 quad12 = IntervalFromEndpoints(0, -math.Pi)
46 quad23 = IntervalFromEndpoints(math.Pi/2, -math.Pi/2)
47 quad34 = IntervalFromEndpoints(-math.Pi, 0)
48 quad41 = IntervalFromEndpoints(-math.Pi/2, math.Pi/2)
49
50 quad123 = IntervalFromEndpoints(0, -math.Pi/2)
51 quad234 = IntervalFromEndpoints(math.Pi/2, 0)
52 quad341 = IntervalFromEndpoints(math.Pi, math.Pi/2)
53 quad412 = IntervalFromEndpoints(-math.Pi/2, -math.Pi)
54
55
56 mid12 = IntervalFromEndpoints(math.Pi/2-0.01, math.Pi/2+0.02)
57 mid23 = IntervalFromEndpoints(math.Pi-0.01, -math.Pi+0.02)
58 mid34 = IntervalFromEndpoints(-math.Pi/2-0.01, -math.Pi/2+0.02)
59 mid41 = IntervalFromEndpoints(-0.01, 0.02)
60 )
61
62 func TestConstructors(t *testing.T) {
63
64 if mipi.Lo != math.Pi {
65 t.Errorf("mipi.Lo = %v, want π", mipi.Lo)
66 }
67 if mipi.Hi != math.Pi {
68 t.Errorf("mipi.Hi = %v, want π", mipi.Lo)
69 }
70
71 var i Interval
72 if !i.IsValid() {
73 t.Errorf("Zero value Interval is not valid")
74 }
75 }
76
77 func TestIntervalFromPointPair(t *testing.T) {
78 tests := []struct {
79 a, b float64
80 want Interval
81 }{
82 {-math.Pi, math.Pi, pi},
83 {math.Pi, -math.Pi, pi},
84 {mid34.Hi, mid34.Lo, mid34},
85 {mid23.Lo, mid23.Hi, mid23},
86 }
87 for _, test := range tests {
88 got := IntervalFromPointPair(test.a, test.b)
89 if got != test.want {
90 t.Errorf("IntervalFromPointPair(%f, %f) = %v, want %v", test.a, test.b, got, test.want)
91 }
92 }
93 }
94
95 func TestSimplePredicates(t *testing.T) {
96 if !zero.IsValid() || zero.IsEmpty() || zero.IsFull() {
97 t.Errorf("Zero interval is invalid or empty or full")
98 }
99 if !empty.IsValid() || !empty.IsEmpty() || empty.IsFull() {
100 t.Errorf("Empty interval is invalid or not empty or full")
101 }
102 if !empty.IsInverted() {
103 t.Errorf("Empty interval is not inverted")
104 }
105 if !full.IsValid() || full.IsEmpty() || !full.IsFull() {
106 t.Errorf("Full interval is invalid or empty or not full")
107 }
108 if !pi.IsValid() || pi.IsEmpty() || pi.IsInverted() {
109 t.Errorf("pi is invalid or empty or inverted")
110 }
111 if !mipi.IsValid() || mipi.IsEmpty() || mipi.IsInverted() {
112 t.Errorf("mipi is invalid or empty or inverted")
113 }
114 }
115
116 func TestAlmostFullOrEmpty(t *testing.T) {
117
118
119
120 almostPi := math.Pi - 2*dblEpsilon
121
122 i := Interval{-almostPi, math.Pi}
123 if i.IsFull() {
124 t.Errorf("%v.IsFull should not be true", i)
125 }
126
127 i = Interval{-math.Pi, almostPi}
128 if i.IsFull() {
129 t.Errorf("%v.IsFull should not be true", i)
130 }
131
132 i = Interval{math.Pi, -almostPi}
133 if i.IsEmpty() {
134 t.Errorf("%v.IsEmpty should not be true", i)
135 }
136
137 i = Interval{almostPi, -math.Pi}
138 if i.IsEmpty() {
139 t.Errorf("%v.IsEmpty should not be true", i)
140 }
141 }
142
143 func TestCenter(t *testing.T) {
144 tests := []struct {
145 interval Interval
146 want float64
147 }{
148 {quad12, math.Pi / 2},
149 {IntervalFromEndpoints(3.1, 2.9), 3 - math.Pi},
150 {IntervalFromEndpoints(-2.9, -3.1), math.Pi - 3},
151 {IntervalFromEndpoints(2.1, -2.1), math.Pi},
152 {pi, math.Pi},
153 {mipi, math.Pi},
154
155 {quad23, math.Pi},
156
157 {quad123, 0.75 * math.Pi},
158 }
159 for _, test := range tests {
160 got := test.interval.Center()
161
162 if math.Abs(got-test.want) > 1e-15 {
163 t.Errorf("%v.Center() = %v, want %v", test.interval, got, test.want)
164 }
165 }
166 }
167
168 func TestLength(t *testing.T) {
169 tests := []struct {
170 interval Interval
171 want float64
172 }{
173 {quad12, math.Pi},
174 {pi, 0},
175 {mipi, 0},
176
177 {quad123, 1.5 * math.Pi},
178
179 {quad23, math.Pi},
180 {full, 2 * math.Pi},
181 }
182 for _, test := range tests {
183 if l := test.interval.Length(); l != test.want {
184 t.Errorf("%v.Length() got %v, want %v", test.interval, l, test.want)
185 }
186 }
187 if l := empty.Length(); l >= 0 {
188 t.Errorf("empty interval has non-negative length %v", l)
189 }
190 }
191
192 func TestContains(t *testing.T) {
193 tests := []struct {
194 interval Interval
195 in, out []float64
196 iIn, iOut []float64
197 }{
198 {empty, nil, []float64{0, math.Pi, -math.Pi}, nil, []float64{math.Pi, -math.Pi}},
199 {full, []float64{0, math.Pi, -math.Pi}, nil, []float64{math.Pi, -math.Pi}, nil},
200 {quad12, []float64{0, math.Pi, -math.Pi}, nil,
201 []float64{math.Pi / 2}, []float64{0, math.Pi, -math.Pi}},
202 {quad23, []float64{math.Pi / 2, -math.Pi / 2, math.Pi, -math.Pi}, []float64{0},
203 []float64{math.Pi, -math.Pi}, []float64{math.Pi / 2, -math.Pi / 2, 0}},
204 {pi, []float64{math.Pi, -math.Pi}, []float64{0}, nil, []float64{math.Pi, -math.Pi}},
205 {mipi, []float64{math.Pi, -math.Pi}, []float64{0}, nil, []float64{math.Pi, -math.Pi}},
206 {zero, []float64{0}, nil, nil, []float64{0}},
207 }
208 for _, test := range tests {
209 for _, p := range test.in {
210 if !test.interval.Contains(p) {
211 t.Errorf("%v should contain %v", test.interval, p)
212 }
213 }
214 for _, p := range test.out {
215 if test.interval.Contains(p) {
216 t.Errorf("%v should not contain %v", test.interval, p)
217 }
218 }
219 for _, p := range test.iIn {
220 if !test.interval.InteriorContains(p) {
221 t.Errorf("interior of %v should contain %v", test.interval, p)
222 }
223 }
224 for _, p := range test.iOut {
225 if test.interval.InteriorContains(p) {
226 t.Errorf("interior %v should not contain %v", test.interval, p)
227 }
228 }
229 }
230 }
231
232 func TestIntervalOperations(t *testing.T) {
233 quad12eps := IntervalFromEndpoints(quad12.Lo, mid23.Hi)
234 quad2hi := IntervalFromEndpoints(mid23.Lo, quad12.Hi)
235 quad412eps := IntervalFromEndpoints(mid34.Lo, quad12.Hi)
236 quadeps12 := IntervalFromEndpoints(mid41.Lo, quad12.Hi)
237 quad1lo := IntervalFromEndpoints(quad12.Lo, mid41.Hi)
238 quad2lo := IntervalFromEndpoints(quad23.Lo, mid12.Hi)
239 quad3hi := IntervalFromEndpoints(mid34.Lo, quad23.Hi)
240 quadeps23 := IntervalFromEndpoints(mid12.Lo, quad23.Hi)
241 quad23eps := IntervalFromEndpoints(quad23.Lo, mid34.Hi)
242 quadeps123 := IntervalFromEndpoints(mid41.Lo, quad23.Hi)
243
244
245 tests := []struct {
246 x, y Interval
247 xContainsY, xInteriorContainsY bool
248 xIntersectsY, xInteriorIntersectsY bool
249 wantUnion, wantIntersection Interval
250 }{
251
252 {empty, empty, true, true, false, false, empty, empty},
253 {empty, full, false, false, false, false, full, empty},
254 {empty, zero, false, false, false, false, zero, empty},
255 {empty, pi, false, false, false, false, pi, empty},
256 {empty, mipi, false, false, false, false, mipi, empty},
257
258
259 {full, empty, true, true, false, false, full, empty},
260 {full, full, true, true, true, true, full, full},
261 {full, zero, true, true, true, true, full, zero},
262 {full, pi, true, true, true, true, full, pi},
263 {full, mipi, true, true, true, true, full, mipi},
264 {full, quad12, true, true, true, true, full, quad12},
265 {full, quad23, true, true, true, true, full, quad23},
266
267
268 {zero, empty, true, true, false, false, zero, empty},
269 {zero, full, false, false, true, false, full, zero},
270 {zero, zero, true, false, true, false, zero, zero},
271 {zero, pi, false, false, false, false, IntervalFromEndpoints(0, math.Pi), empty},
272 {zero, pi2, false, false, false, false, quad1, empty},
273 {zero, mipi, false, false, false, false, quad12, empty},
274 {zero, mipi2, false, false, false, false, quad4, empty},
275 {zero, quad12, false, false, true, false, quad12, zero},
276 {zero, quad23, false, false, false, false, quad123, empty},
277
278
279 {pi2, empty, true, true, false, false, pi2, empty},
280 {pi2, full, false, false, true, false, full, pi2},
281 {pi2, zero, false, false, false, false, quad1, empty},
282 {pi2, pi, false, false, false, false, IntervalFromEndpoints(math.Pi/2, math.Pi), empty},
283 {pi2, pi2, true, false, true, false, pi2, pi2},
284 {pi2, mipi, false, false, false, false, quad2, empty},
285 {pi2, mipi2, false, false, false, false, quad23, empty},
286 {pi2, quad12, false, false, true, false, quad12, pi2},
287 {pi2, quad23, false, false, true, false, quad23, pi2},
288
289
290 {pi, empty, true, true, false, false, pi, empty},
291 {pi, full, false, false, true, false, full, pi},
292 {pi, zero, false, false, false, false, IntervalFromEndpoints(math.Pi, 0), empty},
293 {pi, pi, true, false, true, false, pi, pi},
294 {pi, pi2, false, false, false, false, IntervalFromEndpoints(math.Pi/2, math.Pi), empty},
295 {pi, mipi, true, false, true, false, pi, pi},
296 {pi, mipi2, false, false, false, false, quad3, empty},
297 {pi, quad12, false, false, true, false, IntervalFromEndpoints(0, math.Pi), pi},
298 {pi, quad23, false, false, true, false, quad23, pi},
299
300
301 {mipi, empty, true, true, false, false, mipi, empty},
302 {mipi, full, false, false, true, false, full, mipi},
303 {mipi, zero, false, false, false, false, quad34, empty},
304 {mipi, pi, true, false, true, false, mipi, mipi},
305 {mipi, pi2, false, false, false, false, quad2, empty},
306 {mipi, mipi, true, false, true, false, mipi, mipi},
307 {mipi, mipi2, false, false, false, false, IntervalFromEndpoints(-math.Pi, -math.Pi/2), empty},
308 {mipi, quad12, false, false, true, false, quad12, mipi},
309 {mipi, quad23, false, false, true, false, quad23, mipi},
310
311
312 {quad12, empty, true, true, false, false, quad12, empty},
313 {quad12, full, false, false, true, true, full, quad12},
314 {quad12, zero, true, false, true, false, quad12, zero},
315 {quad12, pi, true, false, true, false, quad12, pi},
316 {quad12, mipi, true, false, true, false, quad12, mipi},
317 {quad12, quad12, true, false, true, true, quad12, quad12},
318 {quad12, quad23, false, false, true, true, quad123, quad2},
319 {quad12, quad34, false, false, true, false, full, quad12},
320
321
322 {quad23, empty, true, true, false, false, quad23, empty},
323 {quad23, full, false, false, true, true, full, quad23},
324 {quad23, zero, false, false, false, false, quad234, empty},
325 {quad23, pi, true, true, true, true, quad23, pi},
326 {quad23, mipi, true, true, true, true, quad23, mipi},
327 {quad23, quad12, false, false, true, true, quad123, quad2},
328 {quad23, quad23, true, false, true, true, quad23, quad23},
329 {quad23, quad34, false, false, true, true, quad234, IntervalFromEndpoints(-math.Pi, -math.Pi/2)},
330
331
332 {quad1, quad23, false, false, true, false, quad123, IntervalFromEndpoints(math.Pi/2, math.Pi/2)},
333 {quad2, quad3, false, false, true, false, quad23, mipi},
334 {quad3, quad2, false, false, true, false, quad23, pi},
335 {quad2, pi, true, false, true, false, quad2, pi},
336 {quad2, mipi, true, false, true, false, quad2, mipi},
337 {quad3, pi, true, false, true, false, quad3, pi},
338 {quad3, mipi, true, false, true, false, quad3, mipi},
339
340
341 {quad12, mid12, true, true, true, true, quad12, mid12},
342 {mid12, quad12, false, false, true, true, quad12, mid12},
343
344
345 {quad12, mid23, false, false, true, true, quad12eps, quad2hi},
346 {mid23, quad12, false, false, true, true, quad12eps, quad2hi},
347
348
349
350
351
352 {quad12, mid34, false, false, false, false, quad412eps, empty},
353 {mid34, quad12, false, false, false, false, quad412eps, empty},
354
355
356 {quad12, mid41, false, false, true, true, quadeps12, quad1lo},
357 {mid41, quad12, false, false, true, true, quadeps12, quad1lo},
358
359
360 {quad23, mid12, false, false, true, true, quadeps23, quad2lo},
361 {mid12, quad23, false, false, true, true, quadeps23, quad2lo},
362 {quad23, mid23, true, true, true, true, quad23, mid23},
363 {mid23, quad23, false, false, true, true, quad23, mid23},
364 {quad23, mid34, false, false, true, true, quad23eps, quad3hi},
365 {mid34, quad23, false, false, true, true, quad23eps, quad3hi},
366 {quad23, mid41, false, false, false, false, quadeps123, empty},
367 {mid41, quad23, false, false, false, false, quadeps123, empty},
368 }
369 should := func(b bool) string {
370 if b {
371 return "should"
372 }
373 return "should not"
374 }
375 for _, test := range tests {
376 if test.x.ContainsInterval(test.y) != test.xContainsY {
377 t.Errorf("%v %s contain %v", test.x, should(test.xContainsY), test.y)
378 }
379 if test.x.InteriorContainsInterval(test.y) != test.xInteriorContainsY {
380 t.Errorf("interior of %v %s contain %v", test.x, should(test.xInteriorContainsY), test.y)
381 }
382 if test.x.Intersects(test.y) != test.xIntersectsY {
383 t.Errorf("%v %s intersect %v", test.x, should(test.xIntersectsY), test.y)
384 }
385 if test.x.InteriorIntersects(test.y) != test.xInteriorIntersectsY {
386 t.Errorf("interior of %v %s intersect %v", test.x, should(test.xInteriorIntersectsY), test.y)
387 }
388 if u := test.x.Union(test.y); u != test.wantUnion {
389 t.Errorf("%v ∪ %v was %v, want %v", test.x, test.y, u, test.wantUnion)
390 }
391 if u := test.x.Intersection(test.y); u != test.wantIntersection {
392 t.Errorf("%v ∩ %v was %v, want %v", test.x, test.y, u, test.wantIntersection)
393 }
394 }
395 }
396
397 func TestAddPoint(t *testing.T) {
398 tests := []struct {
399 interval Interval
400 points []float64
401 want Interval
402 }{
403 {empty, []float64{0}, zero},
404 {empty, []float64{math.Pi}, pi},
405 {empty, []float64{-math.Pi}, mipi},
406 {empty, []float64{math.Pi, -math.Pi}, pi},
407 {empty, []float64{-math.Pi, math.Pi}, mipi},
408 {empty, []float64{mid12.Lo, mid12.Hi}, mid12},
409 {empty, []float64{mid23.Lo, mid23.Hi}, mid23},
410
411 {quad1, []float64{-0.9 * math.Pi, -math.Pi / 2}, quad123},
412 {full, []float64{0}, full},
413 {full, []float64{math.Pi}, full},
414 {full, []float64{-math.Pi}, full},
415 }
416 for _, test := range tests {
417 got := test.interval
418 for _, point := range test.points {
419 got = got.AddPoint(point)
420 }
421 want := test.want
422 if math.Abs(got.Lo-want.Lo) > 1e-15 || math.Abs(got.Hi-want.Hi) > 1e-15 {
423 t.Errorf("%v.AddPoint(%v) = %v, want %v", test.interval, test.points, got, want)
424 }
425 }
426 }
427
428 func TestExpanded(t *testing.T) {
429 tests := []struct {
430 interval Interval
431 margin float64
432 want Interval
433 }{
434 {empty, 1, empty},
435 {full, 1, full},
436 {zero, 1, Interval{-1, 1}},
437 {mipi, 0.01, Interval{math.Pi - 0.01, -math.Pi + 0.01}},
438 {pi, 27, full},
439 {pi, math.Pi / 2, quad23},
440 {pi2, math.Pi / 2, quad12},
441 {mipi2, math.Pi / 2, quad34},
442
443 {empty, -1, empty},
444 {full, -1, full},
445 {quad123, -27, empty},
446 {quad234, -27, empty},
447 {quad123, -math.Pi / 2, quad2},
448 {quad341, -math.Pi / 2, quad4},
449 {quad412, -math.Pi / 2, quad1},
450 }
451 for _, test := range tests {
452 if got, want := test.interval.Expanded(test.margin), test.want; math.Abs(got.Lo-want.Lo) > 1e-15 || math.Abs(got.Hi-want.Hi) > 1e-15 {
453 t.Errorf("%v.Expanded(%v) = %v, want %v", test.interval, test.margin, got, want)
454 }
455 }
456 }
457
458 func TestIntervalString(t *testing.T) {
459 if s, exp := pi.String(), "[3.1415927, 3.1415927]"; s != exp {
460 t.Errorf("pi.String() = %q, want %q", s, exp)
461 }
462 }
463
464 func TestIntervalApproxEqual(t *testing.T) {
465
466
467 lo := 4 * dblEpsilon
468 hi := 6 * dblEpsilon
469
470 tests := []struct {
471 a, b Interval
472 want bool
473 }{
474
475 {a: empty, b: empty, want: true},
476 {a: zero, b: empty, want: true},
477 {a: empty, b: zero, want: true},
478 {a: pi, b: empty, want: true},
479 {a: empty, b: pi, want: true},
480 {a: mipi, b: empty, want: true},
481 {a: empty, b: mipi, want: true},
482 {a: empty, b: full, want: false},
483 {a: empty, b: Interval{1, 1 + 2*lo}, want: true},
484 {a: empty, b: Interval{1, 1 + 2*hi}, want: false},
485 {a: Interval{math.Pi - lo, -math.Pi + lo}, b: empty, want: true},
486
487
488 {a: full, b: full, want: true},
489 {a: full, b: empty, want: false},
490 {a: full, b: zero, want: false},
491 {a: full, b: pi, want: false},
492 {a: full, b: Interval{lo, -lo}, want: true},
493 {a: full, b: Interval{2 * hi, 0}, want: false},
494 {a: Interval{-math.Pi + lo, math.Pi - lo}, b: full, want: true},
495 {a: Interval{-math.Pi, math.Pi - 2*hi}, b: full, want: false},
496
497
498 {a: pi, b: pi, want: true},
499 {a: mipi, b: pi, want: true},
500 {a: pi, b: Interval{math.Pi - lo, math.Pi - lo}, want: true},
501 {a: pi, b: Interval{math.Pi - hi, math.Pi - hi}, want: false},
502 {a: pi, b: Interval{math.Pi - lo, -math.Pi + lo}, want: true},
503 {a: pi, b: Interval{math.Pi - hi, -math.Pi}, want: false},
504 {a: zero, b: pi, want: false},
505 {a: pi.Union(mid12).Union(zero), b: quad12, want: true},
506 {a: quad2.Intersection(quad3), b: pi, want: true},
507 {a: quad3.Intersection(quad2), b: pi, want: true},
508
509
510
511 {a: Interval{0, lo}, b: Interval{lo, 0}, want: false},
512 {a: Interval{math.Pi - 0.5*lo, -math.Pi + 0.5*lo}, b: Interval{-math.Pi + 0.5*lo, math.Pi - 0.5*lo}, want: false},
513
514
515 {a: Interval{1 - lo, 2 + lo}, b: Interval{1, 2}, want: true},
516 {a: Interval{1 + lo, 2 - lo}, b: Interval{1, 2}, want: true},
517 {a: Interval{2 - lo, 1 + lo}, b: Interval{2, 1}, want: true},
518 {a: Interval{2 + lo, 1 - lo}, b: Interval{2, 1}, want: true},
519 {a: Interval{1 - hi, 2 + lo}, b: Interval{1, 2}, want: false},
520 {a: Interval{1 + hi, 2 - lo}, b: Interval{1, 2}, want: false},
521 {a: Interval{2 - hi, 1 + lo}, b: Interval{2, 1}, want: false},
522 {a: Interval{2 + hi, 1 - lo}, b: Interval{2, 1}, want: false},
523 {a: Interval{1 - lo, 2 + hi}, b: Interval{1, 2}, want: false},
524 {a: Interval{1 + lo, 2 - hi}, b: Interval{1, 2}, want: false},
525 {a: Interval{2 - lo, 1 + hi}, b: Interval{2, 1}, want: false},
526 {a: Interval{2 + lo, 1 - hi}, b: Interval{2, 1}, want: false},
527 }
528
529 for _, test := range tests {
530 if got := test.a.ApproxEqual(test.b); got != test.want {
531 t.Errorf("%v.ApproxEqual(%v) = %t, want %t", test.a, test.b, got, test.want)
532 }
533 }
534 }
535
536 func TestIntervalComplement(t *testing.T) {
537 if !EmptyInterval().Complement().IsFull() {
538 t.Error("empty interval's complement is not full, but should be")
539 }
540 if !FullInterval().Complement().IsEmpty() {
541 t.Error("full interval's complement is not empty, but should be")
542 }
543 if !pi.Complement().IsFull() {
544 t.Errorf("pi's (%v) complement is not full, but should be", pi)
545 }
546 if !mipi.Complement().IsFull() {
547 t.Errorf("mipi's (%v) complement is not full, but should be", mipi)
548 }
549 if !zero.Complement().IsFull() {
550 t.Errorf("zero's (%v) complement is not full, but should be", zero)
551 }
552
553 if got := quad12.Complement(); !got.ApproxEqual(quad34) {
554 t.Errorf("%v.Complement = %v, want %v", quad12, got, quad34)
555 }
556 if got := quad34.Complement(); !got.ApproxEqual(quad12) {
557 t.Errorf("%v.Complement = %v, want %v", quad34, got, quad12)
558 }
559 if got := quad123.Complement(); !got.ApproxEqual(quad4) {
560 t.Errorf("%v.Complement = %v, want %v", quad123, got, quad4)
561 }
562 }
563
564 func TestIntervalDirectedHausdorff(t *testing.T) {
565 in := Interval{3.0, -3.0}
566 tests := []struct {
567 i, y Interval
568 want Angle
569 }{
570 {Interval{-0.139626, 0.349066}, Interval{0.139626, 0.139626}, 0.279252 * Radian},
571 {Interval{0.2, 0.4}, Interval{0.1, 0.5}, 0 * Radian},
572 {Interval{0, 0}, EmptyInterval(), math.Pi * Radian},
573 {empty, empty, 0.0},
574 {empty, mid12, 0.0},
575 {mid12, empty, math.Pi},
576 {quad12, quad123, 0.0},
577 {Interval{-0.1, 0.2}, in, 3.0},
578 {Interval{0.1, 0.2}, in, 3.0 - 0.1},
579 {Interval{-0.2, -0.1}, in, 3.0 - 0.1},
580 }
581
582 for _, test := range tests {
583 got := test.i.DirectedHausdorffDistance(test.y)
584 if math.Abs(float64(got-test.want)) > 1e-15 {
585 t.Errorf("%v.DirectedHausdorffDistance(%v) = %v, want %v", test.i, test.y, got.Radians(), test.want.Radians())
586 }
587 }
588 }
589
590 func TestIntervalProject(t *testing.T) {
591 r := IntervalFromEndpoints(-math.Pi, -math.Pi)
592 r1 := IntervalFromEndpoints(0, math.Pi)
593 r2 := IntervalFromEndpoints(math.Pi-0.1, -math.Pi+0.1)
594 tests := []struct {
595 interval Interval
596 have float64
597 want float64
598 }{
599 {r, -math.Pi, math.Pi},
600 {r, 0, math.Pi},
601
602 {r1, 0.1, 0.1},
603 {r1, -math.Pi/2 + 1e-15, 0},
604 {r1, -math.Pi/2 - 1e-15, math.Pi},
605 {r2, math.Pi, math.Pi},
606 {r2, 1e-15, math.Pi - 0.1},
607 {r2, -1e-15, -math.Pi + 0.1},
608 {full, 0, 0},
609 {full, math.Pi, math.Pi},
610 {full, -math.Pi, math.Pi},
611 }
612
613 for _, test := range tests {
614 if got := test.interval.Project(test.have); !float64Eq(got, test.want) {
615 t.Errorf("%v.Project(%v) = %v, want %v", test.interval, test.have, got, test.want)
616 }
617 }
618 }
619
View as plain text