/** * Returns <code>true</code> if <code>other</code> has the same values for its points. * * @param o a <code>LineSegment</code> with which to do the comparison. * @return <code>true</code> if <code>other</code> is a <code>LineSegment</code> with the same * values for the x and y ordinates. */ public boolean equals(Object o) { if (!(o instanceof LineSegment)) { return false; } LineSegment other = (LineSegment) o; return p0.equals(other.p0) && p1.equals(other.p1); }
/** * Compute the projection of a point onto the line determined by this line segment. * * <p>Note that the projected point may lie outside the line segment. If this is the case, the * projection factor will lie outside the range [0.0, 1.0]. */ public Coordinate project(Coordinate p) { if (p.equals(p0) || p.equals(p1)) return new Coordinate(p); double r = projectionFactor(p); Coordinate coord = new Coordinate(); coord.x = p0.x + r * (p1.x - p0.x); coord.y = p0.y + r * (p1.y - p0.y); return coord; }
/** * Computes the closest point on this line segment to another point. * * @param p the point to find the closest point to * @return a Coordinate which is the closest point on the line segment to the point p */ public Coordinate closestPoint(Coordinate p) { double factor = projectionFactor(p); if (factor > 0 && factor < 1) { return project(p); } double dist0 = p0.distance(p); double dist1 = p1.distance(p); if (dist0 < dist1) return p0; return p1; }
public void findEdge(List dirEdgeList) { /** * Check all forward DirectedEdges only. This is still general, because each edge has a forward * DirectedEdge. */ for (Iterator i = dirEdgeList.iterator(); i.hasNext(); ) { DirectedEdge de = (DirectedEdge) i.next(); if (!de.isForward()) continue; checkForRightmostCoordinate(de); } /** * If the rightmost point is a node, we need to identify which of the incident edges is * rightmost. */ Assert.isTrue( minIndex != 0 || minCoord.equals(minDe.getCoordinate()), "inconsistency in rightmost processing"); if (minIndex == 0) { findRightmostEdgeAtNode(); } else { findRightmostEdgeAtVertex(); } /** now check that the extreme side is the R side. If not, use the sym instead. */ orientedDe = minDe; int rightmostSide = getRightmostSide(minDe, minIndex); if (rightmostSide == Position.LEFT) { orientedDe = minDe.getSym(); } }
/** * Computes the closest points on two line segments. * * @param line the segment to find the closest point to * @return a pair of Coordinates which are the closest points on the line segments */ public Coordinate[] closestPoints(LineSegment line) { // test for intersection Coordinate intPt = intersection(line); if (intPt != null) { return new Coordinate[] {intPt, intPt}; } /** * if no intersection closest pair contains at least one endpoint. Test each endpoint in turn. */ Coordinate[] closestPt = new Coordinate[2]; double minDistance = Double.MAX_VALUE; double dist; Coordinate close00 = closestPoint(line.p0); minDistance = close00.distance(line.p0); closestPt[0] = close00; closestPt[1] = line.p0; Coordinate close01 = closestPoint(line.p1); dist = close01.distance(line.p1); if (dist < minDistance) { minDistance = dist; closestPt[0] = close01; closestPt[1] = line.p1; } Coordinate close10 = line.closestPoint(p0); dist = close10.distance(p0); if (dist < minDistance) { minDistance = dist; closestPt[0] = p0; closestPt[1] = close10; } Coordinate close11 = line.closestPoint(p1); dist = close11.distance(p1); if (dist < minDistance) { minDistance = dist; closestPt[0] = p1; closestPt[1] = close11; } return closestPt; }
/** * Computes the Projection Factor for the projection of the point p onto this LineSegment. The * Projection Factor is the constant r by which the vector for this segment must be multiplied to * equal the vector for the projection of <tt>p<//t> on the line defined by this segment. * * <p>The projection factor will lie in the range <tt>(-inf, +inf)</tt>, or be <code>NaN</code> if * the line segment has zero length.. * * @param p the point to compute the factor for * @return the projection factor for the point */ public double projectionFactor(Coordinate p) { if (p.equals(p0)) return 0.0; if (p.equals(p1)) return 1.0; // Otherwise, use comp.graphics.algorithms Frequently Asked Questions method /* AC dot AB r = --------- ||AB||^2 r has the following meaning: r=0 P = A r=1 P = B r<0 P is on the backward extension of AB r>1 P is on the forward extension of AB 0<r<1 P is interior to AB */ double dx = p1.x - p0.x; double dy = p1.y - p0.y; double len = dx * dx + dy * dy; // handle zero-length segments if (len <= 0.0) return Double.NaN; double r = ((p.x - p0.x) * dx + (p.y - p0.y) * dy) / len; return r; }
/** * Returns <code>true</code> if <code>other</code> is topologically equal to this LineSegment * (e.g. irrespective of orientation). * * @param other a <code>LineSegment</code> with which to do the comparison. * @return <code>true</code> if <code>other</code> is a <code>LineSegment</code> with the same * values for the x and y ordinates. */ public boolean equalsTopo(LineSegment other) { return p0.equals(other.p0) && p1.equals(other.p1) || p0.equals(other.p1) && p1.equals(other.p0); }
/** * Compares this object with the specified object for order. Uses the standard lexicographic * ordering for the points in the LineSegment. * * @param o the <code>LineSegment</code> with which this <code>LineSegment</code> is being * compared * @return a negative integer, zero, or a positive integer as this <code>LineSegment</code> is * less than, equal to, or greater than the specified <code>LineSegment</code> */ public int compareTo(Object o) { LineSegment other = (LineSegment) o; int comp0 = p0.compareTo(other.p0); if (comp0 != 0) return comp0; return p1.compareTo(other.p1); }
/** * Computes the {@link Coordinate} that lies a given fraction along the line defined by this * segment. A fraction of <code>0.0</code> returns the start point of the segment; a fraction of * <code>1.0</code> returns the end point of the segment. If the fraction is < 0.0 or > 1.0 the * point returned will lie before the start or beyond the end of the segment. * * @param segmentLengthFraction the fraction of the segment length along the line * @return the point at that distance */ public Coordinate pointAlong(double segmentLengthFraction) { Coordinate coord = new Coordinate(); coord.x = p0.x + segmentLengthFraction * (p1.x - p0.x); coord.y = p0.y + segmentLengthFraction * (p1.y - p0.y); return coord; }
/** * Puts the line segment into a normalized form. This is useful for using line segments in maps * and indexes when topological equality rather than exact equality is desired. A segment in * normalized form has the first point smaller than the second (according to the standard ordering * on {@link Coordinate}). */ public void normalize() { if (p1.compareTo(p0) < 0) reverse(); }
/** * Computes the length of the line segment. * * @return the length of the line segment */ public double getLength() { return p0.distance(p1); }
/** * Tests whether a given point is in an array of points. Uses a value-based test. * * @param pt a {@link Coordinate} for the test point * @param pts an array of {@link Coordinate}s to test * @return <code>true</code> if the point is in the array * @deprecated */ public static boolean isInList(Coordinate pt, Coordinate[] pts) { for (int i = 0; i < pts.length; i++) { if (pt.equals(pts[i])) return true; } return false; }