You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by lu...@apache.org on 2012/09/30 15:22:29 UTC

svn commit: r1392022 - in /commons/proper/math/trunk: ./ src/changes/ src/main/java/org/apache/commons/math3/geometry/euclidean/twod/ src/test/java/org/apache/commons/math3/geometry/euclidean/twod/

Author: luc
Date: Sun Sep 30 13:22:28 2012
New Revision: 1392022

URL: http://svn.apache.org/viewvc?rev=1392022&view=rev
Log:
Added distance to point to 2D Line and Segment.

Patch provided by Curtis Jensen applied with minor modifications.

JIRA: MATH-641

Added:
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/euclidean/twod/SegmentTest.java   (with props)
Modified:
    commons/proper/math/trunk/pom.xml
    commons/proper/math/trunk/src/changes/changes.xml
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/euclidean/twod/Line.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/euclidean/twod/Segment.java
    commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/euclidean/twod/LineTest.java

Modified: commons/proper/math/trunk/pom.xml
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/pom.xml?rev=1392022&r1=1392021&r2=1392022&view=diff
==============================================================================
--- commons/proper/math/trunk/pom.xml (original)
+++ commons/proper/math/trunk/pom.xml Sun Sep 30 13:22:28 2012
@@ -193,6 +193,9 @@
       <name>Matthias Hummel</name>
     </contributor>
     <contributor>
+      <name>Curtis Jensen</name>
+    </contributor>
+    <contributor>
       <name>Ismael Juma</name>
     </contributor>
     <contributor>

Modified: commons/proper/math/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/changes/changes.xml?rev=1392022&r1=1392021&r2=1392022&view=diff
==============================================================================
--- commons/proper/math/trunk/src/changes/changes.xml (original)
+++ commons/proper/math/trunk/src/changes/changes.xml Sun Sep 30 13:22:28 2012
@@ -52,8 +52,11 @@ If the output is not quite correct, chec
   <body>
     <release version="3.1" date="TBD" description="
 ">
+      <action dev="luc" type="fix" issue="MATH-641" due-to="Curtis Jensen">
+        Added distance to point to 2D Line and Segment.
+      </action>
       <action dev="erans" type="fix" issue="MATH-783">
-        "PowellOptimizer" (package "o.a.c.m.optimization.direct") uses
+          "PowellOptimizer" (package "o.a.c.m.optimization.direct") uses
         "BrentOptimizer" as its internal line search optimizer. The fix
         forces the convergence criterion of "BrentOptimizer" to use
         function values (instead of domain values).

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/euclidean/twod/Line.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/euclidean/twod/Line.java?rev=1392022&r1=1392021&r2=1392022&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/euclidean/twod/Line.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/euclidean/twod/Line.java Sun Sep 30 13:22:28 2012
@@ -263,6 +263,18 @@ public class Line implements Hyperplane<
         return FastMath.abs(getOffset(p)) < 1.0e-10;
     }
 
+    /** Compute the distance between the instance and a point.
+     *  This is a shortcut for invoking FastMath.abs(getOffset(p)), 
+     *  and provides consistency with what is in the 
+     *  org.apache.commons.math3.geometry.euclidean.threed.Line class.
+     *  
+     * @param p to check
+     * @return distance between the instance and the point
+     */
+    public double distance(final Vector2D p) {
+        return FastMath.abs(getOffset(p));
+    }
+
     /** Check the instance is parallel to another line.
      * @param line other line to check
      * @return true if the instance is parallel to the other line

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/euclidean/twod/Segment.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/euclidean/twod/Segment.java?rev=1392022&r1=1392021&r2=1392022&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/euclidean/twod/Segment.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/euclidean/twod/Segment.java Sun Sep 30 13:22:28 2012
@@ -16,6 +16,7 @@
  */
 package org.apache.commons.math3.geometry.euclidean.twod;
 
+import org.apache.commons.math3.util.FastMath;
 
 /** Simple container for a two-points segment.
  * @version $Id$
@@ -64,4 +65,43 @@ public class Segment {
         return line;
     }
 
+    /**
+     * Calculates the shortest distance from a point to this line segment.  
+     * <p>
+     * If the perpendicular extension from the point to the line does not 
+     * cross in the bounds of the line segment, the shortest distance to 
+     * the two end points will be returned.
+     * </p>
+     * 
+     * Algorithm adapted from: http://www.codeguru.com/forum/printthread.php?s=cc8cf0596231f9a7dba4da6e77c29db3&t=194400&pp=15&page=1 
+     */
+    public double distance(final Vector2D p) {
+        final double deltaX = end.getX() - start.getX();
+        final double deltaY = end.getY() - start.getY();
+
+        final double r = ((p.getX() - start.getX()) * deltaX + (p.getY() - start.getY()) * deltaY) /
+                         (deltaX * deltaX + deltaY * deltaY);
+
+        // r == 0 => P = startPt
+        // r == 1 => P = endPt
+        // r < 0 => P is on the backward extension of the segment
+        // r > 1 => P is on the forward extension of the segment
+        // 0 < r < 1 => P is on the segment
+
+        // if point isn't on the line segment, just return the shortest distance to the end points
+        if (r < 0 || r > 1) {
+            final double dist1 = getStart().distance(p);
+            final double dist2 = getEnd().distance(p);
+
+            return FastMath.min(dist1, dist2);
+        }
+        else {
+            // find point on line and see if it is in the line segment
+            final double px = start.getX() + r * deltaX;
+            final double py = start.getY() + r * deltaY;
+
+            final Vector2D interPt = new Vector2D(px, py);
+            return interPt.distance(p);
+        }
+    }
 }

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/euclidean/twod/LineTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/euclidean/twod/LineTest.java?rev=1392022&r1=1392021&r2=1392022&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/euclidean/twod/LineTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/euclidean/twod/LineTest.java Sun Sep 30 13:22:28 2012
@@ -64,6 +64,13 @@ public class LineTest {
     }
 
     @Test
+    public void testDistance() {
+        Line l = new Line(new Vector2D(2, 1), new Vector2D(-2, -2));
+        Assert.assertEquals(+5.0, l.distance(new Vector2D(5, -3)), 1.0e-10);
+        Assert.assertEquals(+5.0, l.distance(new Vector2D(-5, 2)), 1.0e-10);
+    }
+
+    @Test
     public void testPointAt() {
         Line l = new Line(new Vector2D(2, 1), new Vector2D(-2, -2));
         for (double a = -2.0; a < 2.0; a += 0.2) {

Added: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/euclidean/twod/SegmentTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/euclidean/twod/SegmentTest.java?rev=1392022&view=auto
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/euclidean/twod/SegmentTest.java (added)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/euclidean/twod/SegmentTest.java Sun Sep 30 13:22:28 2012
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math3.geometry.euclidean.twod;
+
+import org.apache.commons.math3.geometry.euclidean.twod.Line;
+import org.apache.commons.math3.geometry.euclidean.twod.Vector2D;
+import org.apache.commons.math3.util.FastMath;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class SegmentTest {
+
+    @Test
+    public void testDistance() {
+        Vector2D start = new Vector2D(2, 2);
+        Vector2D end = new Vector2D(-2, -2);
+        Segment segment = new Segment(start, end, new Line(start, end));
+
+        // distance to center of segment
+        Assert.assertEquals(FastMath.sqrt(2), segment.distance(new Vector2D(1, -1)), 1.0e-10);
+
+        // distance a point on segment
+        Assert.assertEquals(FastMath.sin(Math.PI / 4.0), segment.distance(new Vector2D(0, -1)), 1.0e-10);
+
+        // distance to end point
+        Assert.assertEquals(FastMath.sqrt(8), segment.distance(new Vector2D(0, 4)), 1.0e-10);
+
+        // distance to start point
+        Assert.assertEquals(FastMath.sqrt(8), segment.distance(new Vector2D(0, -4)), 1.0e-10);
+    }
+}

Propchange: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/euclidean/twod/SegmentTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/geometry/euclidean/twod/SegmentTest.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"