locationtech / jts

The JTS Topology Suite is a Java library for creating and manipulating vector geometry.
Other
1.9k stars 437 forks source link

PolygonTriangulator fails to find a convex corner on provided valid geometry #1025

Closed andy98725 closed 4 months ago

andy98725 commented 7 months ago

Running this to create & triangulate the polygon incurs this error:

Exception in thread "main" java.lang.IllegalStateException: Unable to find a convex corner
        at org.locationtech.jts.triangulate.polygon.PolygonEarClipper.compute(PolygonEarClipper.java:169)
        at org.locationtech.jts.triangulate.polygon.PolygonEarClipper.triangulate(PolygonEarClipper.java:61)
        at org.locationtech.jts.triangulate.polygon.PolygonTriangulator.triangulatePolygon(PolygonTriangulator.java:114)
        at org.locationtech.jts.triangulate.polygon.PolygonTriangulator.compute(PolygonTriangulator.java:95)
        at org.locationtech.jts.triangulate.polygon.PolygonTriangulator.getTriangles(PolygonTriangulator.java:85)
        at com.ExamplePolygon.main(TestArea.java:85)
GeometryFactory gf = new GeometryFactory();

        LinearRing hull = gf.createLinearRing(new Coordinate[] {
                new Coordinate(128, 0),
                new Coordinate(0, 128),
                new Coordinate(0, 256),
                new Coordinate(0, 347.9795837402344),
                new Coordinate(0, 512),
                new Coordinate(0, 640),
                new Coordinate(128, 768),
                new Coordinate(431.6631774902344, 768),
                new Coordinate(433.6377258300781, 758.0259399414062),
                new Coordinate(450.2085876464844, 745.888427734375),
                new Coordinate(477.412353515625, 720.3101196289062),
                new Coordinate(501.31097412109375, 691.5857543945312),
                new Coordinate(521.5836791992188, 660.0360717773438),
                new Coordinate(537.90966796875, 625.98193359375),
                new Coordinate(549.96826171875, 589.7440185546875),
                new Coordinate(557.4385986328125, 551.6431274414062),
                new Coordinate(560, 512),
                new Coordinate(384, 512),
                new Coordinate(256, 384),
                new Coordinate(384, 256),
                new Coordinate(560, 256),
                new Coordinate(557.4385986328125, 216.35687255859375),
                new Coordinate(549.96826171875, 178.25596618652344),
                new Coordinate(537.90966796875, 142.01806640625),
                new Coordinate(521.5836791992188, 107.96390533447266),
                new Coordinate(501.31097412109375, 76.41426086425781),
                new Coordinate(477.412353515625, 47.689884185791016),
                new Coordinate(450.2085876464844, 22.11154556274414),
                new Coordinate(433.6377258300781, 9.974088668823242),
                new Coordinate(431.6631774902344, 0),
                new Coordinate(128, 0),
        });

        LinearRing[] holes = new LinearRing[] {
                gf.createLinearRing(new Coordinate[] {
                        new Coordinate(348.9517517089844, 697.9035034179688),
                        new Coordinate(352, 704),
                        new Coordinate(339.97442626953125, 704),
                        new Coordinate(348.9517517089844, 697.9035034179688),
                }),
                gf.createLinearRing(new Coordinate[] {
                        new Coordinate(352, 64),
                        new Coordinate(348.9517517089844, 70.09649658203125),
                        new Coordinate(339.97442626953125, 64),
                        new Coordinate(352, 64),
                }),
        };

        Geometry shape = gf.createPolygon(hull, holes);
        assert (shape.isValid());
        new PolygonTriangulator(shape).getTriangles();
dr-jts commented 7 months ago

The polygon is:

POLYGON ((128 0, 0 128, 0 256, 0 347.9795837402344, 0 512, 0 640, 128 768, 431.6631774902344 768, 433.6377258300781 758.0259399414062, 450.2085876464844 745.888427734375, 477.412353515625 720.3101196289062, 501.31097412109375 691.5857543945312, 521.5836791992188 660.0360717773438, 537.90966796875 625.98193359375, 549.96826171875 589.7440185546875, 557.4385986328125 551.6431274414062, 560 512, 384 512, 256 384, 384 256, 560 256, 557.4385986328125 216.35687255859375, 549.96826171875 178.25596618652344, 537.90966796875 142.01806640625, 521.5836791992188 107.96390533447266, 501.31097412109375 76.41426086425781, 477.412353515625 47.689884185791016, 450.2085876464844 22.11154556274414, 433.6377258300781 9.974088668823242, 431.6631774902344 0, 128 0), (348.9517517089844 697.9035034179688, 352 704, 339.97442626953125 704, 348.9517517089844 697.9035034179688), (352 64, 348.9517517089844 70.09649658203125, 339.97442626953125 64, 352 64))

The output from PolygonTriangulator in master looks fine to me:

image

There have been some fixes to the code since it was first released.

andy98725 commented 7 months ago

That works! Unfortunately, the latest 1.19.0 release still has these problems- is another patch/release planned soon, or do I need to include this locally in my project to use it?

dr-jts commented 4 months ago

That works! Unfortunately, the latest 1.19.0 release still has these problems- is another patch/release planned soon, or do I need to include this locally in my project to use it?

Yes, hoping to get a 1.20 release out soonish.

andy98725 commented 4 months ago

Sounds good! Closing this now as the bug was already resolved in the codebase. This will no longer be a problem once it releases.

Until then, I'll just clone and use it as a local dependency.