[geos-commits] [SCM] GEOS branch main updated. 5b62cd06ceeee053f2c7a4bf96138fc1c98675bc

git at osgeo.org git at osgeo.org
Fri Aug 7 11:01:31 PDT 2026


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GEOS".

The branch, main has been updated
       via  5b62cd06ceeee053f2c7a4bf96138fc1c98675bc (commit)
      from  4ed8f7bf56fc71cf0092ca354cf3fdcf5a8e8d77 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 5b62cd06ceeee053f2c7a4bf96138fc1c98675bc
Author: Daniel Baston <dbaston at gmail.com>
Date:   Fri Aug 7 14:01:13 2026 -0400

    CircularArcIntersector: Explicitly check for endpoint/control point equality (#1480)

diff --git a/src/algorithm/CircularArcIntersector.cpp b/src/algorithm/CircularArcIntersector.cpp
index 5f82d3230..79ab344b9 100644
--- a/src/algorithm/CircularArcIntersector.cpp
+++ b/src/algorithm/CircularArcIntersector.cpp
@@ -142,9 +142,10 @@ CircularArcIntersector::intersects(const CircularArc& arc, const CoordinateSeque
         return;
     }
 
-    // Check for exact endpoint-endpoint intersections
+    // Check for exact endpoint-endpoint or endpoint-control point intersections
     // If found, replace the computed intersection points with an exact endpoint
     const CoordinateXY& ap0 = arc.p0<CoordinateXY>();
+    const CoordinateXY& ap1 = arc.p1<CoordinateXY>();
     const CoordinateXY& ap2 = arc.p2<CoordinateXY>();
     const CoordinateXY& bp0 = seq.getAt<CoordinateXY>(segPos0);
     const CoordinateXY& bp1 = seq.getAt<CoordinateXY>(segPos1);
@@ -152,6 +153,9 @@ CircularArcIntersector::intersects(const CircularArc& arc, const CoordinateSeque
     if (ap0 == bp0 || ap0 == bp1) {
         closestPoint(isect0, isect1, nPointsIntersectingLine, ap0) = ap0;
     }
+    if (ap1 == bp0 || ap1 == bp1) {
+        closestPoint(isect0, isect1, nPointsIntersectingLine, ap1) = ap1;
+    }
     if (ap2 == bp0 || ap2 == bp1) {
         closestPoint(isect0, isect1, nPointsIntersectingLine, ap2) = ap2;
     }
@@ -251,14 +255,19 @@ CircularArcIntersector::intersects(const CircularArc& arc1, const CircularArc& a
 
         // Check to see if computed intersection points are inexact versions of an endpoint intersection
         const CoordinateXY& ap0 = arc1.p0();
+        const CoordinateXY& ap1 = arc1.p1();
         const CoordinateXY& ap2 = arc1.p2();
         const CoordinateXY& bp0 = arc2.p0();
+        const CoordinateXY& bp1 = arc2.p1();
         const CoordinateXY& bp2 = arc2.p2();
 
-        if (ap0 == bp0 || ap0 == bp2) {
+        if (ap0 == bp0 || ap0 == bp1 || ap0 == bp2) {
             closestPoint(isect0, isect1, 2, ap0) = ap0;
         }
-        if (ap2 == bp0 || ap2 == bp2) {
+        if (ap1 == bp0 || ap1 == bp1 || ap1 == bp2) {
+            closestPoint(isect0, isect1, 2, ap1) = ap1;
+        }
+        if (ap2 == bp0 || ap2 == bp1 || ap2 == bp2) {
             closestPoint(isect0, isect1, 2, ap2) = ap2;
         }
 
diff --git a/tests/xmltester/tests/general/TestOverlayCurvesAA.xml b/tests/xmltester/tests/general/TestOverlayCurvesAA.xml
index d53c49484..c9a1d43a8 100644
--- a/tests/xmltester/tests/general/TestOverlayCurvesAA.xml
+++ b/tests/xmltester/tests/general/TestOverlayCurvesAA.xml
@@ -160,7 +160,7 @@
     </b>
     <test>
       <op name="symdifference" arg1="A" arg2="B">
-        CURVEPOLYGON ((0 0, 0 230, 210 230, 210 0, 0 0), COMPOUNDCURVE ((70 120, 90 90), CIRCULARSTRING (90 90, 100 120, 70 120)), CIRCULARSTRING (60 90, 60 60, 90 60, 96.21320343559643 75, 90 90, 75 96.21320343559643, 60 90), CIRCULARSTRING (0 0, 40 20, 60 60, 20 40, 0 0), (90 90, 120 70, 120 80, 90 90))
+        CURVEPOLYGON ((0 0, 0 230, 210 230, 210 0, 0 0), COMPOUNDCURVE ((70 120, 90 90), CIRCULARSTRING (90 90, 100 120, 70 120)), CIRCULARSTRING (60 60, 75 53.78679656440357, 90 60, 96.21320343559643 75, 90 90, 75 96.21320343559643, 60 90, 53.78679656440357 75, 60 60), CIRCULARSTRING (0 0, 40 20, 60 60, 20 40, 0 0), (90 90, 120 70, 120 80, 90 90))
       </op>
     </test>
   </case>
@@ -174,13 +174,13 @@
     </b>
     <test>
       <op name="intersection" arg1="A" arg2="B">
-        MULTISURFACE (CURVEPOLYGON (CIRCULARSTRING (60 90, 90 90, 90 60, 60 60, 60 90)), CURVEPOLYGON (CIRCULARSTRING (0 0, 20 40, 60 60, 40 20, 0 0)))
+        MULTISURFACE (CURVEPOLYGON (CIRCULARSTRING (60 60, 53.78679656440357 75, 60 90, 90 90, 90 60, 75 53.78679656440357, 60 60)), CURVEPOLYGON (CIRCULARSTRING (0 0, 20 40, 60 60, 40 20, 0 0)))
       </op>
     </test>
 
     <test>
       <op name="symdifference" arg1="A" arg2="B">
-        CURVEPOLYGON ((0 0, 0 300, 340 300, 340 0, 0 0), CIRCULARSTRING (60 90, 60 60, 90 60, 90 90, 60 90), CIRCULARSTRING (0 0, 40 20, 60 60, 20 40, 0 0))
+        CURVEPOLYGON ((0 0, 0 300, 340 300, 340 0, 0 0), CIRCULARSTRING (60 60, 75 53.78679656440357, 90 60, 90 90, 60 90, 53.78679656440357 75, 60 60), CIRCULARSTRING (0 0, 40 20, 60 60, 20 40, 0 0))
       </op>
     </test>
   </case>
@@ -226,12 +226,29 @@
       CURVEPOLYGON (COMPOUNDCURVE((0 80, 0 240, 220 240, 220 80), CIRCULARSTRING(220 80, 110 100, 0 80)), COMPOUNDCURVE((110 100, 120 120), CIRCULARSTRING(120 120, 110 120, 110 100)))
     </b>
 
+    <test>
+      <op name="intersection" arg1="A" arg2="B">
+        CURVEPOLYGON (COMPOUNDCURVE ((20 86.75950277309494, 20 160, 200 160, 200 86.75950277309494), CIRCULARSTRING (200 86.75950277309494, 155.48436755308268 96.672156424695, 110 100, 64.5156324469173 96.672156424695, 20 86.75950277309494)), COMPOUNDCURVE ((110 100, 120 120), CIRCULARSTRING (120 120, 110 120, 110 100)))
+      </op>
+    </test>
+
     <test>
       <op name="union" arg1="A" arg2="B">
         CURVEPOLYGON (COMPOUNDCURVE ((0 80, 0 240, 220 240, 220 80), CIRCULARSTRING (220 80, 210.05709729666793 83.54869072597688, 200 86.75950277309494), (200 86.75950277309494, 200 0, 20 0), (20 0, 20 86.75950277309494), CIRCULARSTRING (20 86.75950277309494, 9.942902703332095 83.54869072597688, 0 80)))
       </op>
     </test>
 
+    <test>
+      <op name="difference" arg1="A" arg2="B">
+        MULTISURFACE (CURVEPOLYGON (COMPOUNDCURVE (CIRCULARSTRING (110 100, 110 120, 120 120), (120 120, 110 100))), CURVEPOLYGON (COMPOUNDCURVE ((20 0, 20 86.75950277309494), CIRCULARSTRING (20 86.75950277309494, 64.5156324469173 96.672156424695, 110 100, 155.48436755308268 96.672156424695, 200 86.75950277309494), (200 86.75950277309494, 200 0, 20 0))))
+      </op>
+    </test>
+
+    <test>
+      <op name="symdifference" arg1="A" arg2="B">
+        MULTISURFACE (CURVEPOLYGON (COMPOUNDCURVE (CIRCULARSTRING (110 100, 110 120, 120 120), (120 120, 110 100))), CURVEPOLYGON (COMPOUNDCURVE ((0 80, 0 240, 220 240, 220 80), CIRCULARSTRING (220 80, 210.05709729666793 83.54869072597688, 200 86.75950277309494), (200 86.75950277309494, 200 160, 20 160, 20 86.75950277309494), CIRCULARSTRING (20 86.75950277309494, 9.942902703332095 83.54869072597688, 0 80))), CURVEPOLYGON (COMPOUNDCURVE ((20 0, 20 86.75950277309494), CIRCULARSTRING (20 86.75950277309494, 64.5156324469173 96.672156424695, 110 100, 155.48436755308268 96.672156424695, 200 86.75950277309494), (200 86.75950277309494, 200 0, 20 0))))
+      </op>
+    </test>
   </case>
   <case>
     <desc>mAmA - complex polygons touching and overlapping</desc>

-----------------------------------------------------------------------

Summary of changes:
 src/algorithm/CircularArcIntersector.cpp           | 15 +++++++++++---
 .../tests/general/TestOverlayCurvesAA.xml          | 23 +++++++++++++++++++---
 2 files changed, 32 insertions(+), 6 deletions(-)


hooks/post-receive
-- 
GEOS


More information about the geos-commits mailing list