Beispiel #1
0
    public int XcompareTo(Object obj) {
      DepthSegment other = (DepthSegment) obj;

      // if segments are collinear and vertical compare endpoints
      if (isVertical() && other.isVertical() && upwardSeg.p0.x == other.upwardSeg.p0.x)
        return compareX(this.upwardSeg, other.upwardSeg);
      // check if segments are trivially ordered along X
      if (upwardSeg.maxX() <= other.upwardSeg.minX()) return -1;
      if (upwardSeg.minX() >= other.upwardSeg.maxX()) return 1;
      /**
       * try and compute a determinate orientation for the segments. Test returns 1 if other is left
       * of this (i.e. this > other)
       */
      int orientIndex = upwardSeg.orientationIndex(other.upwardSeg);
      // if orientation is determinate, return it
      if (orientIndex != 0) return orientIndex;

      /**
       * If comparison between this and other is indeterminate, try the opposite call order.
       * orientationIndex value is 1 if this is left of other, so have to flip sign to get proper
       * comparison value of -1 if this is leftmost
       */
      if (orientIndex == 0) orientIndex = -1 * other.upwardSeg.orientationIndex(upwardSeg);

      // if orientation is determinate, return it
      if (orientIndex != 0) return orientIndex;

      // otherwise, segs must be collinear - sort based on minimum X value
      return compareX(this.upwardSeg, other.upwardSeg);
    }
Beispiel #2
0
 public static void computeDistance(LineString line, Coordinate pt, PointPairDistance ptDist) {
   LineSegment tempSegment = new LineSegment();
   Coordinate[] coords = line.getCoordinates();
   for (int i = 0; i < coords.length - 1; i++) {
     tempSegment.setCoordinates(coords[i], coords[i + 1]);
     // this is somewhat inefficient - could do better
     Coordinate closestPt = tempSegment.closestPoint(pt);
     ptDist.setMinimum(closestPt, pt);
   }
 }
Beispiel #3
0
 private DepthSegment createRandomDepthSegment() {
   double scale = 10;
   int max = 10;
   double x0 = randint(max);
   double y0 = randint(max);
   double ang = 2 * Math.PI * Math.random();
   double x1 = Math.rint(x0 + max * Math.cos(ang));
   double y1 = Math.rint(y0 + max * Math.sin(ang));
   LineSegment seg = new LineSegment(x0, y0, x1, y1);
   seg.normalize();
   return new DepthSegment(seg, 0);
 }
Beispiel #4
0
    /**
     * Defines a comparison operation on DepthSegments which orders them left to right
     *
     * <pre>
     * DS1 < DS2   if   DS1.seg is left of DS2.seg
     * DS1 > DS2   if   DS1.seg is right of DS2.seg
     * </pre>
     *
     * @param obj
     * @return the comparison value
     */
    public int compareTo(Object obj) {
      DepthSegment other = (DepthSegment) obj;

      if (!envelopesOverlap(upwardSeg, other.upwardSeg))
        return upwardSeg.compareTo(other.upwardSeg);
      // check orientations
      int orientIndex = upwardSeg.orientationIndex(other.upwardSeg);
      if (orientIndex != 0) return orientIndex;
      orientIndex = -other.upwardSeg.orientationIndex(upwardSeg);
      if (orientIndex != 0) return orientIndex;
      // segments cross or are collinear.  Use segment ordering
      return upwardSeg.compareTo(other.upwardSeg);
    }
Beispiel #5
0
  /**
   * Compute the width information for a ring of {@link Coordinate}s. Leaves the width information
   * in the instance variables.
   *
   * @param pts
   */
  private void computeConvexRingMinDiameter(Coordinate[] pts) {
    // for each segment in the ring
    minWidth = Double.MAX_VALUE;
    int currMaxIndex = 1;

    LineSegment seg = new LineSegment();
    // compute the max distance for all segments in the ring, and pick the minimum
    for (int i = 0; i < pts.length - 1; i++) {
      seg.p0 = pts[i];
      seg.p1 = pts[i + 1];
      currMaxIndex = findMaxPerpDistance(pts, seg, currMaxIndex);
    }
  }
Beispiel #6
0
 public boolean envelopesOverlap(LineSegment seg1, LineSegment seg2) {
   if (seg1.maxX() <= seg2.minX()) return false;
   if (seg2.maxX() <= seg1.minX()) return false;
   if (seg1.maxY() <= seg2.minY()) return false;
   if (seg2.maxY() <= seg1.minY()) return false;
   return true;
 }
Beispiel #7
0
  /**
   * Gets a {@link LineString} which is a minimum diameter
   *
   * @return a {@link LineString} which is a minimum diameter
   */
  public LineString getDiameter() {
    computeMinimumDiameter();

    // return empty linestring if no minimum width calculated
    if (minWidthPt == null) return inputGeom.getFactory().createLineString((Coordinate[]) null);

    Coordinate basePt = minBaseSeg.project(minWidthPt);
    return inputGeom.getFactory().createLineString(new Coordinate[] {basePt, minWidthPt});
  }
Beispiel #8
0
  private int findMaxPerpDistance(Coordinate[] pts, LineSegment seg, int startIndex) {
    double maxPerpDistance = seg.distancePerpendicular(pts[startIndex]);
    double nextPerpDistance = maxPerpDistance;
    int maxIndex = startIndex;
    int nextIndex = maxIndex;
    while (nextPerpDistance >= maxPerpDistance) {
      maxPerpDistance = nextPerpDistance;
      maxIndex = nextIndex;

      nextIndex = nextIndex(pts, maxIndex);
      nextPerpDistance = seg.distancePerpendicular(pts[nextIndex]);
    }
    // found maximum width for this segment - update global min dist if appropriate
    if (maxPerpDistance < minWidth) {
      minPtIndex = maxIndex;
      minWidth = maxPerpDistance;
      minWidthPt = pts[minPtIndex];
      minBaseSeg = new LineSegment(seg);
      //      System.out.println(minBaseSeg);
      //      System.out.println(minWidth);
    }
    return maxIndex;
  }
Beispiel #9
0
  private void computeWidthConvex(Geometry convexGeom) {
    // System.out.println("Input = " + geom);
    if (convexGeom instanceof Polygon)
      convexHullPts = ((Polygon) convexGeom).getExteriorRing().getCoordinates();
    else convexHullPts = convexGeom.getCoordinates();

    // special cases for lines or points or degenerate rings
    if (convexHullPts.length == 0) {
      minWidth = 0.0;
      minWidthPt = null;
      minBaseSeg = null;
    } else if (convexHullPts.length == 1) {
      minWidth = 0.0;
      minWidthPt = convexHullPts[0];
      minBaseSeg.p0 = convexHullPts[0];
      minBaseSeg.p1 = convexHullPts[0];
    } else if (convexHullPts.length == 2 || convexHullPts.length == 3) {
      minWidth = 0.0;
      minWidthPt = convexHullPts[0];
      minBaseSeg.p0 = convexHullPts[0];
      minBaseSeg.p1 = convexHullPts[1];
    } else computeConvexRingMinDiameter(convexHullPts);
  }
Beispiel #10
0
  /**
   * Gets the minimum rectangular {@link Polygon} which encloses the input geometry. The rectangle
   * has width equal to the minimum diameter, and a longer length. If the convex hull of the input
   * is degenerate (a line or point) a {@link LineString} or {@link Point} is returned.
   *
   * <p>The minimum rectangle can be used as an extremely generalized representation for the given
   * geometry.
   *
   * @return the minimum rectangle enclosing the input (or a line or point if degenerate)
   */
  public Geometry getMinimumRectangle() {
    computeMinimumDiameter();

    // check if minimum rectangle is degenerate (a point or line segment)
    if (minWidth == 0.0) {
      if (minBaseSeg.p0.equals2D(minBaseSeg.p1)) {
        return inputGeom.getFactory().createPoint(minBaseSeg.p0);
      }
      return minBaseSeg.toGeometry(inputGeom.getFactory());
    }

    // deltas for the base segment of the minimum diameter
    double dx = minBaseSeg.p1.x - minBaseSeg.p0.x;
    double dy = minBaseSeg.p1.y - minBaseSeg.p0.y;

    /*
    double c0 = computeC(dx, dy, minBaseSeg.p0);
    double c1 = computeC(dx, dy, minBaseSeg.p1);
    */

    double minPara = Double.MAX_VALUE;
    double maxPara = -Double.MAX_VALUE;
    double minPerp = Double.MAX_VALUE;
    double maxPerp = -Double.MAX_VALUE;

    // compute maxima and minima of lines parallel and perpendicular to base segment
    for (int i = 0; i < convexHullPts.length; i++) {

      double paraC = computeC(dx, dy, convexHullPts[i]);
      if (paraC > maxPara) maxPara = paraC;
      if (paraC < minPara) minPara = paraC;

      double perpC = computeC(-dy, dx, convexHullPts[i]);
      if (perpC > maxPerp) maxPerp = perpC;
      if (perpC < minPerp) minPerp = perpC;
    }

    // compute lines along edges of minimum rectangle
    LineSegment maxPerpLine = computeSegmentForLine(-dx, -dy, maxPerp);
    LineSegment minPerpLine = computeSegmentForLine(-dx, -dy, minPerp);
    LineSegment maxParaLine = computeSegmentForLine(-dy, dx, maxPara);
    LineSegment minParaLine = computeSegmentForLine(-dy, dx, minPara);

    // compute vertices of rectangle (where the para/perp max & min lines intersect)
    Coordinate p0 = maxParaLine.lineIntersection(maxPerpLine);
    Coordinate p1 = minParaLine.lineIntersection(maxPerpLine);
    Coordinate p2 = minParaLine.lineIntersection(minPerpLine);
    Coordinate p3 = maxParaLine.lineIntersection(minPerpLine);

    LinearRing shell =
        inputGeom.getFactory().createLinearRing(new Coordinate[] {p0, p1, p2, p3, p0});
    return inputGeom.getFactory().createPolygon(shell, null);
  }
Beispiel #11
0
 public String toString() {
   return upwardSeg.toString();
 }
Beispiel #12
0
 public static void computeDistance(LineSegment segment, Coordinate pt, PointPairDistance ptDist) {
   Coordinate closestPt = segment.closestPoint(pt);
   ptDist.setMinimum(closestPt, pt);
 }