func reflectPoints(pts []Point) []Point {
	var negativePts []Point
	for _, p := range pts {
		negativePts = append(negativePts, Point{p.Mul(-1)})
	}
	return negativePts
}
Negates S2 points to reflect them through the sphere.
package s2
import (
	"reflect"
	"sort"
	"testing"
	"github.com/golang/geo/s1"
)
func TestDistanceTargetMaxCellTargetCapBound(t *testing.T) {
	var md maxDistance
	zero := md.zero()
	for i := 0; i < 100; i++ {
		cell := CellFromCellID(randomCellID())
		target := NewMaxDistanceToCellTarget(cell)
		c := target.capBound()
		for j := 0; j < 100; j++ {
			pTest := randomPoint()
			if !c.ContainsPoint(pTest) {
				if got := cell.MaxDistance(pTest); !zero.less(maxDistance(got)) {
					t.Errorf("%v.MaxDistance(%v) = %v, want < %v", cell, pTest, got, zero)
				}
			}
		}
	}
}
func TestDistanceTargetMaxCellTargetUpdateDistance(t *testing.T) {
	var ok bool
	targetCell := CellFromCellID(cellIDFromPoint(parsePoint("0:1")))
	target := NewMaxDistanceToCellTarget(targetCell)
	dist0 := maxDistance(0)
	dist10 := maxDistance(s1.ChordAngleFromAngle(s1.Angle(10) * s1.Degree))
	p := parsePoint("0:0")
	if _, ok = target.updateDistanceToPoint(p, dist0); !ok {
		t.Errorf("target.updateDistanceToPoint(%v, %v) should have succeeded", p, dist0)
	}
	if _, ok = target.updateDistanceToPoint(p, dist10); ok {
		t.Errorf("target.updateDistanceToPoint(%v, %v) should have failed", p, dist10)
	}
	dist0 = maxDistance(0)
	pts := parsePoints("0:2, 0:3")
	edge := Edge{pts[0], pts[1]}
	if _, ok := target.updateDistanceToEdge(edge, dist0); !ok {
		t.Errorf("target.updateDistanceToEdge(%v, %v) should have succeeded", edge, dist0)
	}
	if _, ok := target.updateDistanceToEdge(edge, dist10); ok {
		t.Errorf("target.updateDistanceToEdge(%v, %v) should have failed", edge, dist10)
	}
	dist0 = maxDistance(0)
	cell := CellFromCellID(cellIDFromPoint(parsePoint("0:0")))
	if _, ok = target.updateDistanceToCell(cell, dist0); !ok {
		t.Errorf("target.updateDistanceToCell(%v, %v) should have succeeded", cell, dist0)
	}
	if _, ok = target.updateDistanceToCell(cell, dist10); ok {
		t.Errorf("target.updateDistanceToCell(%v, %v) should have failed", cell, dist10)
	}
}
func TestDistanceTargetMaxCellTargetUpdateDistanceToCellAntipodal(t *testing.T) {
	var maxDist maxDistance
	p := parsePoint("0:0")
	targetCell := CellFromCellID(cellIDFromPoint(p))
	target := NewMaxDistanceToCellTarget(targetCell)
	dist := maxDist.infinity()
	cell := CellFromCellID(cellIDFromPoint(Point{p.Mul(-1)}))
	dist0, ok := target.updateDistanceToCell(cell, dist)
	if !ok {
		t.Errorf("target.updateDistanceToCell(%v, %v) should have succeeded", cell, dist)
	}
	if dist0.chordAngle() != s1.StraightChordAngle {
		t.Errorf("target.updateDistanceToCell() = %v, want %v", dist0.chordAngle(), s1.StraightChordAngle)
	}
	if _, ok := target.updateDistanceToCell(cell, dist0); ok {
		t.Errorf("target.updateDistanceToCell(%v, %v) should have failed", cell, dist0)
	}
}
func TestDistanceTargetMaxCellTargetUpdateDistanceToCellWhenEqual(t *testing.T) {
	var maxDist maxDistance
	targetCell := CellFromCellID(cellIDFromPoint(parsePoint("0:1")))
	target := NewMaxDistanceToCellTarget(targetCell)
	dist := maxDist.infinity()
	cell := CellFromCellID(cellIDFromPoint(parsePoint("0:0")))
	dist0, ok := target.updateDistanceToCell(cell, dist)
	if !ok {
		t.Errorf("target.updateDistanceToCell(%v, %v) should have succeeded", cell, dist)
	}
	if _, ok := target.updateDistanceToCell(cell, dist0); ok {
		t.Errorf("target.updateDistanceToCell(%v, %v) should have failed", cell, dist0)
	}
}
func TestDistanceTargetMaxCellTargetUpdateDistanceToEdgeWhenEqual(t *testing.T) {
	var maxDist maxDistance
	targetCell := CellFromCellID(cellIDFromPoint(parsePoint("0:1")))
	target := NewMaxDistanceToCellTarget(targetCell)
	dist := maxDist.infinity()
	pts := parsePoints("0:-1, 0:1")
	edge := Edge{pts[0], pts[1]}
	dist0, ok := target.updateDistanceToEdge(edge, dist)
	if !ok {
		t.Errorf("target.updateDistanceToEdge(%v, %v) should have succeeded", edge, dist)
	}
	if _, ok := target.updateDistanceToEdge(edge, dist0); ok {
		t.Errorf("target.updateDistanceToEdge(%v, %v) should have failed", edge, dist0)
	}
}
func TestDistanceTargetMaxCellTargetVisitContainingShapes(t *testing.T) {
	index := makeShapeIndex("1:1 # 1:1, 2:2 # 0:0, 0:3, 3:0 | 6:6, 6:9, 9:6 | -1:-1, -1:5, 5:-1")
	targetCell := CellFromCellID(cellIDFromPoint(Point{parsePoint("1:1").Mul(-1)}))
	target := NewMaxDistanceToCellTarget(targetCell)
	if got, want := containingShapesForTarget(target, index, 1), []int{2}; !reflect.DeepEqual(got, want) {
		t.Errorf("containingShapesForTarget(%v, %q, 1) = %+v, want %+v", target, shapeIndexDebugString(index), got, want)
	}
	if got, want := containingShapesForTarget(target, index, 5), []int{2, 4}; !reflect.DeepEqual(got, want) {
		t.Errorf("containingShapesForTarget(%v, %q, 5) = %+v, want %+v", target, shapeIndexDebugString(index), got, want)
	}
	target2 := NewMaxDistanceToCellTarget(CellFromCellID(targetCell.ID().Parent(5)))
	if got, want := containingShapesForTarget(target2, index, 5), []int{2, 4}; !reflect.DeepEqual(got, want) {
		t.Errorf("containingShapesForTarget(%v, %q, 5) = %+v, want %+v", target2, shapeIndexDebugString(index), got, want)
	}
}
func TestDistanceTargetMaxPointTargetUpdateDistance(t *testing.T) {
	var ok bool
	var dist0, dist10 distance
	target := NewMaxDistanceToPointTarget(parsePoint("0:0"))
	dist0 = maxDistance(0)
	dist10 = maxDistance(s1.ChordAngleFromAngle(s1.Angle(10) * s1.Degree))
	p := parsePoint("1:0")
	if dist0, ok = target.updateDistanceToPoint(p, dist0); !ok {
		t.Errorf("target.updateDistanceToPoint(%v, %v) should have succeeded", p, dist0)
	}
	if got, want := dist0.chordAngle().Angle().Degrees(), 1.0; !float64Near(got, want, epsilon) {
		t.Errorf("target.updateDistanceToPoint(%v, %v) = %v, want ~%v", p, dist0.chordAngle(), got, want)
	}
	if _, ok = target.updateDistanceToPoint(p, dist10); ok {
		t.Errorf("target.updateDistanceToPoint(%v, %v) should have failed", p, dist0)
	}
	dist0 = maxDistance(0)
	pts := parsePoints("0:-1, 0:1")
	edge := Edge{pts[0], pts[1]}
	if dist0, ok = target.updateDistanceToEdge(edge, dist0); !ok {
		t.Errorf("target.updateDistanceToEdge(%v, %v) should have succeeded", edge, dist0)
	}
	if got, want := dist0.chordAngle().Angle().Degrees(), 1.0; !float64Near(got, want, epsilon) {
		t.Errorf("target.updateDistanceToEdge(%v, %v) = %v, want ~%v", edge, dist0.chordAngle(), got, want)
	}
	if _, ok = target.updateDistanceToEdge(edge, dist10); ok {
		t.Errorf("target.updateDistanceToEdge(%v, %v) should have failed", edge, dist10)
	}
	dist0 = maxDistance(0)
	cell := CellFromCellID(cellIDFromPoint(parsePoint("0:0")))
	if _, ok = target.updateDistanceToCell(cell, dist0); !ok {
		t.Errorf("target.updateDistanceToCell(%v, %v) should have succeeded", cell, dist0)
	}
	if _, ok = target.updateDistanceToCell(cell, dist10); ok {
		t.Errorf("target.updateDistanceToCell(%v, %v) should have failed", cell, dist10)
	}
}
func TestDistanceTargetMaxPointTargetUpdateDistanceToCellWhenEqual(t *testing.T) {
	var maxDist maxDistance
	target := NewMaxDistanceToPointTarget(parsePoint("1:0"))
	dist := maxDist.infinity()
	cell := CellFromCellID(cellIDFromPoint(parsePoint("0:0")))
	dist0, ok := target.updateDistanceToCell(cell, dist)
	if !ok {
		t.Errorf("target.updateDistanceToCell(%v, %v) should have succeeded", cell, dist)
	}
	if _, ok := target.updateDistanceToCell(cell, dist0); ok {
		t.Errorf("target.updateDistanceToCell(%v, %v) should have failed", cell, dist0)
	}
}
func TestDistanceTargetMaxPointTargetUpdateDistanceToEdgeWhenEqual(t *testing.T) {
	var maxDist maxDistance
	target := NewMaxDistanceToPointTarget(parsePoint("1:0"))
	dist := maxDist.infinity()
	pts := parsePoints("0:-1, 0:1")
	edge := Edge{pts[0], pts[1]}
	dist0, ok := target.updateDistanceToEdge(edge, dist)
	if !ok {
		t.Errorf("target.updateDistanceToEdge(%v, %v) should have succeeded", edge, dist)
	}
	if _, ok := target.updateDistanceToEdge(edge, dist0); ok {
		t.Errorf("target.updateDistanceToEdge(%v, %v) should have failed", edge, dist0)
	}
}
func containingShapesForTarget(target distanceTarget, index *ShapeIndex, maxShapes int) []int {
	shapeIDs := map[int32]bool{}
	target.visitContainingShapes(index,
		func(containingShape Shape, targetPoint Point) bool {
			shapeIDs[index.idForShape(containingShape)] = true
			return len(shapeIDs) < maxShapes
		})
	var ids []int
	for k := range shapeIDs {
		ids = append(ids, int(k))
	}
	sort.Ints(ids)
	return ids
}
func TestDistanceTargetMaxPointTargetVisitContainingShapes(t *testing.T) {
	index := makeShapeIndex("1:1 # 1:1, 2:2 # 0:0, 0:3, 3:0 | 6:6, 6:9, 9:6 | 0:0, 0:4, 4:0")
	point := Point{parsePoint("1:1").Mul(-1)}
	target := NewMaxDistanceToPointTarget(point)
	if got, want := containingShapesForTarget(target, index, 1), []int{2}; !reflect.DeepEqual(got, want) {
		t.Errorf("containingShapesForTarget(%v, %q, 1) = %+v, want %+v", point, shapeIndexDebugString(index), got, want)
	}
	if got, want := containingShapesForTarget(target, index, 5), []int{2, 4}; !reflect.DeepEqual(got, want) {
		t.Errorf("containingShapesForTarget(%v, %q, 5) = %+v, want %+v", point, shapeIndexDebugString(index), got, want)
	}
}
func TestDistanceTargetMaxEdgeTargetUpdateDistance(t *testing.T) {
	var ok bool
	var dist0, dist10 distance
	targetPts := parsePoints("0:-1, 0:1")
	targetEdge := Edge{targetPts[0], targetPts[1]}
	target := NewMaxDistanceToEdgeTarget(targetEdge)
	dist0 = maxDistance(0)
	dist10 = maxDistance(s1.ChordAngleFromAngle(s1.Angle(10) * s1.Degree))
	p := parsePoint("0:2")
	if dist0, ok = target.updateDistanceToPoint(p, dist0); !ok {
		t.Errorf("target.updateDistanceToPoint(%v, %v) should have succeeded", p, dist0)
	}
	if got, want := dist0.chordAngle().Angle().Degrees(), 3.0; !float64Near(got, want, epsilon) {
		t.Errorf("target.updateDistanceToPoint(%v, %v) = %v, want ~%v", p, dist0.chordAngle(), got, want)
	}
	if _, ok = target.updateDistanceToPoint(p, dist10); ok {
		t.Errorf("target.updateDistanceToPoint(%v, %v) should have failed", p, dist10)
	}
	dist0 = maxDistance(0)
	pts := parsePoints("0:2, 0:3")
	edge := Edge{pts[0], pts[1]}
	if dist0, ok = target.updateDistanceToEdge(edge, dist0); !ok {
		t.Errorf("target.updateDistanceToEdge(%v, %v) should have succeeded", edge, dist0)
	}
	if got, want := dist0.chordAngle().Angle().Degrees(), 4.0; !float64Near(got, want, epsilon) {
		t.Errorf("target.updateDistanceToEdge(%v, %v) = %v, want ~%v", p, dist0.chordAngle(), got, want)
	}
	if _, ok = target.updateDistanceToEdge(edge, dist10); ok {
		t.Errorf("target.updateDistanceToEdge(%v, %v) should have failed", edge, dist10)
	}
	dist0 = maxDistance(0)
	cell := CellFromCellID(cellIDFromPoint(parsePoint("0:0")))
	if _, ok = target.updateDistanceToCell(cell, dist0); !ok {
		t.Errorf("target.updateDistanceToCell(%v, %v) should have succeeded", cell, dist0)
	}
	if _, ok = target.updateDistanceToCell(cell, dist10); ok {
		t.Errorf("target.updateDistanceToCell(%v, %v) should have failed", cell, dist10)
	}
}
func TestDistanceTargetMaxEdgeTargetUpdateDistanceToCellWhenEqual(t *testing.T) {
	var maxDist maxDistance
	targetEdge := parsePoints("1:0, 1:1")
	target := NewMaxDistanceToEdgeTarget(Edge{targetEdge[0], targetEdge[1]})
	dist := maxDist.infinity()
	cell := CellFromCellID(cellIDFromPoint(parsePoint("0:0")))
	dist0, ok := target.updateDistanceToCell(cell, dist)
	if !ok {
		t.Errorf("target.updateDistanceToCell(%v, %v) should have succeeded", cell, dist)
	}
	if _, ok := target.updateDistanceToCell(cell, dist0); ok {
		t.Errorf("target.updateDistanceToCell(%v, %v) should have failed", cell, dist0)
	}
}
func TestDistanceTargetMaxEdgeTargetUpdateDistanceToEdgeAntipodal(t *testing.T) {
	var maxDist maxDistance
	targetPts := parsePoints("0:89, 0:91")
	targetEdge := Edge{targetPts[0], targetPts[1]}
	target := NewMaxDistanceToEdgeTarget(targetEdge)
	dist := maxDist.infinity()
	pts := parsePoints("1:-90, -1:-90")
	edge := Edge{pts[0], pts[1]}
	dist0, ok := target.updateDistanceToEdge(edge, dist)
	if !ok {
		t.Errorf("target.updateDistanceToEdge(%v, %v) should have succeeded", edge, dist)
	}
	if dist0.chordAngle() != s1.StraightChordAngle {
		t.Errorf("target.updateDistanceToPoint(%v, %v) = %v, want %v", edge, dist0, dist0, s1.StraightChordAngle)
	}
}
func TestDistanceTargetMaxEdgeTargetUpdateDistanceToEdgeWhenEqual(t *testing.T) {
	var maxDist maxDistance
	targetEdge := parsePoints("1:0, 1:1")
	target := NewMaxDistanceToEdgeTarget(Edge{targetEdge[0], targetEdge[1]})
	dist := maxDist.infinity()
	pts := parsePoints("0:-1, 0:1")
	edge := Edge{pts[0], pts[1]}
	dist0, ok := target.updateDistanceToEdge(edge, dist)
	if !ok {
		t.Errorf("target.updateDistanceToEdge(%v, %v) should have succeeded", edge, dist)
	}
	if _, ok := target.updateDistanceToEdge(edge, dist0); ok {
		t.Errorf("target.updateDistanceToEdge(%v, %v) should have failed", edge, dist0)
	}
}
func TestDistanceTargetMaxEdgeTargetVisitContainingShapes(t *testing.T) {
	index := makeShapeIndex("1:1 # 1:1, 2:2 # 0:0, 0:3, 3:0 | 6:6, 6:9, 9:6 | 0:0, 0:4, 4:0")
	pts := parsePoints("1:2, 2:1")
	edge := Edge{Point{pts[0].Mul(-1)}, Point{pts[1].Mul(-1)}}
	target := NewMaxDistanceToEdgeTarget(edge)
	if got, want := containingShapesForTarget(target, index, 1), []int{2}; !reflect.DeepEqual(got, want) {
		t.Errorf("containingShapesForTarget(%v, %q, 1) = %+v, want %+v", target, shapeIndexDebugString(index), got, want)
	}
	if got, want := containingShapesForTarget(target, index, 5), []int{2, 4}; !reflect.DeepEqual(got, want) {
		t.Errorf("containingShapesForTarget(%v, %q, 5) = %+v, want %+v", target, shapeIndexDebugString(index), got, want)
	}
}
func TestDistanceTargetMaxShapeIndexTargetCapBound(t *testing.T) {
}
func TestDistanceTargetMaxShapeIndexTargetUpdateDistanceToCellWhenEqual(t *testing.T) {
	var maxDist maxDistance
	index := makeShapeIndex("1:0 # #")
	target := NewMaxDistanceToShapeIndexTarget(index)
	dist := maxDist.infinity()
	cell := CellFromCellID(cellIDFromPoint(parsePoint("0:0")))
	dist0, ok := target.updateDistanceToCell(cell, dist)
	if !ok {
		t.Errorf("target.updateDistanceToCell(%v, %v) should have succeeded", cell, dist)
	}
	if _, ok := target.updateDistanceToCell(cell, dist0); ok {
		t.Errorf("target.updateDistanceToCell(%v, %v) should have failed", cell, dist0)
	}
}
func TestDistanceTargetMaxShapeIndexTargetUpdateDistanceToEdgeWhenEqual(t *testing.T) {
	var maxDist maxDistance
	index := makeShapeIndex("1:0 # #")
	target := NewMaxDistanceToShapeIndexTarget(index)
	dist := maxDist.infinity()
	pts := parsePoints("0:-1, 0:1")
	edge := Edge{pts[0], pts[1]}
	dist0, ok := target.updateDistanceToEdge(edge, dist)
	if !ok {
		t.Errorf("target.updateDistanceToEdge(%v, %v) should have succeeded", edge, dist)
	}
	if _, ok := target.updateDistanceToEdge(edge, dist0); ok {
		t.Errorf("target.updateDistanceToEdge(%v, %v) should have failed", edge, dist0)
	}
}