public Segment2D getLongestEdge() { EdgeRing edges = getEdges(); Segment2D longestEdge = null; for (Segment2D edge : edges) if (longestEdge == null || edge.getLength() > longestEdge.getLength()) longestEdge = edge; return longestEdge; }
public double getLengthTo(Point2D p) { double res = 0; for (Segment2D s : getEdges()) { if (s.p0.equals(p)) break; res += s.getLength(); } return res; }
public double getShortestDistance(Point2D p) { double res = Double.POSITIVE_INFINITY; for (Segment2D s : getEdges()) { double d = s.getShortestDistance(p); if (d < res) res = d; } return res; }
public Polygon(EdgeRing col) { points = new PointRing(); edges = new EdgeRing(col); if (!edges.loop()) throw new RuntimeException( "Can't construct " + this.getClass().getName() + " because edge list is not valid loop."); for (Segment2D edge : edges) points.add(edge.getStart()); check(); }
public boolean isRectangular(double tolerance) { EdgeRing edges = getEdges(); for (Segment2D edge : edges) { double angle = AngleUtil.getSmallestDifference(edge.getAngle(), edges.getPrevious(edge).getAngle()); if (angle < AngleUtil.RIGHT - tolerance) return false; if (angle > AngleUtil.RIGHT + tolerance && angle < AngleUtil.FLAT - tolerance) return false; } return true; }
public boolean hasInside(Point2D p) { if (!isLoop()) return false; int turn = Angle.NONE; for (Segment2D s : this) { int localTurn = Angle.getTurn(s.getStart(), s.getEnd(), p); if (localTurn == Angle.NONE) return true; if (turn == Angle.NONE) turn = localTurn; else if (turn != localTurn) return false; } return true; }
public boolean hasIntersectingDiagonal(Segment2D diagonal) { for (Segment2D edge : getEdges()) { if (edge.hasCommonEnd(diagonal)) continue; if (edge.intersectAtSinglePoint(diagonal)) { return true; // Point2D intersection = edge.getUniqueIntersection(diagonal); // if(diagonal.hasPoint(intersection)) // continue; // else // return true; } } return false; }
public OrientedBoundingBox getMinimumBoundingBox() { if (obb == null) { double minArea = Double.POSITIVE_INFINITY; for (Segment2D s : getEdges()) { OrientedBoundingBox b = new OrientedBoundingBox(points, s.getAngle()); if (b.getArea() < minArea) { minArea = b.getArea(); obb = b; } } if (obb == null) throw new RuntimeException("Unexpected Error."); } return obb; }
/* * Code from Computational Geometry Library */ public boolean hasInternalDiagonal(Segment2D diagonal) { Point2D sum = diagonal.getEnd(); Point2D base = diagonal.getStart(); Point2D previous = points.getPrevious(base); Point2D next = points.getNext(base); int turn = AngleUtil.getTurn(previous, base, next); if (turn == AngleUtil.CLOCKWISE) { // At this point, we know that the angle at the base of the diagonal is reflex return AngleUtil.getTurn(sum, base, previous) == AngleUtil.CLOCKWISE || AngleUtil.getTurn(sum, base, next) == AngleUtil.COUNTERCLOCKWISE; } else if (turn == AngleUtil.COUNTERCLOCKWISE) { // At this point, we know that the angle at the base of the diagonal is convex return AngleUtil.getTurn(sum, base, previous) == AngleUtil.CLOCKWISE && AngleUtil.getTurn(sum, base, next) == AngleUtil.COUNTERCLOCKWISE; } else return true; }
/* * Split the polygon in two, by the given line. Returns a list of polygons. The first is the one who contains the * given point. */ public ArrayList<Polygon> getSplits(Point2D pointOnLeftSide, Line2D splitLine) { PointRing left = new PointRing(); PointRing right = new PointRing(); PointRing actual = left; // we check if the given point is valid for this polygon if (!points.contains(pointOnLeftSide)) throw new RuntimeException("The specified point can't be found in this polygon."); Point2D p = pointOnLeftSide; Point2D start = null; // TODO, gerer les splits sur un point unique for (int i = 0; i < size(); i++) { actual.add(p); Point2D next = points.getNext(p); Segment2D edge = new Segment2D(p, next); if (edge.isCollinear(splitLine)) throw new RuntimeException( "Trying to split a polygon with a line collinear to one of its edges : " + splitLine); if (edge.intersect(splitLine)) { // An intersection point is found Point2D intersection = edge.getAnyIntersection(splitLine); // We check if the intersection point is the end of the edge. // In this case, we continue to the next edge which will have intersection on its start // point. if (!intersection.equals(edge.getEnd())) { // We check if the intersection is on the edge start. // In this case, we don't add the point to the actual polygon if (!intersection.equals(edge.getStart())) actual.add(intersection); // then we switch actual polygon if (actual == left) { // we save the point just before the intersection. after the split, we will shift the // left // polygon to this point. start = p; actual = right; } else actual = left; // after switching, we add the intersection to the new actual polygon. actual.add(intersection); } } p = next; } // debug : check if we get only one intersection if (actual == right) throw new RuntimeException( "The polygon have been splitted on an impair number of points, which is not allowed."); left.shiftTo(start); ArrayList<Polygon> res = new ArrayList<Polygon>(); res.add(new Polygon(left)); res.add(new Polygon(right)); return res; }
// TODO verifier le check private boolean isSimple() { ArrayList<Segment2D> edges = getEdges(); for (Segment2D e1 : edges) { for (Segment2D e2 : edges) { if (e1 == e2) continue; if (e1.hasCommonEnd(e2)) continue; if (e1.intersectAtSinglePoint(e2)) { Point2D intersection = e1.getUniqueIntersection(e2); if (e1.hasPoint(intersection) || e2.hasPoint(intersection)) continue; // TODO à voir si on autorise le cas des edges qui se touchent mais ne se // croisent pas // (gestion des trous) else return false; } } } return true; }
public Polyline2D getTransformed(Transform2D transform) { Polyline2D res = new Polyline2D(); for (Segment2D s : this) res.add(s.getTransformed(transform)); return res; }
public boolean contains(Point2D p) { for (Segment2D s : this) if (s.contains(p)) return true; return false; }
public boolean hasInside(Point2D p) { for (Segment2D s : getEdges()) if (AngleUtil.getTurn(s.getStart(), s.getEnd(), p) != AngleUtil.COUNTERCLOCKWISE) return false; return true; }
/* * returns the cumulated lengthes of all edges. */ public double getLength() { double res = 0; for (Segment2D s : getEdges()) res += s.getLength(); return res; }