From 751a7504a2acb39b570b9cfacc4d2a402c1b5a19 Mon Sep 17 00:00:00 2001 From: Mike Barry Date: Mon, 30 May 2022 06:49:23 -0400 Subject: [PATCH] fix is convex negated --- .../onthegomap/planetiler/geo/GeoUtils.java | 11 ++++- .../planetiler/geo/GeoUtilsTest.java | 45 ++++++++++--------- 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/geo/GeoUtils.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/geo/GeoUtils.java index aaeafb02b6..accfeed1f3 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/geo/GeoUtils.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/geo/GeoUtils.java @@ -403,11 +403,20 @@ public static Polygon createPolygon(LinearRing exteriorRing, List ri return JTS_FACTORY.createPolygon(exteriorRing, rings.toArray(LinearRing[]::new)); } + /** - * Returns {@code true} if the signed area of the triangle formed by 3 sequential points changes sign anywhere along + * Returns {@code false} if the signed area of the triangle formed by 3 sequential points changes sign anywhere along * {@code ring}, ignoring repeated and collinear points. */ public static boolean isConvex(LinearRing ring) { + return !isConcave(ring); + } + + /** + * Returns {@code true} if the signed area of the triangle formed by 3 sequential points changes sign anywhere along + * {@code ring}, ignoring repeated and collinear points. + */ + public static boolean isConcave(LinearRing ring) { CoordinateSequence seq = ring.getCoordinateSequence(); if (seq.size() <= 3) { return false; diff --git a/planetiler-core/src/test/java/com/onthegomap/planetiler/geo/GeoUtilsTest.java b/planetiler-core/src/test/java/com/onthegomap/planetiler/geo/GeoUtilsTest.java index 84e46d72f6..583944c721 100644 --- a/planetiler-core/src/test/java/com/onthegomap/planetiler/geo/GeoUtilsTest.java +++ b/planetiler-core/src/test/java/com/onthegomap/planetiler/geo/GeoUtilsTest.java @@ -117,7 +117,7 @@ void testMetersPerPixel(int zoom, double meters) { @Test void testIsConvexTriangle() { - assertConvex(true, newLinearRing( + assertConcave(true, newLinearRing( 0, 0, 1, 0, 0, 1, @@ -127,7 +127,7 @@ void testIsConvexTriangle() { @Test void testIsConvexRectangle() { - assertConvex(true, newLinearRing( + assertConcave(true, newLinearRing( 0, 0, 1, 0, 1, 1, @@ -138,21 +138,21 @@ void testIsConvexRectangle() { @Test void testBarelyConvexRectangle() { - assertConvex(true, newLinearRing( + assertConcave(true, newLinearRing( 0, 0, 1, 0, 1, 1, 0.5, 0.5, 0, 0 )); - assertConvex(true, newLinearRing( + assertConcave(true, newLinearRing( 0, 0, 1, 0, 1, 1, 0.4, 0.4, 0, 0 )); - assertConvex(true, newLinearRing( + assertConcave(true, newLinearRing( 0, 0, 1, 0, 1, 1, @@ -163,7 +163,7 @@ void testBarelyConvexRectangle() { @Test void testConcaveRectangleDoublePoints() { - assertConvex(true, newLinearRing( + assertConcave(true, newLinearRing( 0, 0, 0, 0, 1, 0, @@ -171,7 +171,7 @@ void testConcaveRectangleDoublePoints() { 0, 1, 0, 0 )); - assertConvex(true, newLinearRing( + assertConcave(true, newLinearRing( 0, 0, 1, 0, 1, 0, @@ -179,7 +179,7 @@ void testConcaveRectangleDoublePoints() { 0, 1, 0, 0 )); - assertConvex(true, newLinearRing( + assertConcave(true, newLinearRing( 0, 0, 1, 0, 1, 1, @@ -187,7 +187,7 @@ void testConcaveRectangleDoublePoints() { 0, 1, 0, 0 )); - assertConvex(true, newLinearRing( + assertConcave(true, newLinearRing( 0, 0, 1, 0, 1, 1, @@ -195,7 +195,7 @@ void testConcaveRectangleDoublePoints() { 0, 1, 0, 0 )); - assertConvex(true, newLinearRing( + assertConcave(true, newLinearRing( 0, 0, 1, 0, 1, 1, @@ -207,7 +207,7 @@ void testConcaveRectangleDoublePoints() { @Test void testBarelyConcaveRectangle() { - assertConvex(false, newLinearRing( + assertConcave(false, newLinearRing( 0, 0, 1, 0, 1, 1, @@ -218,7 +218,7 @@ void testBarelyConcaveRectangle() { @Test void test5PointsConcave() { - assertConvex(false, newLinearRing( + assertConcave(false, newLinearRing( 0, 0, 0.5, 0.1, 1, 0, @@ -226,7 +226,7 @@ void test5PointsConcave() { 0, 1, 0, 0 )); - assertConvex(false, newLinearRing( + assertConcave(false, newLinearRing( 0, 0, 1, 0, 0.9, 0.5, @@ -234,7 +234,7 @@ void test5PointsConcave() { 0, 1, 0, 0 )); - assertConvex(false, newLinearRing( + assertConcave(false, newLinearRing( 0, 0, 1, 0, 1, 1, @@ -242,7 +242,7 @@ void test5PointsConcave() { 0, 1, 0, 0 )); - assertConvex(false, newLinearRing( + assertConcave(false, newLinearRing( 0, 0, 1, 0, 1, 1, @@ -254,7 +254,7 @@ void test5PointsConcave() { @Test void test5PointsColinear() { - assertConvex(true, newLinearRing( + assertConcave(true, newLinearRing( 0, 0, 0.5, 0, 1, 0, @@ -262,7 +262,7 @@ void test5PointsColinear() { 0, 1, 0, 0 )); - assertConvex(true, newLinearRing( + assertConcave(true, newLinearRing( 0, 0, 1, 0, 1, 0.5, @@ -270,7 +270,7 @@ void test5PointsColinear() { 0, 1, 0, 0 )); - assertConvex(true, newLinearRing( + assertConcave(true, newLinearRing( 0, 0, 1, 0, 1, 1, @@ -278,7 +278,7 @@ void test5PointsColinear() { 0, 1, 0, 0 )); - assertConvex(true, newLinearRing( + assertConcave(true, newLinearRing( 0, 0, 1, 0, 1, 1, @@ -288,14 +288,17 @@ void test5PointsColinear() { )); } - private static void assertConvex(boolean isConvex, LinearRing ring) { + private static void assertConcave(boolean isConcave, LinearRing ring) { for (double rotation : new double[]{0, 90, 180, 270}) { LinearRing rotated = (LinearRing) AffineTransformation.rotationInstance(Math.toRadians(rotation)).transform(ring); for (boolean flip : new boolean[]{false, true}) { LinearRing flipped = flip ? (LinearRing) AffineTransformation.scaleInstance(-1, 1).transform(rotated) : rotated; for (boolean reverse : new boolean[]{false, true}) { LinearRing reversed = reverse ? flipped.reverse() : flipped; - assertEquals(isConvex, isConvex(reversed), "rotation=" + rotation + " flip=" + flip + " reverse=" + reverse); + assertEquals(isConcave, isConcave(reversed), + "rotation=" + rotation + " flip=" + flip + " reverse=" + reverse); + assertEquals(!isConcave, isConvex(reversed), + "rotation=" + rotation + " flip=" + flip + " reverse=" + reverse); } } }