예제 #1
0
  public Vector2D tangent(double t) {
    // format between min and max admissible values
    t = min(max(0, t), abs(angleExtent));

    // compute tangent vector depending on position
    if (angleExtent < 0) {
      // need to invert vector for indirect arcs
      return ellipse.tangent(startAngle - t).times(-1);
    } else {
      return ellipse.tangent(startAngle + t);
    }
  }
예제 #2
0
 /** Returns the curvature of the ellipse arc. Curvature is negative if the arc is indirect. */
 public double curvature(double t) {
   // convert position to angle
   if (angleExtent < 0) t = startAngle - t;
   else t = startAngle + t;
   double kappa = ellipse.curvature(t);
   return this.isDirect() ? kappa : -kappa;
 }
예제 #3
0
  /*
   * (non-Javadoc)
   *
   * @see math.geom2d.Shape2D#signedDistance(math.geom2d.Point2D)
   */
  public double signedDistance(double x, double y) {
    boolean direct = angleExtent >= 0;

    double dist = distance(x, y);
    Point2D point = new Point2D(x, y);

    boolean inside = ellipse.isInside(point);
    if (inside) return angleExtent > 0 ? -dist : dist;

    Point2D p1 = point(startAngle);
    double endAngle = startAngle + angleExtent;
    Point2D p2 = point(endAngle);
    boolean onLeft = (new StraightLine2D(p1, p2)).isInside(point);

    if (direct && !onLeft) return dist;
    if (!direct && onLeft) return -dist;

    Ray2D ray = new Ray2D(p1, -sin(startAngle), cos(startAngle));
    boolean left1 = ray.isInside(point);
    if (direct && !left1) return dist;
    if (!direct && left1) return -dist;

    ray = new Ray2D(p2, -sin(endAngle), cos(endAngle));
    boolean left2 = ray.isInside(point);
    if (direct && !left2) return dist;
    if (!direct && left2) return -dist;

    if (direct) return -dist;
    else return dist;
  }
예제 #4
0
  /*
   * (non-Javadoc)
   *
   * @see math.geom2d.OrientedCurve2D#windingAngle(math.geom2d.Point2D)
   */
  public double windingAngle(Point2D point) {
    Point2D p1 = point(0);
    Point2D p2 = point(abs(angleExtent));

    // compute angle of point with extreme points
    double angle1 = Angle2D.horizontalAngle(point, p1);
    double angle2 = Angle2D.horizontalAngle(point, p2);

    // test on which 'side' of the arc the point lie
    boolean b1 = (new StraightLine2D(p1, p2)).isInside(point);
    boolean b2 = ellipse.isInside(point);

    if (angleExtent > 0) {
      if (b1 || b2) { // inside of ellipse arc
        if (angle2 > angle1) return angle2 - angle1;
        else return 2 * PI - angle1 + angle2;
      } else { // outside of ellipse arc
        if (angle2 > angle1) return angle2 - angle1 - 2 * PI;
        else return angle2 - angle1;
      }
    } else {
      if (!b1 || b2) {
        if (angle1 > angle2) return angle2 - angle1;
        else return angle2 - angle1 - 2 * PI;
      } else {
        if (angle1 > angle2) return angle2 - angle1 + 2 * PI;
        else return angle2 - angle1;
      }
    }
  }
예제 #5
0
  /*
   * (non-Javadoc)
   *
   * @see math.geom2d.Curve2D#intersections(math.geom2d.LinearShape2D)
   */
  public Collection<Point2D> intersections(LinearShape2D line) {

    // check point contained in it
    ArrayList<Point2D> array = new ArrayList<Point2D>();
    for (Point2D point : ellipse.intersections(line)) if (contains(point)) array.add(point);

    return array;
  }
예제 #6
0
  /*
   * (non-Javadoc)
   *
   * @see math.geom2d.Curve2D#position(math.geom2d.Point2D)
   */
  public double position(Point2D point) {
    double angle = Angle2D.horizontalAngle(ellipse.center(), point);
    if (this.containsAngle(angle))
      if (angleExtent > 0) return Angle2D.formatAngle(angle - startAngle);
      else return Angle2D.formatAngle(startAngle - angle);

    // If the point is not contained in the arc, return NaN.
    return Double.NaN;
  }
예제 #7
0
  /*
   * (non-Javadoc)
   *
   * @see math.geom2d.Curve2D#point(double, math.geom2d.Point2D)
   */
  public Point2D point(double t) {
    // check bounds
    t = max(t, 0);
    t = min(t, abs(angleExtent));

    // convert position to angle
    if (angleExtent < 0) t = startAngle - t;
    else t = startAngle + t;

    // return corresponding point
    return ellipse.point(t);
  }
예제 #8
0
 @Override
 public String toString() {
   Point2D center = ellipse.center();
   return String.format(
       Locale.US,
       "EllipseArc2D(%7.2f,%7.2f,%7.2f,%7.2f,%7.5f,%7.5f,%7.5f)",
       center.x(),
       center.y(),
       ellipse.r1,
       ellipse.r2,
       ellipse.theta,
       startAngle,
       angleExtent);
 }
예제 #9
0
  public double project(Point2D point) {
    double angle = ellipse.project(point);

    // Case of an angle contained in the ellipse arc
    if (this.containsAngle(angle)) {
      if (angleExtent > 0) return Angle2D.formatAngle(angle - startAngle);
      else return Angle2D.formatAngle(startAngle - angle);
    }

    // return either 0 or T1, depending on which extremity is closer.
    double d1 = this.firstPoint().distance(point);
    double d2 = this.lastPoint().distance(point);
    return d1 < d2 ? 0 : abs(angleExtent);
  }
예제 #10
0
  /*
   * (non-Javadoc)
   *
   * @see math.geom2d.Shape2D#transform(math.geom2d.AffineTransform2D)
   */
  public EllipseArc2D transform(AffineTransform2D trans) {
    // transform supporting ellipse
    Ellipse2D ell = ellipse.transform(trans);

    // ensure ellipse is direct
    if (!ell.isDirect()) ell = ell.reverse();

    // Compute position of end points on the transformed ellipse
    double startPos = ell.project(this.firstPoint().transform(trans));
    double endPos = ell.project(this.lastPoint().transform(trans));

    // Compute the new arc
    boolean direct = !(angleExtent > 0 ^ trans.isDirect());
    return new EllipseArc2D(ell, startPos, endPos, direct);
  }
예제 #11
0
  public Box2D boundingBox() {

    // first get ending points
    Point2D p0 = firstPoint();
    Point2D p1 = lastPoint();

    // get coordinate of ending points
    double x0 = p0.x();
    double y0 = p0.y();
    double x1 = p1.x();
    double y1 = p1.y();

    // initialize min and max coords
    double xmin = min(x0, x1);
    double xmax = max(x0, x1);
    double ymin = min(y0, y1);
    double ymax = max(y0, y1);

    // precomputes some values
    Point2D center = ellipse.center();
    double xc = center.x();
    double yc = center.y();
    double endAngle = startAngle + angleExtent;
    boolean direct = angleExtent >= 0;

    // check cases arc contains one maximum
    if (Angle2D.containsAngle(startAngle, endAngle, PI / 2 + ellipse.theta, direct))
      ymax = max(ymax, yc + ellipse.r1);
    if (Angle2D.containsAngle(startAngle, endAngle, 3 * PI / 2 + ellipse.theta, direct))
      ymin = min(ymin, yc - ellipse.r1);
    if (Angle2D.containsAngle(startAngle, endAngle, ellipse.theta, direct))
      xmax = max(xmax, xc + ellipse.r2);
    if (Angle2D.containsAngle(startAngle, endAngle, PI + ellipse.theta, direct))
      xmin = min(xmin, xc - ellipse.r2);

    // return a bounding with computed limits
    return new Box2D(xmin, xmax, ymin, ymax);
  }