1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package s2
16
17 import (
18 "math"
19 "testing"
20
21 "github.com/golang/geo/s1"
22 )
23
24
25
26
27
28 func testIntersectionExact(a0, a1, b0, b1 Point) Point {
29 x := intersectionExact(a0, a1, b0, b1)
30 if x.Dot((a0.Add(a1.Vector)).Add(b0.Add(b1.Vector))) < 0 {
31 x = Point{x.Mul(-1)}
32 }
33 return x
34 }
35
36 var distanceAbsError = s1.Angle(3 * dblEpsilon)
37
38 func TestEdgeutilIntersectionError(t *testing.T) {
39
40
41
42
43 var maxPointDist, maxEdgeDist s1.Angle
44 for iter := 0; iter < 5000; iter++ {
45
46
47
48
49
50
51
52
53
54
55
56 f := randomFrame()
57 p := f.col(0)
58 d1 := f.col(1)
59 d2 := f.col(2)
60
61 slope := 1e-15 * math.Pow(1e30, randomFloat64())
62 d2 = Point{d1.Add(d2.Mul(slope)).Normalize()}
63 var a, b, c, d Point
64
65
66 for {
67 abLen := math.Pow(1e-15, randomFloat64())
68 cdLen := math.Pow(1e-15, randomFloat64())
69 aFraction := math.Pow(1e-5, randomFloat64())
70 if oneIn(2) {
71 aFraction = 1 - aFraction
72 }
73 cFraction := math.Pow(1e-5, randomFloat64())
74 if oneIn(2) {
75 cFraction = 1 - cFraction
76 }
77 a = Point{p.Sub(d1.Mul(aFraction * abLen)).Normalize()}
78 b = Point{p.Add(d1.Mul((1 - aFraction) * abLen)).Normalize()}
79 c = Point{p.Sub(d2.Mul(cFraction * cdLen)).Normalize()}
80 d = Point{p.Add(d2.Mul((1 - cFraction) * cdLen)).Normalize()}
81 if NewEdgeCrosser(a, b).CrossingSign(c, d) == Cross {
82 break
83 }
84 }
85
86
87
88 if got, want := DistanceFromSegment(p, a, b), s1.Angle(1.5*dblEpsilon)+distanceAbsError; got > want {
89 t.Errorf("DistanceFromSegment(%v, %v, %v) = %v, want %v", p, a, b, got, want)
90 }
91 if got, want := DistanceFromSegment(p, c, d), s1.Angle(1.5*dblEpsilon)+distanceAbsError; got > want {
92 t.Errorf("DistanceFromSegment(%v, %v, %v) = %v, want %v", p, c, d, got, want)
93 }
94
95
96
97
98 expected := testIntersectionExact(a, b, c, d)
99 if got, want := DistanceFromSegment(expected, a, b), s1.Angle(3*dblEpsilon)+distanceAbsError; got > want {
100 t.Errorf("DistanceFromSegment(%v, %v, %v) = %v, want %v", expected, a, b, got, want)
101 }
102 if got, want := DistanceFromSegment(expected, c, d), s1.Angle(3*dblEpsilon)+distanceAbsError; got > want {
103 t.Errorf("DistanceFromSegment(%v, %v, %v) = %v, want %v", expected, c, d, got, want)
104 }
105 if got, want := expected.Distance(p), s1.Angle(3*dblEpsilon/slope)+intersectionError; got > want {
106 t.Errorf("%v.Distance(%v) = %v, want %v", expected, p, got, want)
107 }
108
109
110 actual := Intersection(a, b, c, d)
111 distAB := DistanceFromSegment(actual, a, b)
112 distCD := DistanceFromSegment(actual, c, d)
113 pointDist := expected.Distance(actual)
114 if got, want := distAB, intersectionError+distanceAbsError; got > want {
115 t.Errorf("DistanceFromSegment(%v, %v, %v) = %v want <= %v", actual, a, b, got, want)
116 }
117 if got, want := distCD, intersectionError+distanceAbsError; got > want {
118 t.Errorf("DistanceFromSegment(%v, %v, %v) = %v want <= %v", actual, c, d, got, want)
119 }
120 if got, want := pointDist, intersectionError; got > want {
121 t.Errorf("%v.Distance(%v) = %v want <= %v", expected, actual, got, want)
122 }
123 maxEdgeDist = maxAngle(maxEdgeDist, maxAngle(distAB, distCD))
124 maxPointDist = maxAngle(maxPointDist, pointDist)
125 }
126 }
127
128 func TestAngleContainsVertex(t *testing.T) {
129 a := PointFromCoords(1, 0, 0)
130 b := PointFromCoords(0, 1, 0)
131 refB := b.referenceDir()
132
133
134 if AngleContainsVertex(a, b, a) {
135 t.Errorf("AngleContainsVertex(%v, %v, %v = true, want false", a, b, a)
136 }
137
138
139 if !AngleContainsVertex(refB, b, a) {
140 t.Errorf("AngleContainsVertex(%v, %v, %v = false, want true", refB, b, a)
141 }
142
143
144 if AngleContainsVertex(a, b, refB) {
145 t.Errorf("AngleContainsVertex(%v, %v, %v = true, want false", a, b, refB)
146 }
147
148
149
150 loop := RegularLoop(b, s1.Angle(10)*s1.Degree, 10)
151 count := 0
152 for i, v := range loop.Vertices() {
153 if AngleContainsVertex(loop.Vertex(i+1), b, v) {
154 count++
155 }
156 }
157 if count != 1 {
158 t.Errorf("with a set of polygons tiled around a vertex, only one should contain the vertex, got %d", count)
159 }
160 }
161
162
163
164
165
166
167
168
169
170
171
172
View as plain text