1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package s2
16
17 import (
18 "testing"
19
20 "github.com/golang/geo/s1"
21 )
22
23 func TestFurthestEdgeQueryNoEdges(t *testing.T) {
24 index := &ShapeIndex{}
25 query := NewFurthestEdgeQuery(index, nil)
26 target := NewMaxDistanceToPointTarget(PointFromCoords(1, 0, 0))
27 edge := query.findEdge(target, query.opts)
28
29 if edge.shapeID != -1 {
30 t.Errorf("shapeID for empty index should be -1, got %v", edge.shapeID)
31 }
32 if edge.edgeID != -1 {
33 t.Errorf("edgeID for empty index should be -1, got %v", edge.edgeID)
34 }
35 if got, want := edge.Distance(), s1.NegativeChordAngle; got != want {
36 t.Errorf("edge.Distance = %+v, want %+v", got, want)
37 }
38 if got, want := query.Distance(target), s1.NegativeChordAngle; got != want {
39 t.Errorf("query.Distance(%v) = %+v, want %+v", target, got, want)
40 }
41 }
42
43 func TestFurthestEdgeQueryBasicTest(t *testing.T) {
44 index := makeShapeIndex("0:1 | 0:2 | 0:3 # #")
45 query := NewFurthestEdgeQuery(index, NewFurthestEdgeQueryOptions().
46 MaxResults(3).
47 DistanceLimit(s1.ChordAngleFromAngle(s1.Angle(1)*s1.Degree)).
48 MaxError(s1.ChordAngleFromAngle(s1.Angle(0.001)*s1.Degree)))
49 target := NewMaxDistanceToPointTarget(parsePoint("0:4"))
50
51 result := query.findEdge(target, query.opts)
52
53 if result.edgeID != 0 {
54 t.Errorf("query.findEdge(%v).edgeID = %v, want %v", target, result.edgeID, 0)
55 }
56
57 if got, want := query.Distance(target).Angle().Degrees(), 3.0; !float64Near(got, want, epsilon) {
58 t.Errorf("query.Distance(%v) = %v, want %v", target, got, want)
59 }
60 if !query.IsDistanceGreater(target, s1.ChordAngleFromAngle(s1.Angle(1.5)*s1.Degree)) {
61 t.Errorf("query.IsDistanceGreater(%v, 1.5) should be true but wasn't", target)
62 }
63 }
64
65 func TestFurthestEdgeQueryAntipodalPointInsideIndexedPolygon(t *testing.T) {
66
67
68 index := makeShapeIndex("# 0:0, 0:5, 5:5, 5:0 # 0:10, 0:15, 5:15, 5:10")
69
70
71 query := NewFurthestEdgeQuery(index, NewFurthestEdgeQueryOptions().
72 IncludeInteriors(true).
73 DistanceLimit(s1.ChordAngleFromAngle(s1.Angle(178)*s1.Degree)))
74 target := NewMaxDistanceToPointTarget(Point{parsePoint("2:12").Mul(-1)})
75
76 results := query.FindEdges(target)
77
78 if len(results) < 1 {
79 t.Errorf("aa")
80 }
81 result := results[0]
82 if result.Distance() != s1.StraightChordAngle {
83 t.Errorf("result.Distance = %v, want %v", result.Distance(), s1.StraightChordAngle)
84 }
85
86 if result.shapeID != 1 {
87 t.Errorf("result.shapeID of result should be 1, was %v", result.shapeID)
88 }
89
90 if result.edgeID != -1 {
91 t.Errorf("result.edgeID = %v, want -1", result.edgeID)
92 }
93
94
95
96 query.opts.IncludeInteriors(false)
97 results = query.FindEdges(target)
98
99 if len(results) <= 0 {
100 t.Errorf("findEdges returned no results, should have been at least 1")
101 return
102 }
103 result = results[0]
104 if result.Distance() > s1.StraightChordAngle {
105 t.Errorf("result.Distance = %v, want less than %v", result.Distance(), s1.StraightChordAngle)
106 }
107 if result.shapeID != 1 {
108 t.Errorf("result.shapeID = %v, want 1", result.shapeID)
109 }
110
111 if result.edgeID == -1 {
112 t.Errorf("result.edgeID = %v, want >= 0", result.edgeID)
113 }
114 }
115
116 func TestFurthestEdgeQueryAntipodalPointOutsideIndexedPolygon(t *testing.T) {
117
118
119
120 index := makeShapeIndex("# 0:0, 0:5, 5:5, 5:0 # 0:10, 0:15, 5:15, 5:10")
121 query := NewFurthestEdgeQuery(index, NewFurthestEdgeQueryOptions().
122 IncludeInteriors(true).
123 DistanceLimit(s1.ChordAngleFromAngle(s1.Angle(179)*s1.Degree)))
124 target := NewMaxDistanceToPointTarget(Point{parsePoint("2:2").Mul(-1)})
125
126 results := query.FindEdges(target)
127 if len(results) != 0 {
128 t.Errorf("len(query.FindEdges(target)) = %d, want 0", len(results))
129 }
130 }
131
132 func TestFurthestEdgeQueryTargetPolygonContainingIndexedPoints(t *testing.T) {
133
134
135 index := makeShapeIndex("2:2 | 4:4 | 1:11 | 3:12 # #")
136 query := NewFurthestEdgeQuery(index, NewFurthestEdgeQueryOptions().UseBruteForce(false))
137
138 targetIndex := makeShapeIndex("# 0:0, 0:5, 5:5, 5:0 # 0:10, 0:15, 5:15, 5:10")
139 target := NewMaxDistanceToShapeIndexTarget(targetIndex)
140 target.setIncludeInteriors(true)
141 target.setUseBruteForce(true)
142 results := query.FindEdges(target)
143
144
145 if len(results) != 4 {
146 t.Errorf("All 4 shapes should have matched. Got %d shapes", len(results))
147 }
148
149 r0 := results[0]
150 if r0.Distance() == 0 {
151 t.Errorf("result[0].Distance = 0, want non-zero")
152 }
153 if r0.shapeID != 0 {
154 t.Errorf("result[0].shapeID = %v, want 0", r0.shapeID)
155 }
156 if r0.edgeID != 0 {
157 t.Errorf("result[0].edgeID = %v, want 0", r0.edgeID)
158 }
159
160 r1 := results[1]
161 if r1.Distance() == 0 {
162 t.Errorf("result[1].Distance = 0, want non-zero")
163 }
164 if r1.shapeID != 0 {
165 t.Errorf("result[1].shapeID = %v, want 0", r1.shapeID)
166 }
167 if r1.edgeID != 3 {
168 t.Errorf("result[1].edgeID = %v, want 3", r1.edgeID)
169 }
170 }
171
172 func TestFurthestEdgeQueryAntipodalPolygonContainingIndexedPoints(t *testing.T) {
173
174
175 index := NewShapeIndex()
176 pts := parsePoints("2:2, 3:3, 1:11, 3:13")
177 antipodalPts := reflectPoints(pts)
178 pv := PointVector(antipodalPts)
179 index.Add(&pv)
180
181 query := NewFurthestEdgeQuery(index, NewFurthestEdgeQueryOptions().
182 DistanceLimit(s1.ChordAngleFromAngle(s1.Angle(179)*s1.Degree)),
183 )
184 targetIndex := makeShapeIndex("# 0:0, 0:5, 5:5, 5:0 # 0:10, 0:15, 5:15, 5:10")
185 target := NewMaxDistanceToShapeIndexTarget(targetIndex)
186 target.setIncludeInteriors(true)
187 results := query.FindEdges(target)
188
189 if len(results) != 2 {
190 t.Errorf("2 shapes should have matched. Got %d shapes", len(results))
191 }
192
193 r0 := results[0]
194 if r0.Distance() != s1.StraightChordAngle {
195 t.Errorf("result[1].Distance = %v, want %v", r0.Distance(), s1.StraightChordAngle)
196 }
197 if r0.shapeID != 0 {
198 t.Errorf("result[0].shapeID = %v, want 0", r0.shapeID)
199 }
200 if r0.edgeID != 2 {
201 t.Errorf("result[0].edgeID = %v, want 2", r0.edgeID)
202 }
203
204 r1 := results[1]
205 if r1.Distance() != s1.StraightChordAngle {
206 t.Errorf("result[1].Distance = %v, want %v", r1.Distance(), s1.StraightChordAngle)
207 }
208 if r1.shapeID != 0 {
209 t.Errorf("result[1].shapeID = %v, want 0", r1.shapeID)
210 }
211 if r1.edgeID != 3 {
212 t.Errorf("result[1].edgeID = %v, want 3", r1.edgeID)
213 }
214 }
215
216 func TestFurthestEdgeQueryEmptyPolygonTarget(t *testing.T) {
217
218 emptyPolygonIndex := makeShapeIndex("# # empty")
219 pointIndex := makeShapeIndex("1:1 # #")
220 fullPolygonIndex := makeShapeIndex("# # full")
221
222 target := NewMaxDistanceToShapeIndexTarget(emptyPolygonIndex)
223
224 emptyQuery := NewFurthestEdgeQuery(emptyPolygonIndex, NewFurthestEdgeQueryOptions().IncludeInteriors(true))
225 if got, want := emptyQuery.Distance(target), s1.NegativeChordAngle; got != want {
226 t.Errorf("emptyQuery.Distance(%v) = %v, want %v", target, got, want)
227 }
228
229 pointQuery := NewFurthestEdgeQuery(pointIndex, NewFurthestEdgeQueryOptions().IncludeInteriors(true))
230 if got, want := pointQuery.Distance(target), s1.NegativeChordAngle; got != want {
231 t.Errorf("pointQuery.Distance(%v) = %v, want %v", target, got, want)
232 }
233
234 fullQuery := NewFurthestEdgeQuery(fullPolygonIndex, NewFurthestEdgeQueryOptions().IncludeInteriors(true))
235 if got, want := fullQuery.Distance(target), s1.NegativeChordAngle; got != want {
236 t.Errorf("fullQuery.Distance(%v) = %v, want %v", target, got, want)
237 }
238 }
239
240 func TestFurthestEdgeQueryFullPolygonTarget(t *testing.T) {
241
242
243 emptyPolygonIndex := makeShapeIndex("# # empty")
244 pointIndex := makeShapeIndex("1:1 # #")
245 fullPolygonIndex := makeShapeIndex("# #")
246 fullPolygonIndex.Add(makePolygon("full", true))
247
248 target := NewMaxDistanceToShapeIndexTarget(fullPolygonIndex)
249
250 emptyQuery := NewFurthestEdgeQuery(emptyPolygonIndex, NewFurthestEdgeQueryOptions().IncludeInteriors(true))
251 if got, want := emptyQuery.Distance(target), s1.NegativeChordAngle; got != want {
252 t.Errorf("emptyQuery.Distance(%v) = %v, want %v", target, got, want)
253 }
254
255 pointQuery := NewFurthestEdgeQuery(pointIndex, NewFurthestEdgeQueryOptions().IncludeInteriors(true))
256 if got, want := pointQuery.Distance(target), s1.StraightChordAngle; got != want {
257 t.Errorf("pointQuery.Distance(%v) = %v, want %v", target, got, want)
258 }
259
260 fullQuery := NewFurthestEdgeQuery(fullPolygonIndex, NewFurthestEdgeQueryOptions().IncludeInteriors(true))
261 if got, want := fullQuery.Distance(target), s1.StraightChordAngle; got != want {
262 t.Errorf("fullQuery.Distance(%v) = %v, want %v", target, got, want)
263 }
264 }
265
266
289
290
291
292
293
294
295
View as plain text