[GRASS-SVN] r57844 - grass/branches/releasebranch_6_4/lib/gis

svn_grass at osgeo.org svn_grass at osgeo.org
Thu Sep 26 03:30:53 PDT 2013


Author: mmetz
Date: 2013-09-26 03:30:53 -0700 (Thu, 26 Sep 2013)
New Revision: 57844

Modified:
   grass/branches/releasebranch_6_4/lib/gis/plot.c
Log:
libgis: backport fix FPE error tolerance for plotting

Modified: grass/branches/releasebranch_6_4/lib/gis/plot.c
===================================================================
--- grass/branches/releasebranch_6_4/lib/gis/plot.c	2013-09-26 10:27:51 UTC (rev 57843)
+++ grass/branches/releasebranch_6_4/lib/gis/plot.c	2013-09-26 10:30:53 UTC (rev 57844)
@@ -485,16 +485,20 @@
     }
 
     /* check if perimeter has odd number of points */
-    if (np % 2)
+    if (np % 2) {
+	G_debug(1, "Weird internal error: perimeter has odd number of points");
 	return OUT_OF_SYNC;
+    }
 
     /* sort the edge points by col(x) and then by row(y) */
     qsort(P, np, sizeof(POINT), &edge_order);
 
     /* plot */
     for (i = 1; i < np; i += 2) {
-	if (P[i].y != P[i - 1].y)
+	if (P[i].y != P[i - 1].y) {
+	    G_debug(1, "Weird internal error: edge leaves row");
 	    return OUT_OF_SYNC;
+	}
 	row_fill(P[i].y, P[i - 1].x + shift1, P[i].x + shift1);
     }
     if (window.proj == PROJECTION_LL) {	/* now do wrap-around, part 2 */
@@ -622,8 +626,10 @@
     }				/* for() */
 
     /* check if perimeter has odd number of points */
-    if (np % 2)
+    if (np % 2) {
+	G_debug(1, "Weird internal error: perimeter has odd number of points");
 	return OUT_OF_SYNC;
+    }
 
     /* sort the edge points by col(x) and then by row(y) */
     qsort(P, np, sizeof(POINT), &edge_order);
@@ -631,8 +637,10 @@
     /* plot */
     for (j = 0; j < rings; j++) {
 	for (i = 1; i < np; i += 2) {
-	    if (P[i].y != P[i - 1].y)
+	    if (P[i].y != P[i - 1].y) {
+		G_debug(1, "Weird internal error: edge leaves row");
 		return OUT_OF_SYNC;
+	    }
 	    row_fill(P[i].y, P[i - 1].x + shift1[j], P[i].x + shift1[j]);
 	}
 	if (window.proj == PROJECTION_LL) {	/* now do wrap-around, part 2 */
@@ -661,17 +669,26 @@
 static int edge(double x0, double y0, double x1, double y1)
 {
     register double m;
-    double dy, x;
+    double x, d;
     int ystart, ystop;
+    int exp;
 
+    /* tolerance to avoid FPE */
+    d = GRASS_EPSILON;
+    if (y0 != y1) {
+	if (fabs(y0) > fabs(y1))
+	    d = fabs(y0);
+	else
+	    d = fabs(y1);
 
-    /* tolerance to avoid FPE */
-    dy = y0 - y1;
-    if (fabs(dy) < 1e-10)
+	d = frexp(d, &exp);
+	exp -= 53;
+	d = ldexp(d, exp);
+    }
+
+    if (fabs(y0 - y1) < d)
 	return 1;
 
-    m = (x0 - x1) / dy;
-
     if (y0 < y1) {
 	ystart = iceil(y0);
 	ystop = ifloor(y1);
@@ -687,6 +704,7 @@
     if (ystart > ystop)
 	return 1;		/* does not cross center line of row */
 
+    m = (x0 - x1) / (y0 - y1);
     x = m * (ystart - y0) + x0;
     while (ystart <= ystop) {
 	if (!edge_point(x, ystart++))



More information about the grass-commit mailing list