[geos-commits] [SCM] GEOS branch 3.8 updated. ee69f653aa879999cbd981b250124afb6852b7e8

git at osgeo.org git at osgeo.org
Tue Mar 24 11:22:39 PDT 2020


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, 3.8 has been updated
       via  ee69f653aa879999cbd981b250124afb6852b7e8 (commit)
      from  f60b72ee61db69a3db7fbbf74eb7cf3d466a6369 (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 ee69f653aa879999cbd981b250124afb6852b7e8
Author: Paul Ramsey <pramsey at cleverelephant.ca>
Date:   Tue Mar 24 10:30:37 2020 -0700

    Fix buffer fillet generation to avoid extra segments JTS-526, https://trac.osgeo.org/geos/ticket/743

diff --git a/include/geos/operation/buffer/OffsetSegmentGenerator.h b/include/geos/operation/buffer/OffsetSegmentGenerator.h
index f9974a6..6f461dd 100644
--- a/include/geos/operation/buffer/OffsetSegmentGenerator.h
+++ b/include/geos/operation/buffer/OffsetSegmentGenerator.h
@@ -329,7 +329,7 @@ private:
      * @param direction the orientation of the fillet
      * @param radius the radius of the fillet
      */
-    void addFillet(const geom::Coordinate& p, const geom::Coordinate& p0,
+    void addDirectedFillet(const geom::Coordinate& p, const geom::Coordinate& p0,
                    const geom::Coordinate& p1,
                    int direction, double radius);
 
@@ -342,7 +342,7 @@ private:
      * @param direction is -1 for a CW angle, 1 for a CCW angle
      * @param radius the radius of the fillet
      */
-    void addFillet(const geom::Coordinate& p, double startAngle,
+    void addDirectedFillet(const geom::Coordinate& p, double startAngle,
                    double endAngle, int direction, double radius);
 private:
     // An OffsetSegmentGenerator cannot be copied because of member "const BufferParameters& bufParams"
diff --git a/src/operation/buffer/OffsetSegmentGenerator.cpp b/src/operation/buffer/OffsetSegmentGenerator.cpp
index 9605ec1..cbb2cf2 100644
--- a/src/operation/buffer/OffsetSegmentGenerator.cpp
+++ b/src/operation/buffer/OffsetSegmentGenerator.cpp
@@ -207,7 +207,7 @@ OffsetSegmentGenerator::addLineEndCap(const Coordinate& p0, const Coordinate& p1
     case BufferParameters::CAP_ROUND:
         // add offset seg points with a fillet between them
         segList.addPt(offsetL.p1);
-        addFillet(p1, angle + PI / 2.0, angle - PI / 2.0,
+        addDirectedFillet(p1, angle + PI / 2.0, angle - PI / 2.0,
                   Orientation::CLOCKWISE, distance);
         segList.addPt(offsetR.p1);
         break;
@@ -237,7 +237,7 @@ OffsetSegmentGenerator::addLineEndCap(const Coordinate& p0, const Coordinate& p1
 
 /*private*/
 void
-OffsetSegmentGenerator::addFillet(const Coordinate& p, const Coordinate& p0,
+OffsetSegmentGenerator::addDirectedFillet(const Coordinate& p, const Coordinate& p0,
                                   const Coordinate& p1, int direction, double radius)
 {
     double dx0 = p0.x - p.x;
@@ -259,14 +259,14 @@ OffsetSegmentGenerator::addFillet(const Coordinate& p, const Coordinate& p0,
     }
 
     segList.addPt(p0);
-    addFillet(p, startAngle, endAngle, direction, radius);
+    addDirectedFillet(p, startAngle, endAngle, direction, radius);
     segList.addPt(p1);
 }
 
 /*private*/
 void
-OffsetSegmentGenerator::addFillet(const Coordinate& p, double startAngle,
-                                  double endAngle, int direction, double radius)
+OffsetSegmentGenerator::addDirectedFillet(const Coordinate& p, double startAngle,
+                                          double endAngle, int direction, double radius)
 {
     int directionFactor = direction == Orientation::CLOCKWISE ? -1 : 1;
 
@@ -274,28 +274,19 @@ OffsetSegmentGenerator::addFillet(const Coordinate& p, double startAngle,
     int nSegs = (int)(totalAngle / filletAngleQuantum + 0.5);
 
     // no segments because angle is less than increment-nothing to do!
-    if(nSegs < 1) {
-        return;
-    }
-
-    double initAngle, currAngleInc;
+    if(nSegs < 1) return;
 
-    // choose angle increment so that each segment has equal length
-    initAngle = 0.0;
-    currAngleInc = totalAngle / nSegs;
-
-    double currAngle = initAngle;
+    // double initAngle, currAngleInc;
+    double angleInc = totalAngle / nSegs;
     Coordinate pt;
-    while(currAngle < totalAngle) {
-        double angle = startAngle + directionFactor * currAngle;
+    for (int i = 0; i < nSegs; i++) {
+        double angle = startAngle + directionFactor * i * angleInc;
         pt.x = p.x + radius * cos(angle);
         pt.y = p.y + radius * sin(angle);
         segList.addPt(pt);
-        currAngle += currAngleInc;
     }
 }
 
-
 /*private*/
 void
 OffsetSegmentGenerator::createCircle(const Coordinate& p, double p_distance)
@@ -303,7 +294,7 @@ OffsetSegmentGenerator::createCircle(const Coordinate& p, double p_distance)
     // add start point
     Coordinate pt(p.x + p_distance, p.y);
     segList.addPt(pt);
-    addFillet(p, 0.0, 2.0 * PI, -1, p_distance);
+    addDirectedFillet(p, 0.0, 2.0 * PI, -1, p_distance);
     segList.closeRing();
 }
 
@@ -354,7 +345,7 @@ OffsetSegmentGenerator::addCollinear(bool addStartPoint)
             segList.addPt(offset1.p0);
         }
         else {
-            addFillet(s1, offset0.p1, offset1.p0,
+            addDirectedFillet(s1, offset0.p1, offset1.p0,
                       Orientation::CLOCKWISE, distance);
         }
     }
@@ -392,7 +383,7 @@ OffsetSegmentGenerator::addOutsideTurn(int orientation, bool addStartPoint)
         }
 
         // TESTING - comment out to produce beveled joins
-        addFillet(s1, offset0.p1, offset1.p0, orientation, distance);
+        addDirectedFillet(s1, offset0.p1, offset1.p0, orientation, distance);
         segList.addPt(offset1.p0);
     }
 }
diff --git a/tests/unit/operation/buffer/BufferOpTest.cpp b/tests/unit/operation/buffer/BufferOpTest.cpp
index d8599bf..cef4333 100644
--- a/tests/unit/operation/buffer/BufferOpTest.cpp
+++ b/tests/unit/operation/buffer/BufferOpTest.cpp
@@ -117,7 +117,7 @@ void object::test<3>
     ensure_not(gBuffer->isEmpty());
     ensure(gBuffer->isValid());
     ensure_equals(gBuffer->getGeometryTypeId(), geos::geom::GEOS_POLYGON);
-    ensure(gBuffer->getNumPoints() > std::size_t(129));
+    ensure(gBuffer->getNumPoints() >= std::size_t(129));
 }
 
 template<>
@@ -143,7 +143,7 @@ void object::test<4>
         ensure_not(gBuffer->isEmpty());
         ensure(gBuffer->isValid());
         ensure_equals(gBuffer->getGeometryTypeId(), geos::geom::GEOS_POLYGON);
-        ensure(gBuffer->getNumPoints() >= std::size_t(245));
+        ensure(gBuffer->getNumPoints() >= std::size_t(243));
     }
 
     // Buffer point with custom parameters: 32 quadrant segments
@@ -156,7 +156,7 @@ void object::test<4>
         ensure_not(gBuffer->isEmpty());
         ensure(gBuffer->isValid());
         ensure_equals(gBuffer->getGeometryTypeId(), geos::geom::GEOS_POLYGON);
-        ensure(gBuffer->getNumPoints() >= std::size_t(318));
+        ensure(gBuffer->getNumPoints() >= std::size_t(317));
     }
 }
 
@@ -367,5 +367,32 @@ MULTILINESTRING(  \
     ensure_equals(int(gBuffer->getArea()), 3520);
 }
 
+template<>
+template<>
+void object::test<12>
+()
+{
+    using geos::operation::buffer::BufferOp;
+    using geos::operation::buffer::BufferParameters;
+
+    std::string wkt0("POINT(100 100)");
+    GeomPtr g0(wktreader.read(wkt0));
+
+    // Buffer point with custom parameters: 32 quadrant segments
+    int const segments = 53;
+    int expected_segments = 4 * segments + 1;
+    BufferParameters params(segments);
+
+    BufferOp op(g0.get(), params);
+
+    double const distance = 80.0;
+    GeomPtr gBuffer(op.getResultGeometry(distance));
+
+    ensure_not(gBuffer->isEmpty());
+    ensure(gBuffer->isValid());
+    ensure_equals(gBuffer->getGeometryTypeId(), geos::geom::GEOS_POLYGON);
+    ensure(gBuffer->getNumPoints() >= std::size_t(expected_segments));
+}
+
 } // namespace tut
 

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

Summary of changes:
 .../geos/operation/buffer/OffsetSegmentGenerator.h |  4 +--
 src/operation/buffer/OffsetSegmentGenerator.cpp    | 35 ++++++++--------------
 tests/unit/operation/buffer/BufferOpTest.cpp       | 33 ++++++++++++++++++--
 3 files changed, 45 insertions(+), 27 deletions(-)


hooks/post-receive
-- 
GEOS


More information about the geos-commits mailing list