Beispiel #1
0
 /**
  * Project the value given along the line segment, where 0 represents A and 1 represents B.
  * Tolerance is used to snap points to A or B if close enough. If u < 0 return A and if u > 1
  * return B and the point is beyond the tolerance, return null
  *
  * @param u
  * @param tolerance tolerance for snapping to end points
  * @param target target vector
  * @throws IllegalArgumentException if u was infinite or NaN
  * @throws NullPointerException if tolerance or target was null
  */
 public void projectClosest(double u, Tolerance tolerance, VectBuilder target)
     throws NullPointerException, IllegalArgumentException {
   double x = (u * (bx - ax)) + ax;
   double y = (u * (by - ay)) + ay;
   if ((u < 0) || tolerance.match(x, y, ax, ay)) {
     getA(target);
   } else if ((u > 1) || tolerance.match(x, y, bx, by)) {
     getB(target);
   } else {
     target.set(x, y);
   }
 }
Beispiel #2
0
  static void intersectionLineCircleInternal(
      double ax,
      double ay,
      double bx,
      double by,
      double cx,
      double cy,
      double radius,
      Tolerance tolerance,
      VectBuilder working,
      VectList intersections) {

    projectOnToLineInternal(
        ax, ay, bx, by, cx, cy, tolerance,
        working); // get the closest point on the line to the circle center

    double dx = working.getX();
    double dy = working.getY();

    double distToLineSq = Vect.distSq(cx, cy, dx, dy);
    double radiusSq = radius * radius;
    switch (tolerance.check(distToLineSq - radiusSq)) {
      case 1: // dist to line is greater than radius - line does not intersect circle
        return;
      case 0: // dist to line matches radius - line touches circle
        intersections.add(dx, dy);
        return;
      default: // dist to line is less than radius - line crosses circle
        double mx = bx - ax;
        double my = by - ay;
        double segmentLen = Math.sqrt(mx * mx + my * my);
        double projectDist;
        if (tolerance.check(distToLineSq) == 0) { // line crosses circle center
          projectDist = radius;
          dx = cx;
          dy = cy;
        } else {
          projectDist = Math.sqrt(radiusSq - distToLineSq);
        }
        double mul = projectDist / segmentLen;
        mx *= mul;
        my *= mul;
        intersections.add(dx - mx, dy - my);
        intersections.add(dx + mx, dy + my);
    }
  }
Beispiel #3
0
 static boolean project(
     double ax,
     double ay,
     double bx,
     double by,
     double u,
     Tolerance tolerance,
     VectBuilder target) {
   double x = (u * (bx - ax)) + ax;
   double y = (u * (by - ay)) + ay;
   if (tolerance.match(x, y, ax, ay)) {
     target.set(ax, ay);
     return true;
   } else if (tolerance.match(x, y, bx, by)) {
     target.set(bx, by);
     return true;
   } else {
     target.set(x, y);
     return ((u > 0) && (u < 1));
   }
 }
Beispiel #4
0
  /**
   * Determine if segments intersect. Segments which do not intersect, but are within the tolerance
   * given from each other are considered to intersect unless they are parallel
   *
   * @param line
   * @param tolerance
   * @return true if segments intersect, false otherwise
   * @throws NullPointerException if line or tolerance was null
   */
  public boolean intersectsSeg(Line line, Tolerance tolerance) throws NullPointerException {
    double jax = line.ax;
    double jay = line.ay;
    double jbx = line.bx;
    double jby = line.by;
    double denom = getDenom(ax, ay, bx, by, jax, jay, jbx, jby);
    if (denom == 0.0) { // Lines are parallel.
      return false;
    }
    double ui =
        ((jbx - jax) * (ay - jay) - (jby - jay) * (ax - jax))
            / denom; // projected distance along i and j
    double uj = ((bx - ax) * (ay - jay) - (by - ay) * (ax - jax)) / denom;

    if ((ui >= 0) && (ui <= 1) && (uj >= 0) && (uj <= 1)) {
      return true;
    }
    double x = (ui * (bx - ax)) + ax;
    double y = (ui * (by - ay)) + ay;

    if (ui < 0) {
      if (!tolerance.match(x, y, ax, ay)) {
        return false;
      }
    } else if (ui > 1) {
      if (!tolerance.match(x, y, bx, by)) {
        return false;
      }
    }
    if (uj < 0) {
      if (!tolerance.match(x, y, jax, jay)) {
        return false;
      }
    } else if (uj > 1) {
      if (!tolerance.match(x, y, jbx, jby)) {
        return false;
      }
    }
    return true;
  }
Beispiel #5
0
 /**
  * Determine if the point given lies to the left, right, or on the line given.
  *
  * @param ax
  * @param ay
  * @param bx
  * @param by
  * @param x
  * @param y
  * @param accuracy
  * @return 1 if left of line, -1 if right of line, 0 if on line.
  */
 public static int counterClockwise(
     double ax, double ay, double bx, double by, double x, double y, Tolerance accuracy) {
   bx -= ax;
   by -= ay;
   x -= ax;
   y -= ay;
   double ccw = x * by - y * bx;
   if (ccw
       == 0.0) { // Point is colinear - classify based on whether b is further away from a than
                 // point
     ccw = ((x * x) + (y * y)) - ((bx * bx) + (by * by));
     ccw = Math.max(ccw, 0);
   }
   return accuracy.check(ccw);
 }
Beispiel #6
0
  static boolean intersectionSegInternal(
      double ax,
      double ay,
      double bx,
      double by,
      double jax,
      double jay,
      double jbx,
      double jby,
      Tolerance tolerance,
      VectBuilder target)
      throws NullPointerException {
    if (Vect.compare(ax, ay, bx, by) > 0) {
      double tmp = ax;
      ax = bx;
      bx = tmp;
      tmp = ay;
      ay = by;
      by = tmp;
    }
    if (Vect.compare(jax, jay, jbx, jby) > 0) {
      double tmp = jax;
      jax = jbx;
      jbx = tmp;
      tmp = jay;
      jay = jby;
      jby = tmp;
    }
    if (compare(ax, ay, bx, by, jax, jay, jbx, jby) > 0) {
      double tmp = ax;
      ax = jax;
      jax = tmp;

      tmp = ay;
      ay = jay;
      jay = tmp;

      tmp = bx;
      bx = jbx;
      jbx = tmp;

      tmp = by;
      by = jby;
      jby = tmp;
    }

    double denom = getDenom(ax, ay, bx, by, jax, jay, jbx, jby);
    if (denom == 0.0) { // Lines are parallel.
      return false;
    }
    double ui =
        ((jbx - jax) * (ay - jay) - (jby - jay) * (ax - jax))
            / denom; // projected distance along i and j
    double uj = ((bx - ax) * (ay - jay) - (by - ay) * (ax - jax)) / denom;

    double x, y;
    if (ax == bx) {
      x = ax;
    } else if (jax == jbx) {
      x = jax;
    } else {
      x = (ui * (bx - ax)) + ax;
    }
    if (ay == by) {
      y = ay;
    } else if (jay == jby) {
      y = jay;
    } else {
      y = (ui * (by - ay)) + ay;
    }

    boolean ia = tolerance.match(x, y, ax, ay);
    boolean ib = tolerance.match(x, y, bx, by);
    boolean i = ia || ib || ((ui >= 0) && (ui <= 1));

    boolean ja = tolerance.match(x, y, jax, jay);
    boolean jb = tolerance.match(x, y, jbx, jby);
    boolean j = ja || jb || ((uj >= 0) && (uj <= 1));

    if (i && j) {
      if (ia) {
        target.set(ax, ay);
      } else if (ib) {
        target.set(bx, by);
      } else if (ja) {
        target.set(jax, jay);
      } else if (jb) {
        target.set(jbx, jby);
      } else {
        target.set(x, y);
      }
      return true;
    }
    return false;
  }
Beispiel #7
0
 /**
  * Determine if this line is parallell to that given, with differences in slope within the
  * tolerance
  *
  * @param line
  * @param tolerance
  * @return
  * @throws NullPointerException if line or tolerance was null
  */
 public boolean isParallel(Line line, Tolerance tolerance) throws NullPointerException {
   double denom = getDenom(ax, ay, bx, by, line.ax, line.ay, line.bx, line.by);
   return tolerance.match(denom, 0);
 }
Beispiel #8
0
 /**
  * Get the side of the line on which vect lies. Positive values imply that it lies on the left of
  * the line. Negative values imply it lies on the right of the line. 0 implies it lies on the line
  *
  * @param vect
  * @param tolerance
  * @return
  * @throws IllegalStateException if invalid
  */
 public int sign(Vect vect, Tolerance tolerance) throws NullPointerException {
   return tolerance.check(sign(vect));
 }
Beispiel #9
0
 /**
  * Determine if the distance between the end points is greater than the tolerance given
  *
  * @param tolerance
  * @return true if distance is greater, false otherwise
  */
 public boolean isValid(Tolerance tolerance) {
   return (!tolerance.match(ax, ay, bx, by));
 }