Hi Gerd

Here is patch that prevents possible underflow when node is very close
to an almost horizontal or vertical line and incorrect results when
exactly on this line.

Ticker

Index: src/uk/me/parabola/util/IsInUtil.java
===================================================================
--- src/uk/me/parabola/util/IsInUtil.java	(revision 4495)
+++ src/uk/me/parabola/util/IsInUtil.java	(working copy)
@@ -351,29 +351,29 @@
 					++lhsCount; // definite line segment all slightly to the left
 				} else { // need to consider this segment more carefully.
 					if (leadLat == trailLat)
-						lonDif = 0; // dif meaningless; will be ignored in crossing calc, 0 handled for distToLine calc
+						lonDif = Double.NaN;
 					else
 						lonDif = nodeLon - trailLon - (double)(nodeLat - trailLat) / (leadLat - trailLat) * (leadLon - trailLon);
 					if (leadLon == trailLon)
-						latDif = 0; // ditto
+						latDif = Double.NaN;
 					else
 						latDif = nodeLat - trailLat - (double)(nodeLon - trailLon) / (leadLon - trailLon) * (leadLat - trailLat);
 					// calculate distance to segment using right-angle attitude theorem
-					final double lonDifSqrd = lonDif*lonDif;
-					final double latDifSqrd = latDif*latDif;
 					log.debug("inBox", leadLon-nodeLon, leadLat-nodeLat, trailLon-nodeLon, trailLat-nodeLat, lonDif, latDif, lhsCount, rhsCount);
-					// there a small area between the square EPS_HP*2 and the circle within, where, if polygon vertix and
+					// there is a small area between the square EPS_HP*2 and the circle within, where, if polygon vertix and
 					// segments are the other side, it might still be calculated as ON.
-					if (lonDif == 0)
-						distSqrd = latDifSqrd;
-					else if (latDif == 0)
-						distSqrd = lonDifSqrd;
+					if (Double.isNaN(lonDif))
+						distSqrd = latDif*latDif;
+					else if (Double.isNaN(latDif))
+						distSqrd = lonDif*lonDif;
+					else if (Math.abs(lonDif) < EPS_HP || Math.abs(latDif) < EPS_HP)
+						return ON;
 					else
-						distSqrd = lonDifSqrd * latDifSqrd / (lonDifSqrd + latDifSqrd);
+						distSqrd = lonDif*lonDif * latDif*latDif / (lonDif*lonDif + latDif*latDif);
 					if (distSqrd < EPS_HP_SQRD)
 						return ON;
 					if ((trailLat <= nodeLat && leadLat >  nodeLat) || //  an upward crossing
-					    (trailLat >  nodeLat && leadLat <= nodeLat)) { // a downward crossing
+						(trailLat >  nodeLat && leadLat <= nodeLat)) { // a downward crossing
 						if (lonDif < 0)
 							++rhsCount; // a valid crossing right of nodeLon
 						else
_______________________________________________
mkgmap-dev mailing list
mkgmap-dev@lists.mkgmap.org.uk
http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev

Reply via email to