/* * 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; }
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 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; }
/* * 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; }
public boolean hasInside(Point2D p) { for (Segment2D s : getEdges()) if (AngleUtil.getTurn(s.getStart(), s.getEnd(), p) != AngleUtil.COUNTERCLOCKWISE) return false; return true; }