]> granicus.if.org Git - postgis/commitdiff
Circular string distances have some failure modes, and test
authorPaul Ramsey <pramsey@cleverelephant.ca>
Fri, 12 Apr 2019 22:16:43 +0000 (22:16 +0000)
committerPaul Ramsey <pramsey@cleverelephant.ca>
Fri, 12 Apr 2019 22:16:43 +0000 (22:16 +0000)
suite should test everything bi-directionally.
References #4326

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

NEWS
liblwgeom/cunit/cu_measures.c
liblwgeom/measures.c

diff --git a/NEWS b/NEWS
index 8fe45b0d680534979db913c3a82bb69669867676..69146a1de75332bbe63124a0581da2f4aa158d9c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,8 @@ PostGIS 2.4.8
   * Bug Fixes and Enhancements *
 
   - #4361, Fix postgis_type_name with (GEOMETRYM,3) (Matt Bretl)
+  - #4326, Fix circular arc distance calculation (Paul Ramsey)
+
 
 PostGIS 2.4.7
 2019/03/11
index 50e180cf312a8460f4cd8dc8b35b98737a3cb1bb..d860f56599ead2c6590c6b090be64f9c0db981e3 100644 (file)
@@ -31,7 +31,8 @@ static LWGEOM* lwgeom_from_text(const char *str)
 }
 
 #define DIST2DTEST(str1, str2, res) \
-       do_test_mindistance_tolerance(str1, str2, res, __LINE__, lwgeom_mindistance2d_tolerance)
+       do_test_mindistance_tolerance(str1, str2, res, __LINE__, lwgeom_mindistance2d_tolerance);\
+       do_test_mindistance_tolerance(str2, str1, res, __LINE__, lwgeom_mindistance2d_tolerance)
 #define DIST3DTEST(str1, str2, res) \
        do_test_mindistance_tolerance(str1, str2, res, __LINE__, lwgeom_mindistance3d_tolerance)
 
@@ -687,6 +688,18 @@ test_lw_dist2d_arc_arc(void)
        POINT2D A1, A2, A3, B1, B2, B3;
        int rv;
 
+       /* Ticket #4326 */
+       lw_dist2d_distpts_init(&dl, DIST_MIN);
+       A1.x = -1.0; A1.y =  4.0;
+       A2.x =  0.0; A2.y =  5.0;
+       A3.x =  1.0; A3.y =  4.0;
+       B1.x =  1.0; B1.y =  6.0;
+       B2.x =  6.0; B2.y =  1.0;
+       B3.x =  9.0; B3.y =  7.0;
+       rv = lw_dist2d_arc_arc(&A1, &A2, &A3, &B1, &B2, &B3, &dl);
+       CU_ASSERT_EQUAL( rv, LW_SUCCESS );
+       CU_ASSERT_DOUBLE_EQUAL(dl.distance, 0.0475666, 0.000001);
+
        /* Unit semicircle at 0,0 */
        B1.x = -1; B1.y = 0;
        B2.x = 0 ; B2.y = 1;
@@ -851,7 +864,6 @@ test_lw_dist2d_arc_arc(void)
        CU_ASSERT_EQUAL( rv, LW_SUCCESS );
        CU_ASSERT_DOUBLE_EQUAL(dl.distance, 5.0, 0.000001);
 
-
 }
 
 static void
index a5a9231d4fbd75083b2b99871bbb3354136ffb03..d5147865b6eb97a4ca22afe68c2085422d2acbd0 100644 (file)
@@ -1496,7 +1496,6 @@ lw_dist2d_arc_arc(const POINT2D *A1, const POINT2D *A2, const POINT2D *A3,
 {
        POINT2D CA, CB; /* Center points of arcs A and B */
        double radius_A, radius_B, d; /* Radii of arcs A and B */
-       POINT2D P; /* Temporary point P */
        POINT2D D; /* Mid-point between the centers CA and CB */
        int pt_in_arc_A, pt_in_arc_B; /* Test whether potential intersection point is within the arc */
 
@@ -1542,11 +1541,13 @@ lw_dist2d_arc_arc(const POINT2D *A1, const POINT2D *A2, const POINT2D *A3,
        if ( radius_B > radius_A )
        {
                const POINT2D *tmp;
+               POINT2D TP; /* Temporary point P */
+               double td;
                tmp = B1; B1 = A1; A1 = tmp;
                tmp = B2; B2 = A2; A2 = tmp;
                tmp = B3; B3 = A3; A3 = tmp;
-               P = CB; CB = CA; CA = P;
-               d = radius_B; radius_B = radius_A; radius_A = d;
+               TP = CB; CB = CA; CA = TP;
+               td = radius_B; radius_B = radius_A; radius_A = td;
        }
 
        /* Circles touch at a point. Is that point within the arcs? */
@@ -1662,8 +1663,8 @@ lw_dist2d_arc_arc(const POINT2D *A1, const POINT2D *A2, const POINT2D *A3,
        {
                lw_dist2d_pt_pt(A1, B1, dl);
                lw_dist2d_pt_pt(A1, B3, dl);
-               lw_dist2d_pt_pt(A2, B1, dl);
-               lw_dist2d_pt_pt(A2, B3, dl);
+               lw_dist2d_pt_pt(A3, B1, dl);
+               lw_dist2d_pt_pt(A3, B3, dl);
                return LW_TRUE;
        }