@@ -16,6 +16,8 @@ package s2
16
16
17
17
import (
18
18
"sort"
19
+
20
+ "github.com/golang/geo/r3"
19
21
)
20
22
21
23
// ConvexHullQuery builds the convex hull of any collection of points,
@@ -231,7 +233,24 @@ func singlePointLoop(p Point) *Loop {
231
233
232
234
// singleEdgeLoop constructs a loop consisting of the two vertices and their midpoint.
233
235
func singleEdgeLoop (a , b Point ) * Loop {
234
- vertices := []Point {a , b , {a .Add (b .Vector ).Normalize ()}}
236
+ // If the points are exactly antipodal we return the full loop.
237
+ //
238
+ // Note that we could use the code below even in this case (which would
239
+ // return a zero-area loop that follows the edge AB), except that (1) the
240
+ // direction of AB is defined using symbolic perturbations and therefore is
241
+ // not predictable by ordinary users, and (2) Loop disallows anitpodal
242
+ // adjacent vertices and so we would need to use 4 vertices to define the
243
+ // degenerate loop. (Note that the Loop antipodal vertex restriction is
244
+ // historical and now could easily be removed, however it would still have
245
+ // the problem that the edge direction is not easily predictable.)
246
+ if a .Add (b .Vector ) == (r3.Vector {}) {
247
+ return FullLoop ()
248
+ }
249
+
250
+ // Construct a loop consisting of the two vertices and their midpoint. We
251
+ // use Interpolate() to ensure that the midpoint is very close to
252
+ // the edge even when its endpoints nearly antipodal.
253
+ vertices := []Point {a , b , Interpolate (0.5 , a , b )}
235
254
loop := LoopFromPoints (vertices )
236
255
// The resulting loop may be clockwise, so invert it if necessary.
237
256
loop .Normalize ()
0 commit comments