diff --git a/s2/rect.go b/s2/rect.go index 0fb99a1..165f37e 100644 --- a/s2/rect.go +++ b/s2/rect.go @@ -247,7 +247,7 @@ func (r Rect) CapBound() Cap { // maximum cap size is achieved at one of the rectangle vertices. For // rectangles that are larger than 180 degrees, we punt and always return a // bounding cap centered at one of the two poles. - if math.Remainder(r.Lng.Hi-r.Lng.Lo, 2*math.Pi) >= 0 && r.Lng.Hi-r.Lng.Lo < 2*math.Pi { + if math.Remainder(r.Lng.Hi-r.Lng.Lo, 2*math.Pi) >= 0 && r.Lng.Hi-r.Lng.Lo <= math.Pi { midCap := CapFromPoint(PointFromLatLng(r.Center())).AddPoint(PointFromLatLng(r.Lo())).AddPoint(PointFromLatLng(r.Hi())) if midCap.Height() < poleCap.Height() { return midCap diff --git a/s2/rect_test.go b/s2/rect_test.go index 66c105c..272b444 100644 --- a/s2/rect_test.go +++ b/s2/rect_test.go @@ -395,6 +395,16 @@ func TestRectCapBound(t *testing.T) { rectFromDegrees(-30, -150, -10, 50), CapFromCenterAngle(Point{r3.Vector{X: 0, Y: 0, Z: -1}}, s1.Angle(80)*s1.Degree), }, + { + // Longitude span > 180 degrees and latitude span > 90 degrees. This results + // in a polar cap that is larger than the "midpoint cap" (centered at the + // center of the rect and containing the vertices), but is nonetheless the + // correct result. The "midpoint cap" must not be returned since it doesn't + // contain the entire rect due the rect being wider than 180 degrees. + // In this example, (-34, 49) is in the rect but not the midpoint cap. + rectFromDegrees(-60, -150, 70, 50), + CapFromCenterAngle(Point{r3.Vector{X: 0, Y: 0, Z: 1}}, s1.Angle(150)*s1.Degree), + }, } for _, test := range tests { if got := test.r.CapBound(); !test.want.ApproxEqual(got) {