[GRASS-SVN] r57839 - grass/trunk/lib/gis
svn_grass at osgeo.org
svn_grass at osgeo.org
Wed Sep 25 06:15:33 PDT 2013
Author: mmetz
Date: 2013-09-25 06:15:32 -0700 (Wed, 25 Sep 2013)
New Revision: 57839
Modified:
grass/trunk/lib/gis/plot.c
Log:
libgis: fix FPE tolerance for plotting
Modified: grass/trunk/lib/gis/plot.c
===================================================================
--- grass/trunk/lib/gis/plot.c 2013-09-25 10:39:29 UTC (rev 57838)
+++ grass/trunk/lib/gis/plot.c 2013-09-25 13:15:32 UTC (rev 57839)
@@ -449,16 +449,20 @@
}
/* check if perimeter has odd number of points */
- if (st->np % 2)
+ if (st->np & 1) {
+ 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(st->P, st->np, sizeof(POINT), edge_order);
/* plot */
for (i = 1; i < st->np; i += 2) {
- if (st->P[i].y != st->P[i - 1].y)
+ if (st->P[i].y != st->P[i - 1].y) {
+ G_debug(1, "Weird internal error: edge leaves row");
return OUT_OF_SYNC;
+ }
st->row_fill(st->P[i].y, st->P[i - 1].x + shift1, st->P[i].x + shift1);
}
if (st->window.proj == PROJECTION_LL) { /* now do wrap-around, part 2 */
@@ -581,8 +585,10 @@
} /* for() */
/* check if perimeter has odd number of points */
- if (st->np % 2)
+ if (st->np & 1) {
+ 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(st->P, st->np, sizeof(POINT), &edge_order);
@@ -590,8 +596,10 @@
/* plot */
for (j = 0; j < rings; j++) {
for (i = 1; i < st->np; i += 2) {
- if (st->P[i].y != st->P[i - 1].y)
+ if (st->P[i].y != st->P[i - 1].y) {
+ G_debug(1, "Weird internal error: edge leaves row");
return OUT_OF_SYNC;
+ }
st->row_fill(st->P[i].y, st->P[i - 1].x + shift1[j], st->P[i].x + shift1[j]);
}
if (st->window.proj == PROJECTION_LL) { /* now do wrap-around, part 2 */
@@ -619,19 +627,27 @@
static int edge(double x0, double y0, double x1, double y1)
{
- double m;
- double dx, dy, x;
+ double m, d;
+ double x;
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 */
- dx = x0 - x1;
- dy = y0 - y1;
- if (fabs(dy) < 1e-10)
+ d = frexp(d, &exp);
+ exp -= 52;
+ d = ldexp(d, exp);
+ }
+
+ if (fabs(y0 - y1) < d)
return 1;
- m = (x0 - x1) / dy;
-
if (y0 < y1) {
ystart = iceil(y0);
ystop = ifloor(y1);
@@ -648,12 +664,14 @@
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++))
return 0;
x += m;
}
+
return 1;
}
More information about the grass-commit
mailing list