@@ -47,16 +47,15 @@ double Bbox_Double::center_lon() const
4747
4848bool Bbox_Double::contains (const Point_Double& point) const
4949{
50- if (point.lat < south || point.lat > north)
50+ if (point.lat + 5e-8 < south || point.lat - 5e-8 > north)
5151 return false ;
5252
5353 if (east >= west)
54- return point.lon >= west && point.lon <= east;
54+ return point.lon + 5e-8 >= west && point.lon - 5e-8 <= east;
5555
56- return point.lon >= west || point.lon <= east;
56+ return point.lon + 5e-8 >= west || point.lon - 5e-8 <= east;
5757}
5858
59-
6059bool Bbox_Double::intersects (const Point_Double& from, const Point_Double& to) const
6160{
6261 double from_lon = from.lon ;
@@ -67,48 +66,55 @@ bool Bbox_Double::intersects(const Point_Double& from, const Point_Double& to) c
6766 to_lon += 360 .;
6867
6968 double delta_from = 0 ;
70- if (from.lat < south)
69+ if (from.lat + 5e-8 < south)
7170 {
72- if (to.lat < south)
71+ if (to.lat + 5e-8 < south)
7372 return false ;
74- // Otherwise just adjust from.lat and from.lon
75- delta_from = (to_lon - from_lon)*(south - from.lat )/(to.lat - from.lat );
73+ if (to.lat - 5e-8 > from.lat )
74+ delta_from = (to_lon - from_lon)*(south - from.lat )/(to.lat - from.lat );
75+ // Asserted: (south, from_lon + delta_from) is a point on the segment
7676 }
77- else if (from.lat > north)
77+ else if (from.lat - 5e-8 > north)
7878 {
79- if (to.lat > north)
79+ if (to.lat - 5e-8 > north)
8080 return false ;
81- // Otherwise just adjust from.lat and from.lon
82- delta_from = (to_lon - from_lon)*(north - from.lat )/(to.lat - from.lat );
81+ if (to.lat + 5e-8 < from.lat )
82+ delta_from = (to_lon - from_lon)*(north - from.lat )/(to.lat - from.lat );
83+ // Asserted: (north, from_lon + delta_from) is a point on the segment
8384 }
8485
85- if (to.lat < south)
86+ if (to.lat + 5e-8 < south && from. lat - 5e-8 > to. lat )
8687 // Adjust to.lat and to.lon
8788 to_lon += (from_lon - to_lon)*(south - to.lat )/(from.lat - to.lat );
88- else if (to.lat > north)
89+ // Asserted: (south, to_lon) is a point on the segment
90+ else if (to.lat - 5e-8 > north && from.lat + 5e-8 < to.lat )
8991 // Adjust to.lat and to.lon
9092 to_lon += (from_lon - to_lon)*(north - to.lat )/(from.lat - to.lat );
93+ // Asserted: (north, to_lon) is a point on the segment
9194 from_lon += delta_from;
95+
96+ // Asserted: (std::min(north, std::max(south, from.lat)), from_lon) is on the segment
97+ // Asserted: (std::min(north, std::max(south, to.lat)), to_lon) is on the segment
9298
9399 // Now we know that both latitudes are between south and north.
94- // Thus we only need to check whether the segment touches the bbox in its east-west-extension .
100+ // Thus we only need to check whether the segment touches the bbox in its east-west-extent .
95101 // Note that the lons have now values between -180.0 and 360.0.
96102 double min_lon = std::min (from_lon, to_lon);
97103 double max_lon = std::max (from_lon, to_lon);
98104 if (west <= east)
99105 {
100106 if (max_lon < 180 .)
101- return min_lon <= east && max_lon >= west;
107+ return min_lon - 5e-8 <= east && max_lon + 5e-8 >= west;
102108 else if (min_lon > 180 .)
103- return min_lon - 360 . <= east && max_lon - 360 . >= west;
109+ return min_lon - 5e-8 - 360 . <= east && max_lon + 5e-8 - 360 . >= west;
104110
105- return min_lon <= east && max_lon - 360 . >= west;
111+ return min_lon - 5e-8 <= east && max_lon + 5e-8 - 360 . >= west;
106112 }
107113
108114 if (max_lon < 180 .)
109- return min_lon <= east || max_lon >= west;
115+ return min_lon - 5e-8 <= east || max_lon + 5e-8 >= west;
110116 else if (min_lon > 180 .)
111- return min_lon - 360 . <= east || max_lon - 360 . >= west;
117+ return min_lon - 5e-8 - 360 . <= east || max_lon + 5e-8 - 360 . >= west;
112118
113119 return true ;
114120}
0 commit comments