From aa755818e9299da4403c9fe4bcb7e998d79dca21 Mon Sep 17 00:00:00 2001 From: Martin Davis Date: Wed, 22 Jan 2025 17:16:18 -0800 Subject: [PATCH] Change to use MathUtil.hypot (#1112) --- .../jtstest/testbuilder/ui/style/AWTUtil.java | 4 +++- .../testbuilder/ui/style/ArrowSegmentStyle.java | 7 ++++--- .../testbuilder/ui/style/DataLabelStyle.java | 3 ++- .../locationtech/jts/algorithm/CGAlgorithms.java | 2 +- .../org/locationtech/jts/algorithm/Length.java | 3 ++- .../jts/algorithm/LineIntersector.java | 3 ++- .../jts/algorithm/MinimumBoundingCircle.java | 3 ++- .../org/locationtech/jts/geom/Coordinate.java | 3 ++- .../java/org/locationtech/jts/geom/Envelope.java | 6 ++++-- .../org/locationtech/jts/geom/LineSegment.java | 3 ++- .../jts/geom/util/AffineTransformation.java | 7 ++++--- .../jts/index/strtree/EnvelopeDistance.java | 3 ++- .../java/org/locationtech/jts/math/MathUtil.java | 15 +++++++++++++++ .../java/org/locationtech/jts/math/Vector2D.java | 4 ++-- .../operation/buffer/OffsetSegmentGenerator.java | 3 ++- .../overlay/validate/OffsetPointGenerator.java | 3 ++- .../jts/triangulate/quadedge/Vertex.java | 3 ++- .../org/locationtech/jtslab/edgeray/EdgeRay.java | 5 +++-- 18 files changed, 56 insertions(+), 24 deletions(-) diff --git a/modules/app/src/main/java/org/locationtech/jtstest/testbuilder/ui/style/AWTUtil.java b/modules/app/src/main/java/org/locationtech/jtstest/testbuilder/ui/style/AWTUtil.java index 7d7b8d38b5..50eddc65bb 100644 --- a/modules/app/src/main/java/org/locationtech/jtstest/testbuilder/ui/style/AWTUtil.java +++ b/modules/app/src/main/java/org/locationtech/jtstest/testbuilder/ui/style/AWTUtil.java @@ -17,6 +17,8 @@ import java.awt.Stroke; import java.awt.geom.Point2D; +import org.locationtech.jts.math.MathUtil; + public class AWTUtil { @@ -35,7 +37,7 @@ public static Point2D multiply(Point2D v, double x) { public static Point2D vector(Point2D a, Point2D b, double size) { double dx = b.getX() - a.getX(); double dy = b.getY() - a.getY(); - double len = Math.hypot(dx, dy); + double len = MathUtil.hypot(dx, dy); return new Point2D.Double(size * dx/len, size * dy/len); } diff --git a/modules/app/src/main/java/org/locationtech/jtstest/testbuilder/ui/style/ArrowSegmentStyle.java b/modules/app/src/main/java/org/locationtech/jtstest/testbuilder/ui/style/ArrowSegmentStyle.java index 6838b0579b..94813f476c 100644 --- a/modules/app/src/main/java/org/locationtech/jtstest/testbuilder/ui/style/ArrowSegmentStyle.java +++ b/modules/app/src/main/java/org/locationtech/jtstest/testbuilder/ui/style/ArrowSegmentStyle.java @@ -20,6 +20,7 @@ import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.Point2D; +import org.locationtech.jts.math.MathUtil; import org.locationtech.jtstest.testbuilder.ui.Viewport; @@ -101,7 +102,7 @@ private static GeneralPath arrowHalfOffset(Point2D p0, Point2D p1) { double dx = p1.getX() - p0.getX(); double dy = p1.getY() - p0.getY(); - double len = Math.hypot(dx, dy); + double len = MathUtil.hypot(dx, dy); double vy = dy / len; double vx = dx / len; @@ -162,7 +163,7 @@ private static GeneralPath arrowHeadHalf(Point2D origin, Point2D p1, double dx = p1.getX() - origin.getX(); double dy = p1.getY() - origin.getY(); - double vlen = Math.hypot(dx, dy); + double vlen = MathUtil.hypot(dx, dy); if (vlen <= 0) return null; @@ -206,7 +207,7 @@ private static boolean isTooSmallToRender(Point2D p0, Point2D p1, double minLen) double dx = p1.getX() - p0.getX(); double dy = p1.getY() - p0.getY(); - double len = Math.hypot(dx, dy); + double len = MathUtil.hypot(dx, dy); return len < minLen; } diff --git a/modules/app/src/main/java/org/locationtech/jtstest/testbuilder/ui/style/DataLabelStyle.java b/modules/app/src/main/java/org/locationtech/jtstest/testbuilder/ui/style/DataLabelStyle.java index 38c8eb8978..9077f67912 100644 --- a/modules/app/src/main/java/org/locationtech/jtstest/testbuilder/ui/style/DataLabelStyle.java +++ b/modules/app/src/main/java/org/locationtech/jtstest/testbuilder/ui/style/DataLabelStyle.java @@ -23,6 +23,7 @@ import org.locationtech.jts.geom.LineSegment; import org.locationtech.jts.geom.LineString; import org.locationtech.jts.geom.Polygon; +import org.locationtech.jts.math.MathUtil; import org.locationtech.jtstest.testbuilder.geom.ConstrainedInteriorPoint; import org.locationtech.jtstest.testbuilder.ui.GraphicsUtil; import org.locationtech.jtstest.testbuilder.ui.Viewport; @@ -103,7 +104,7 @@ private void paintLabelLine(String label, Geometry line, Viewport viewport, Grap double offsetLen = 15; double nudgeX = 5; - double dirVecLen = Math.hypot(dx, dy); + double dirVecLen = MathUtil.hypot(dx, dy); double offsetX = offsetLen * dx / dirVecLen; double offsetY = offsetLen * dy / dirVecLen; diff --git a/modules/core/src/main/java/org/locationtech/jts/algorithm/CGAlgorithms.java b/modules/core/src/main/java/org/locationtech/jts/algorithm/CGAlgorithms.java index dad9032d41..0311b21e09 100644 --- a/modules/core/src/main/java/org/locationtech/jts/algorithm/CGAlgorithms.java +++ b/modules/core/src/main/java/org/locationtech/jts/algorithm/CGAlgorithms.java @@ -605,7 +605,7 @@ public static double length(CoordinateSequence pts) double dx = x1 - x0; double dy = y1 - y0; - len += Math.hypot(dx, dy); + len += MathUtil.hypot(dx, dy); x0 = x1; y0 = y1; diff --git a/modules/core/src/main/java/org/locationtech/jts/algorithm/Length.java b/modules/core/src/main/java/org/locationtech/jts/algorithm/Length.java index a69b52239e..60834051be 100644 --- a/modules/core/src/main/java/org/locationtech/jts/algorithm/Length.java +++ b/modules/core/src/main/java/org/locationtech/jts/algorithm/Length.java @@ -13,6 +13,7 @@ import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.CoordinateSequence; +import org.locationtech.jts.math.MathUtil; /** * Functions for computing length. @@ -49,7 +50,7 @@ public static double ofLine(CoordinateSequence pts) double dx = x1 - x0; double dy = y1 - y0; - len += Math.hypot(dx, dy); + len += MathUtil.hypot(dx, dy); x0 = x1; y0 = y1; diff --git a/modules/core/src/main/java/org/locationtech/jts/algorithm/LineIntersector.java b/modules/core/src/main/java/org/locationtech/jts/algorithm/LineIntersector.java index 4ec1190d5e..a0fb7a8525 100644 --- a/modules/core/src/main/java/org/locationtech/jts/algorithm/LineIntersector.java +++ b/modules/core/src/main/java/org/locationtech/jts/algorithm/LineIntersector.java @@ -17,6 +17,7 @@ import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.PrecisionModel; import org.locationtech.jts.io.WKTWriter; +import org.locationtech.jts.math.MathUtil; import org.locationtech.jts.util.Assert; /** @@ -131,7 +132,7 @@ public static double nonRobustComputeEdgeDistance( { double dx = p.x - p1.x; double dy = p.y - p1.y; - double dist = Math.hypot(dx, dy); // dummy value + double dist = MathUtil.hypot(dx, dy); // dummy value Assert.isTrue(! (dist == 0.0 && ! p.equals(p1)), "Invalid distance calculation"); return dist; } diff --git a/modules/core/src/main/java/org/locationtech/jts/algorithm/MinimumBoundingCircle.java b/modules/core/src/main/java/org/locationtech/jts/algorithm/MinimumBoundingCircle.java index 4c6101eda2..5e489c85ec 100644 --- a/modules/core/src/main/java/org/locationtech/jts/algorithm/MinimumBoundingCircle.java +++ b/modules/core/src/main/java/org/locationtech/jts/algorithm/MinimumBoundingCircle.java @@ -17,6 +17,7 @@ import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.Point; import org.locationtech.jts.geom.Triangle; +import org.locationtech.jts.math.MathUtil; import org.locationtech.jts.util.Assert; /** @@ -367,7 +368,7 @@ private static Coordinate pointWitMinAngleWithX(Coordinate[] pts, Coordinate P) double dx = p.x - P.x; double dy = p.y - P.y; if (dy < 0) dy = -dy; - double len = Math.hypot(dx, dy); + double len = MathUtil.hypot(dx, dy); double sin = dy / len; if (sin < minSin) { diff --git a/modules/core/src/main/java/org/locationtech/jts/geom/Coordinate.java b/modules/core/src/main/java/org/locationtech/jts/geom/Coordinate.java index fbdda635a0..cecd823918 100644 --- a/modules/core/src/main/java/org/locationtech/jts/geom/Coordinate.java +++ b/modules/core/src/main/java/org/locationtech/jts/geom/Coordinate.java @@ -14,6 +14,7 @@ import java.io.Serializable; import java.util.Comparator; +import org.locationtech.jts.math.MathUtil; import org.locationtech.jts.util.Assert; import org.locationtech.jts.util.NumberUtil; @@ -435,7 +436,7 @@ public Coordinate create() { public double distance(Coordinate c) { double dx = x - c.x; double dy = y - c.y; - return Math.hypot(dx, dy); + return MathUtil.hypot(dx, dy); } /** diff --git a/modules/core/src/main/java/org/locationtech/jts/geom/Envelope.java b/modules/core/src/main/java/org/locationtech/jts/geom/Envelope.java index a784bcfe14..0af880418f 100644 --- a/modules/core/src/main/java/org/locationtech/jts/geom/Envelope.java +++ b/modules/core/src/main/java/org/locationtech/jts/geom/Envelope.java @@ -13,6 +13,8 @@ import java.io.Serializable; +import org.locationtech.jts.math.MathUtil; + /** * Defines a rectangular region of the 2D coordinate plane. * It is often used to represent the bounding box of a {@link Geometry}, @@ -303,7 +305,7 @@ public double getDiameter() { } double w = getWidth(); double h = getHeight(); - return Math.hypot(w, h); + return MathUtil.hypot(w, h); } /** * Returns the Envelopes minimum x-value. min x > max x @@ -780,7 +782,7 @@ else if (minx > env.maxx) // if either is zero, the envelopes overlap either vertically or horizontally if (dx == 0.0) return dy; if (dy == 0.0) return dx; - return Math.hypot(dx, dy); + return MathUtil.hypot(dx, dy); } public boolean equals(Object other) { diff --git a/modules/core/src/main/java/org/locationtech/jts/geom/LineSegment.java b/modules/core/src/main/java/org/locationtech/jts/geom/LineSegment.java index 9dd72a6d1f..cd7f497fe6 100644 --- a/modules/core/src/main/java/org/locationtech/jts/geom/LineSegment.java +++ b/modules/core/src/main/java/org/locationtech/jts/geom/LineSegment.java @@ -19,6 +19,7 @@ import org.locationtech.jts.algorithm.Orientation; import org.locationtech.jts.algorithm.RobustLineIntersector; import org.locationtech.jts.io.WKTConstants; +import org.locationtech.jts.math.MathUtil; /** @@ -337,7 +338,7 @@ public Coordinate pointAlongOffset(double segmentLengthFraction, double offsetDi double dx = p1.x - p0.x; double dy = p1.y - p0.y; - double len = Math.hypot(dx, dy); + double len = MathUtil.hypot(dx, dy); double ux = 0.0; double uy = 0.0; if (offsetDistance != 0.0) { diff --git a/modules/core/src/main/java/org/locationtech/jts/geom/util/AffineTransformation.java b/modules/core/src/main/java/org/locationtech/jts/geom/util/AffineTransformation.java index a8ed63ac25..ef3814678d 100644 --- a/modules/core/src/main/java/org/locationtech/jts/geom/util/AffineTransformation.java +++ b/modules/core/src/main/java/org/locationtech/jts/geom/util/AffineTransformation.java @@ -16,6 +16,7 @@ import org.locationtech.jts.geom.CoordinateSequence; import org.locationtech.jts.geom.CoordinateSequenceFilter; import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.math.MathUtil; import org.locationtech.jts.util.Assert; /** * Represents an affine transformation on the 2D Cartesian plane. @@ -494,7 +495,7 @@ public AffineTransformation setToReflectionBasic(double x0, double y0, double x1 } double dx = x1 - x0; double dy = y1 - y0; - double d = Math.hypot(dx, dy); + double d = MathUtil.hypot(dx, dy); double sin = dy / d; double cos = dx / d; double cs2 = 2 * sin * cos; @@ -525,7 +526,7 @@ public AffineTransformation setToReflection(double x0, double y0, double x1, dou // rotate vector to positive x axis direction double dx = x1 - x0; double dy = y1 - y0; - double d = Math.hypot(dx, dy); + double d = MathUtil.hypot(dx, dy); double sin = dy / d; double cos = dx / d; rotate(-sin, cos); @@ -576,7 +577,7 @@ public AffineTransformation setToReflection(double x, double y) } // rotate vector to positive x axis direction - double d = Math.hypot(x, y); + double d = MathUtil.hypot(x, y); double sin = y / d; double cos = x / d; rotate(-sin, cos); diff --git a/modules/core/src/main/java/org/locationtech/jts/index/strtree/EnvelopeDistance.java b/modules/core/src/main/java/org/locationtech/jts/index/strtree/EnvelopeDistance.java index cfe770b1ee..2162a75723 100644 --- a/modules/core/src/main/java/org/locationtech/jts/index/strtree/EnvelopeDistance.java +++ b/modules/core/src/main/java/org/locationtech/jts/index/strtree/EnvelopeDistance.java @@ -12,6 +12,7 @@ package org.locationtech.jts.index.strtree; import org.locationtech.jts.geom.Envelope; +import org.locationtech.jts.math.MathUtil; /** * Functions for computing distances between {@link Envelope}s. @@ -44,7 +45,7 @@ public static double maximumDistance(Envelope env1, Envelope env2) private static double distance(double x1, double y1, double x2, double y2) { double dx = x2 - x1; double dy = y2 - y1; - return Math.hypot(dx, dy); + return MathUtil.hypot(dx, dy); } /** diff --git a/modules/core/src/main/java/org/locationtech/jts/math/MathUtil.java b/modules/core/src/main/java/org/locationtech/jts/math/MathUtil.java index 78b3578ecd..da689bfd19 100644 --- a/modules/core/src/main/java/org/locationtech/jts/math/MathUtil.java +++ b/modules/core/src/main/java/org/locationtech/jts/math/MathUtil.java @@ -74,6 +74,21 @@ public static int ceil(int num, int denom) { return div * denom >= num ? div : div + 1; } + /** + * Computes the length of the vector (x,y). + * This is the length of the hypotenuse of + * a right triangle with sides of length x and y. + * + * This function is faster than the standard {@link Math.hypot} function. + * + * @param x the x ordinate + * @param y the y ordinate + * @return the length of vector (x,y) + */ + public static double hypot(double x, double y) { + return Math.sqrt(x * x + y * y); + } + private static final double LOG_10 = Math.log(10); /** diff --git a/modules/core/src/main/java/org/locationtech/jts/math/Vector2D.java b/modules/core/src/main/java/org/locationtech/jts/math/Vector2D.java index 9c8bc944d6..6ba5dc205e 100644 --- a/modules/core/src/main/java/org/locationtech/jts/math/Vector2D.java +++ b/modules/core/src/main/java/org/locationtech/jts/math/Vector2D.java @@ -148,7 +148,7 @@ public Vector2D negate() { } public double length() { - return Math.hypot(x, y); + return MathUtil.hypot(x, y); } public double lengthSquared() { @@ -196,7 +196,7 @@ public double distance(Vector2D v) { double delx = v.x - x; double dely = v.y - y; - return Math.hypot(delx, dely); + return MathUtil.hypot(delx, dely); } /** diff --git a/modules/core/src/main/java/org/locationtech/jts/operation/buffer/OffsetSegmentGenerator.java b/modules/core/src/main/java/org/locationtech/jts/operation/buffer/OffsetSegmentGenerator.java index 15d6369dff..c9c79b3d76 100644 --- a/modules/core/src/main/java/org/locationtech/jts/operation/buffer/OffsetSegmentGenerator.java +++ b/modules/core/src/main/java/org/locationtech/jts/operation/buffer/OffsetSegmentGenerator.java @@ -21,6 +21,7 @@ import org.locationtech.jts.geom.LineSegment; import org.locationtech.jts.geom.Position; import org.locationtech.jts.geom.PrecisionModel; +import org.locationtech.jts.math.MathUtil; /** * Generates segments which form an offset curve. @@ -398,7 +399,7 @@ static void computeOffsetSegment(LineSegment seg, int side, double distance, Lin int sideSign = side == Position.LEFT ? 1 : -1; double dx = seg.p1.x - seg.p0.x; double dy = seg.p1.y - seg.p0.y; - double len = Math.hypot(dx, dy); + double len = MathUtil.hypot(dx, dy); // u is the vector that is the length of the offset, in the direction of the segment double ux = sideSign * distance * dx / len; double uy = sideSign * distance * dy / len; diff --git a/modules/core/src/main/java/org/locationtech/jts/operation/overlay/validate/OffsetPointGenerator.java b/modules/core/src/main/java/org/locationtech/jts/operation/overlay/validate/OffsetPointGenerator.java index eccc4049e7..98b81b9192 100644 --- a/modules/core/src/main/java/org/locationtech/jts/operation/overlay/validate/OffsetPointGenerator.java +++ b/modules/core/src/main/java/org/locationtech/jts/operation/overlay/validate/OffsetPointGenerator.java @@ -20,6 +20,7 @@ import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.LineString; import org.locationtech.jts.geom.util.LinearComponentExtracter; +import org.locationtech.jts.math.MathUtil; /** * Generates points offset by a given distance @@ -95,7 +96,7 @@ private void computeOffsetPoints(Coordinate p0, Coordinate p1, double offsetDist { double dx = p1.x - p0.x; double dy = p1.y - p0.y; - double len = Math.hypot(dx, dy); + double len = MathUtil.hypot(dx, dy); // u is the vector that is the length of the offset, in the direction of the segment double ux = offsetDistance * dx / len; double uy = offsetDistance * dy / len; diff --git a/modules/core/src/main/java/org/locationtech/jts/triangulate/quadedge/Vertex.java b/modules/core/src/main/java/org/locationtech/jts/triangulate/quadedge/Vertex.java index 058fa3ee7d..b5fb965efb 100644 --- a/modules/core/src/main/java/org/locationtech/jts/triangulate/quadedge/Vertex.java +++ b/modules/core/src/main/java/org/locationtech/jts/triangulate/quadedge/Vertex.java @@ -16,6 +16,7 @@ import org.locationtech.jts.algorithm.HCoordinate; import org.locationtech.jts.algorithm.NotRepresentableException; import org.locationtech.jts.geom.Coordinate; +import org.locationtech.jts.math.MathUtil; /** * Models a site (node) in a {@link QuadEdgeSubdivision}. @@ -161,7 +162,7 @@ Vertex sub(Vertex v) { /* magnitude of vector */ double magn() { - return (Math.hypot(p.x, p.y)); + return (MathUtil.hypot(p.x, p.y)); } /* returns k X v (cross product). this is a vector perpendicular to v */ diff --git a/modules/lab/src/main/java/org/locationtech/jtslab/edgeray/EdgeRay.java b/modules/lab/src/main/java/org/locationtech/jtslab/edgeray/EdgeRay.java index 9b87740a4a..9e550d1e49 100644 --- a/modules/lab/src/main/java/org/locationtech/jtslab/edgeray/EdgeRay.java +++ b/modules/lab/src/main/java/org/locationtech/jtslab/edgeray/EdgeRay.java @@ -12,6 +12,7 @@ package org.locationtech.jtslab.edgeray; import org.locationtech.jts.geom.Coordinate; +import org.locationtech.jts.math.MathUtil; class EdgeRay { @@ -28,7 +29,7 @@ public static double areaTermBoth(double x0, double y0, double x1, double y1) { double dx = x1 - x0; double dy = y1 - y0; - double len = Math.hypot(dx, dy); + double len = MathUtil.hypot(dx, dy); double u0x = dx / len; double u0y = dy / len; @@ -59,7 +60,7 @@ public static double areaTerm( double dx = x1 - x0; double dy = y1 - y0; - double len = Math.hypot(dx, dy); + double len = MathUtil.hypot(dx, dy); if (len <= 0) return 0;