From: Paul Ramsey <pramsey@cleverelephant.ca>
Date: Wed, 4 Nov 2009 00:13:04 +0000 (+0000)
Subject: Remove unit test failure cases in 32-bit architectures. Now have to test correctness
X-Git-Tag: 1.5.0b1~301
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e0381459b7ebd05794657f371fe45f9cfe507de7;p=postgis

Remove unit test failure cases in 32-bit architectures. Now have to test correctness
of algorithms on test data in 64-bit environment.


git-svn-id: http://svn.osgeo.org/postgis/trunk@4732 b70326c6-7e19-0410-871a-916f4a2858ee
---

diff --git a/liblwgeom/cunit/cu_geodetic.c b/liblwgeom/cunit/cu_geodetic.c
index bbe2be6b7..b61e4a6ba 100644
--- a/liblwgeom/cunit/cu_geodetic.c
+++ b/liblwgeom/cunit/cu_geodetic.c
@@ -283,7 +283,7 @@ void test_edge_intersection(void)
 	rv = edge_intersection(e1, e2, &g);
 	CU_ASSERT_EQUAL(rv, LW_FALSE);	
 
-	/* Second Medford case, very short segment vs very long one 	
+	/* Second Medford case, very short segment vs very long one 
 	e1.start.lat = 0.73826546728290887156;
 	e1.start.lon = -2.14426380171833042;
 	e1.end.lat = 0.73826545883786642843;
@@ -368,34 +368,48 @@ void test_edge_intersection(void)
 	CU_ASSERT_DOUBLE_EQUAL(g.lat, 90.0, 0.00001);
 	CU_ASSERT_EQUAL(rv, LW_TRUE); 
 
-	/* End touches arc at north pole */
-	edge_set(-180.0, 80.0, 0.0, 80.0, &e1);
-	edge_set(90.0, 80.0, -90.0, 90.0, &e2);
+	/* Equal edges return true */
+	edge_set(45.0, 10.0, 50.0, 20.0, &e1);
+	edge_set(45.0, 10.0, 50.0, 20.0, &e2);
 	rv = edge_intersection(e1, e2, &g);
 	point_rad2deg(&g);
-	CU_ASSERT_DOUBLE_EQUAL(g.lat, 90.0, 0.00001);
 	CU_ASSERT_EQUAL(rv, LW_TRUE); 	
 
-	/* End touches end at north pole */
-	edge_set(-180.0, 80.0, 0.0, 90.0, &e1);
-	edge_set(90.0, 80.0, -90.0, 90.0, &e2);
+	/* Parallel edges (same great circle, different end points) return true  */
+	edge_set(40.0, 0.0, 70.0, 0.0, &e1);
+	edge_set(60.0, 0.0, 50.0, 0.0, &e2);
 	rv = edge_intersection(e1, e2, &g);
 	point_rad2deg(&g);
-	CU_ASSERT_DOUBLE_EQUAL(g.lat, 90.0, 0.00001);
 	CU_ASSERT_EQUAL(rv, LW_TRUE); 	
 
-	/* Equal edges return true */
-	edge_set(45.0, 10.0, 50.0, 20.0, &e1);
-	edge_set(45.0, 10.0, 50.0, 20.0, &e2);
+	/* End touches arc at north pole */
+	edge_set(-180.0, 80.0, 0.0, 80.0, &e1);
+	edge_set(90.0, 80.0, -90.0, 90.0, &e2);
 	rv = edge_intersection(e1, e2, &g);
 	point_rad2deg(&g);
+#if 0
+	printf("\n");
+	printf("LINESTRING(%.15g %.15g, %.15g %.15g)\n", e1.start.lon,  e1.start.lat, e1.end.lon,  e1.end.lat);
+	printf("LINESTRING(%.15g %.15g, %.15g %.15g)\n", e2.start.lon,  e2.start.lat, e2.end.lon,  e2.end.lat);
+	printf("g = (%.15g %.15g)\n", g.lon, g.lat);
+	printf("rv = %d\n", rv);
+#endif
+	CU_ASSERT_DOUBLE_EQUAL(g.lat, 90.0, 0.00001);
 	CU_ASSERT_EQUAL(rv, LW_TRUE); 	
 
-	/* Parallel edges (same great circle, different end points) return true  */
-	edge_set(40.0, 0.0, 70.0, 0.0, &e1);
-	edge_set(60.0, 0.0, 50.0, 0.0, &e2);
+	/* End touches end at north pole */
+	edge_set(-180.0, 80.0, 0.0, 90.0, &e1);
+	edge_set(90.0, 80.0, -90.0, 90.0, &e2);
 	rv = edge_intersection(e1, e2, &g);
 	point_rad2deg(&g);
+#if 0
+	printf("\n");
+	printf("LINESTRING(%.15g %.15g, %.15g %.15g)\n", e1.start.lon,  e1.start.lat, e1.end.lon,  e1.end.lat);
+	printf("LINESTRING(%.15g %.15g, %.15g %.15g)\n", e2.start.lon,  e2.start.lat, e2.end.lon,  e2.end.lat);
+	printf("g = (%.15g %.15g)\n", g.lon, g.lat);
+	printf("rv = %d\n", rv);
+#endif
+	CU_ASSERT_DOUBLE_EQUAL(g.lat, 90.0, 0.00001);
 	CU_ASSERT_EQUAL(rv, LW_TRUE); 	
 
 }
diff --git a/liblwgeom/lwgeodetic.c b/liblwgeom/lwgeodetic.c
index 75584edc5..eee0d8c1d 100644
--- a/liblwgeom/lwgeodetic.c
+++ b/liblwgeom/lwgeodetic.c
@@ -438,7 +438,19 @@ int edge_point_in_cone(GEOGRAPHIC_EDGE e, GEOGRAPHIC_POINT p)
 	vp_dot_vcp = dot_product(vp, vcp);
 	LWDEBUGF(4,"vp_dot_vcp %.19g",vp_dot_vcp);
 	/* If p is more similar than start then p is inside the cone */
-	if ( vp_dot_vcp >= vs_dot_vcp )
+	LWDEBUGF(4,"fabs(vp_dot_vcp - vs_dot_vcp) %.39g",fabs(vp_dot_vcp - vs_dot_vcp));
+	
+	/* 
+	** We want to test that vp_dot_vcp is >= vs_dot_vcp but there are 
+	** numerical stability issues for values that are very very nearly 
+	** equal. Unfortunately there are also values of vp_dot_vcp that are legitimately
+	** very close to but still less than vs_dot_vcp which we also need to catch.
+	** The tolerance of 10-17 seems to do the trick on 32-bit and 64-bit architectures,
+	** for the test cases here.
+	** However, tuning the tolerance value feels like a dangerous hack. 
+	** Fundamentally, the problem is that this test is so sensitive.
+	*/
+	if ( vp_dot_vcp > vs_dot_vcp || fabs(vp_dot_vcp - vs_dot_vcp) < 1e-17 )
 	{
 		LWDEBUG(4, "point is in cone");
 		return LW_TRUE;
@@ -774,10 +786,10 @@ int edge_intersection(GEOGRAPHIC_EDGE e1, GEOGRAPHIC_EDGE e2, GEOGRAPHIC_POINT *
 		}
 	}
 	unit_normal(ea, eb, &v);
-	LWDEBUGF(4, "v == POINT(%.8g %.8g %.8g)", v.x, v.y, v.z);
+	LWDEBUGF(4, "v == POINT(%.12g %.12g %.12g)", v.x, v.y, v.z);
 	g->lat = atan2(v.z, sqrt(v.x * v.x + v.y * v.y));
 	g->lon = atan2(v.y, v.x);
-	LWDEBUGF(4, "g == GPOINT(%.6g %.6g)", g->lat, g->lon);
+	LWDEBUGF(4, "g == GPOINT(%.12g %.12g)", g->lat, g->lon);
 	LWDEBUGF(4, "g == POINT(%.12g %.12g)", rad2deg(g->lon), rad2deg(g->lat));
 	if ( edge_contains_point(e1, *g) && edge_contains_point(e2, *g) )
 	{
@@ -785,6 +797,7 @@ int edge_intersection(GEOGRAPHIC_EDGE e1, GEOGRAPHIC_EDGE e2, GEOGRAPHIC_POINT *
 	}
 	else
 	{
+		LWDEBUG(4, "flipping point to other side of sphere");
 		g->lat = -1.0 * g->lat;
 		g->lon = g->lon + M_PI;
 		if ( g->lon > M_PI )