private boolean isConcave(Coordinate p0, Coordinate p1, Coordinate p2) { int orientation = CGAlgorithms.computeOrientation(p0, p1, p2); boolean isConcave = (orientation == angleOrientation); return isConcave; } }
/** * Implements the total order relation: * <p> * a has a greater angle with the positive x-axis than b * <p> * Using the obvious algorithm of simply computing the angle is not robust, * since the angle calculation is obviously susceptible to roundoff. * A robust algorithm is: * - first compare the quadrant. If the quadrants * are different, it it trivial to determine which vector is "greater". * - if the vectors lie in the same quadrant, the computeOrientation function * can be used to decide the relative orientation of the vectors. */ public int compareDirection(EdgeEnd e) { if (dx == e.dx && dy == e.dy) return 0; // if the rays are in different quadrants, determining the ordering is trivial if (quadrant > e.quadrant) return 1; if (quadrant < e.quadrant) return -1; // vectors are in the same quadrant - check relative orientation of direction vectors // this is > e if it is CCW of e return CGAlgorithms.computeOrientation(e.p0, e.p1, p1); }
/** *@return whether the three coordinates are collinear and c2 lies between * c1 and c3 inclusive */ private boolean isBetween(Coordinate c1, Coordinate c2, Coordinate c3) { if (CGAlgorithms.computeOrientation(c1, c2, c3) != 0) { return false; } if (c1.x != c3.x) { if (c1.x <= c2.x && c2.x <= c3.x) { return true; } if (c3.x <= c2.x && c2.x <= c1.x) { return true; } } if (c1.y != c3.y) { if (c1.y <= c2.y && c2.y <= c3.y) { return true; } if (c3.y <= c2.y && c2.y <= c1.y) { return true; } } return false; }
/** * Returns 1 if this DirectedEdge has a greater angle with the * positive x-axis than b", 0 if the DirectedEdges are collinear, and -1 otherwise. * <p> * Using the obvious algorithm of simply computing the angle is not robust, * since the angle calculation is susceptible to roundoff. A robust algorithm * is: * <ul> * <li>first compare the quadrants. If the quadrants are different, it it * trivial to determine which vector is "greater". * <li>if the vectors lie in the same quadrant, the robust * {@link CGAlgorithms#computeOrientation(Coordinate, Coordinate, Coordinate)} * function can be used to decide the relative orientation of the vectors. * </ul> */ public int compareDirection(DirectedEdge e) { // if the rays are in different quadrants, determining the ordering is trivial if (quadrant > e.quadrant) return 1; if (quadrant < e.quadrant) return -1; // vectors are in the same quadrant - check relative orientation of direction vectors // this is > e if it is CCW of e return CGAlgorithms.computeOrientation(e.p0, e.p1, p1); }
int orient = CGAlgorithms.computeOrientation(o, p, q);
private boolean isShallowConcavity(Coordinate p0, Coordinate p1, Coordinate p2, double distanceTol) { int orientation = CGAlgorithms.computeOrientation(p0, p1, p2); boolean isAngleToSimplify = (orientation == angleOrientation); if (! isAngleToSimplify) return false; double dist = CGAlgorithms.distancePointLine(p1, p0, p2); return dist < distanceTol; }
/** * Uses the Graham Scan algorithm to compute the convex hull vertices. * * @param c a list of points, with at least 3 entries * @return a Stack containing the ordered points of the convex hull ring */ private Stack grahamScan(Coordinate[] c) { Coordinate p; Stack ps = new Stack(); p = (Coordinate) ps.push(c[0]); p = (Coordinate) ps.push(c[1]); p = (Coordinate) ps.push(c[2]); for (int i = 3; i < c.length; i++) { p = (Coordinate) ps.pop(); // check for empty stack to guard against robustness problems while ( ! ps.empty() && CGAlgorithms.computeOrientation((Coordinate) ps.peek(), p, c[i]) > 0) { p = (Coordinate) ps.pop(); } p = (Coordinate) ps.push(p); p = (Coordinate) ps.push(c[i]); } p = (Coordinate) ps.push(c[0]); return ps; }
/** * The coordinate pairs match if they define line segments lying in the same direction. * E.g. the segments are parallel and in the same quadrant * (as opposed to parallel and opposite!). */ private boolean matchInSameDirection(Coordinate p0, Coordinate p1, Coordinate ep0, Coordinate ep1) { if (! p0.equals(ep0)) return false; if (CGAlgorithms.computeOrientation(p0, p1, ep1) == CGAlgorithms.COLLINEAR && Quadrant.quadrant(p0, p1) == Quadrant.quadrant(ep0, ep1) ) return true; return false; }
private void findRightmostEdgeAtVertex() { /** * The rightmost point is an interior vertex, so it has a segment on either side of it. * If these segments are both above or below the rightmost point, we need to * determine their relative orientation to decide which is rightmost. */ Coordinate[] pts = minDe.getEdge().getCoordinates(); Assert.isTrue(minIndex > 0 && minIndex < pts.length, "rightmost point expected to be interior vertex of edge"); Coordinate pPrev = pts[minIndex - 1]; Coordinate pNext = pts[minIndex + 1]; int orientation = CGAlgorithms.computeOrientation(minCoord, pNext, pPrev); boolean usePrev = false; // both segments are below min point if (pPrev.y < minCoord.y && pNext.y < minCoord.y && orientation == CGAlgorithms.COUNTERCLOCKWISE) { usePrev = true; } else if (pPrev.y > minCoord.y && pNext.y > minCoord.y && orientation == CGAlgorithms.CLOCKWISE) { usePrev = true; } // if both segments are on the same side, do nothing - either is safe // to select as a rightmost segment if (usePrev) { minIndex = minIndex - 1; } } private void checkForRightmostCoordinate(DirectedEdge de)
if (CGAlgorithms.computeOrientation(seg.p0, seg.p1, stabbingRayLeftPt) == CGAlgorithms.RIGHT) continue;
return false; int disc = computeOrientation(prev, hiPt, next);
private boolean isConcave(Coordinate p0, Coordinate p1, Coordinate p2) { int orientation = CGAlgorithms.computeOrientation(p0, p1, p2); boolean isConcave = (orientation == angleOrientation); return isConcave; } }
public void addNextSegment(Coordinate p, boolean addStartPoint) { // s0-s1-s2 are the coordinates of the previous segment and the current one s0 = s1; s1 = s2; s2 = p; seg0.setCoordinates(s0, s1); computeOffsetSegment(seg0, side, distance, offset0); seg1.setCoordinates(s1, s2); computeOffsetSegment(seg1, side, distance, offset1); // do nothing if points are equal if (s1.equals(s2)) return; int orientation = CGAlgorithms.computeOrientation(s0, s1, s2); boolean outsideTurn = (orientation == CGAlgorithms.CLOCKWISE && side == Position.LEFT) || (orientation == CGAlgorithms.COUNTERCLOCKWISE && side == Position.RIGHT); if (orientation == 0) { // lines are collinear addCollinear(addStartPoint); } else if (outsideTurn) { addOutsideTurn(orientation, addStartPoint); } else { // inside turn addInsideTurn(orientation, addStartPoint); } }
private boolean isShallowConcavity(Coordinate p0, Coordinate p1, Coordinate p2, double distanceTol) { int orientation = CGAlgorithms.computeOrientation(p0, p1, p2); boolean isAngleToSimplify = (orientation == angleOrientation); if (! isAngleToSimplify) return false; double dist = CGAlgorithms.distancePointLine(p1, p0, p2); return dist < distanceTol; }
/** * The coordinate pairs match if they define line segments lying in the same direction. * E.g. the segments are parallel and in the same quadrant * (as opposed to parallel and opposite!). */ private boolean matchInSameDirection(Coordinate p0, Coordinate p1, Coordinate ep0, Coordinate ep1) { if (! p0.equals(ep0)) return false; if (CGAlgorithms.computeOrientation(p0, p1, ep1) == CGAlgorithms.COLLINEAR && Quadrant.quadrant(p0, p1) == Quadrant.quadrant(ep0, ep1) ) return true; return false; }
/** * Reverse the LineString to be oriented counter-clockwise. * @param lineString * @return */ private static LineString getCounterClockWise(final LineString lineString) { final Coordinate c0 = lineString.getCoordinateN(0); final Coordinate c1 = lineString.getCoordinateN(1); final Coordinate c2 = lineString.getCoordinateN(2); lineString.apply(new UpdateZCoordinateSequenceFilter(0, 3)); if (CGAlgorithms.computeOrientation(c0, c1, c2) == CGAlgorithms.COUNTERCLOCKWISE) { return lineString; } else { return (LineString) lineString.reverse(); } }
/** * Reverse the LineString to be oriented counter-clockwise. * @param lineString * @return */ private static LineString getCounterClockWise(final LineString lineString) { final Coordinate c0 = lineString.getCoordinateN(0); final Coordinate c1 = lineString.getCoordinateN(1); final Coordinate c2 = lineString.getCoordinateN(2); lineString.apply(new UpdateZCoordinateSequenceFilter(0, 3)); if (CGAlgorithms.computeOrientation(c0, c1, c2) == CGAlgorithms.COUNTERCLOCKWISE) { return lineString; } else { return (LineString) lineString.reverse(); } }
/** * Reverse the LineString to be oriented clockwise. * All NaN z values are replaced by a zero value. * @param lineString * @return */ private static LineString getClockWise(final LineString lineString) { final Coordinate c0 = lineString.getCoordinateN(0); final Coordinate c1 = lineString.getCoordinateN(1); final Coordinate c2 = lineString.getCoordinateN(2); lineString.apply(new UpdateZCoordinateSequenceFilter(0, 3)); if (CGAlgorithms.computeOrientation(c0, c1, c2) == CGAlgorithms.CLOCKWISE) { return lineString; } else { return (LineString) lineString.reverse(); } }
/** * Reverse the LineString to be oriented clockwise. * All NaN z values are replaced by a zero value. * @param lineString * @return */ private static LineString getClockWise(final LineString lineString) { final Coordinate c0 = lineString.getCoordinateN(0); final Coordinate c1 = lineString.getCoordinateN(1); final Coordinate c2 = lineString.getCoordinateN(2); lineString.apply(new UpdateZCoordinateSequenceFilter(0, 3)); if (CGAlgorithms.computeOrientation(c0, c1, c2) == CGAlgorithms.CLOCKWISE) { return lineString; } else { return (LineString) lineString.reverse(); } }
public void addNextSegment(Coordinate p, boolean addStartPoint) { // s0-s1-s2 are the coordinates of the previous segment and the current one s0 = s1; s1 = s2; s2 = p; seg0.setCoordinates(s0, s1); computeOffsetSegment(seg0, side, distance, offset0); seg1.setCoordinates(s1, s2); computeOffsetSegment(seg1, side, distance, offset1); // do nothing if points are equal if (s1.equals(s2)) return; int orientation = CGAlgorithms.computeOrientation(s0, s1, s2); boolean outsideTurn = (orientation == CGAlgorithms.CLOCKWISE && side == Position.LEFT) || (orientation == CGAlgorithms.COUNTERCLOCKWISE && side == Position.RIGHT); if (orientation == 0) { // lines are collinear addCollinear(addStartPoint); } else if (outsideTurn) { addOutsideTurn(orientation, addStartPoint); } else { // inside turn addInsideTurn(orientation, addStartPoint); } }