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