diff --git a/CHANGELOG.md b/CHANGELOG.md index 2747989f..701cb8a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed * Fixed invalid results given by `PGS_Morphology.rounding()`. +* `PGS_ShapePredicates.elongation()` now correctly measures shape elongation (previously inverted, now returns 1 for highly elongated shapes). ### Removed diff --git a/src/main/java/micycle/pgs/PGS_ShapePredicates.java b/src/main/java/micycle/pgs/PGS_ShapePredicates.java index 21186de8..091c6b6e 100644 --- a/src/main/java/micycle/pgs/PGS_ShapePredicates.java +++ b/src/main/java/micycle/pgs/PGS_ShapePredicates.java @@ -415,11 +415,14 @@ public static double sphericity(final PShape shape) { } /** - * Measures the elongation of a shape; the ratio of a shape's bounding box - * length to its width. + * Measures the elongation of a shape as the ratio of the difference between the + * bounding box's length and width to the maximum dimension. A value of 1 + * indicates a highly elongated shape, while a value of 0 indicates a square or + * nearly square shape. * * @param shape - * @return a value in [0, 1] + * @return a value in the range [0, 1], where 1 represents high elongation and 0 + * represents no elongation */ public static double elongation(final PShape shape) { Geometry obb = MinimumDiameter.getMinimumRectangle(fromPShape(shape)); @@ -429,11 +432,9 @@ public static double elongation(final PShape shape) { Coordinate c2 = rect.getCoordinates()[2]; double l = c0.distance(c1); double w = c1.distance(c2); - if (l >= w) { - return w / l; - } else { - return l / w; - } + double max = Math.max(l, w); + double min = Math.min(l, w); + return 1 - (min / max); } /** diff --git a/src/test/java/micycle/pgs/PGS_ShapePredicatesTests.java b/src/test/java/micycle/pgs/PGS_ShapePredicatesTests.java index 1278f37a..b4fc5713 100644 --- a/src/test/java/micycle/pgs/PGS_ShapePredicatesTests.java +++ b/src/test/java/micycle/pgs/PGS_ShapePredicatesTests.java @@ -18,7 +18,7 @@ class PGS_ShapePredicatesTests { private static final double EPSILON = 1E-4; - static PShape square, triangle; + static PShape square, triangle, rect; @BeforeAll static void initShapes() { @@ -29,6 +29,14 @@ static void initShapes() { square.vertex(10, 10); square.vertex(0, 10); square.endShape(PConstants.CLOSE); // close affects rendering only -- does not append another vertex + + rect = new PShape(PShape.GEOMETRY); // 10x10 rect + rect.beginShape(); + rect.vertex(0, 0); + rect.vertex(10, 0); + rect.vertex(10, 20); + rect.vertex(0, 20); + rect.endShape(PConstants.CLOSE); // close affects rendering only -- does not append another vertex float[] centroid = new float[] { 0, 0 }; float side_length = 10; @@ -87,5 +95,11 @@ void testIsClockwise() { assertFalse(PGS_ShapePredicates.isClockwise(PGS_Conversion.fromPVector(ccw))); } + + @Test + void testElongation() { + assertEquals(0, PGS_ShapePredicates.elongation(square)); + assertEquals(0.5, PGS_ShapePredicates.elongation(rect)); + } }