예제 #1
0
  /**
   * Calculate dx, dy values for a point
   *
   * @param t : parameter
   * @param delta : where to store dx, dy values
   */
  private void calcTangentAt(double t, FPoint2 delta) {
    final boolean db = false;
    if (db) {
      System.out.println("calcTangentAt " + t);
    }
    t = toInt(t);
    if (db) {
      System.out.println(" flipped=" + flipped() + " ti=" + t);
    }
    double a = toW2.get(0, 0), b = toW2.get(0, 1), c = toW2.get(0, 2);
    double d = toW2.get(1, 0), e = toW2.get(1, 1), f = toW2.get(1, 2);
    if (db) {
      System.out.println(" a=" + a + " b=" + b + " c=" + c + "\n d=" + d + " e=" + e + " f=" + f);
    }
    double rt = Polyn.sqrt(A + B * t * t);
    double dx = a * B * t / rt + b;
    double dy = d * B * t / rt + e;

    if (flipped()) {
      dx = -dx;
      dy = -dy;
    }
    if (db) {
      System.out.println(" dx=" + dx + "\n dy=" + dy);
      System.out.println(" ratio=" + (dy / dx));
    }
    delta.setLocation(dx, dy);
  }
예제 #2
0
  /**
   * Calculate a point on the hyperbola
   *
   * @param t : parameter in internal space (after flipping has occurred)
   * @param dest : where to store the calculated point
   */
  private FPoint2 calcPointInternal(double t, FPoint2 dest) {
    final boolean db = false;
    if (!valid) throw new FPError("calcPoint of invalid hyperbola");

    //    Tools.ASSERT(valid, "calcPoint of invalid hyperbola");
    //    final FPoint2 work = new FPoint2();
    //
    //    work.setLocation(Polyn.sqrt(A + t * t * B), t);
    dest = toW2.apply(Polyn.sqrt(A + t * t * B), t, dest);
    //
    //    if (dest == null)
    //      dest = new FPoint2();
    //    Matrix.apply(toW2, work, dest);
    if (db) {
      System.out.println(
          "calcPoint t="
              + Tools.f(toExt(t)) // + " armsp=" + work
              + " world="
              + dest);
    }
    return dest;
  }
예제 #3
0
 /**
  * Calculate a point on the hyperbola, leave in arm space
  *
  * @param t : parameter, after conversion to 'internal' value
  * @return point in arm space
  */
 private FPoint2 calcPointInArmSpace0(double t) {
   return new FPoint2(Polyn.sqrt(A + t * t * B), t);
 }
예제 #4
0
  /**
   * Constructor
   *
   * @param f1 FPoint2
   * @param f2 FPoint2
   * @param pt FPoint2, or null for bisector
   */
  private void construct(FPoint2 f1, FPoint2 f2, FPoint2 pt) {

    //    userData[LEFT] = new DArray();
    //    userData[RIGHT]  =new DArray();

    final boolean db = false;
    if (db) {
      System.out.println("Hyperbola constructor\n f1=" + f1 + "\n f2=" + f2 + "\n pt=" + pt);
    }
    boolean bisector = (pt == null);
    initializeVisibleSegments();

    // if point on arm is closer to f2 than f1, swap f1 & f2.

    if (!bisector && FPoint2.distanceSquared(f1, pt) > FPoint2.distanceSquared(f2, pt)) {
      flipped = true;
    }

    this.foci[RIGHT] = new FPoint2(f1);
    this.foci[LEFT] = new FPoint2(f2);
    if (!bisector) {
      this.pt = new FPoint2(pt);
    }

    double fociDist = FPoint2.distance(f1, f2);
    if (fociDist == 0) {
      throw new FPError("Hyperbola foci are same point");
    }

    c = fociDist * .5;

    // calculate the translation of the hyperbola away from
    // standard position.

    FPoint2 rFocus = getFocus(0), lFocus = getFocus(1);

    origin = new FPoint2(.5 * (rFocus.x + lFocus.x), .5 * (rFocus.y + lFocus.y));

    // calculate the angle of rotation of the hyperbola away
    // from the standard position.

    double theta = Math.atan2(rFocus.y - lFocus.y, rFocus.x - lFocus.x);

    Matrix fromCenterInW = Matrix.getTranslate(origin, true);
    Matrix rotToE = Matrix.getRotate(-theta);

    toE2 = rotToE;
    Matrix.mult(toE2, fromCenterInW, toE2);
    // calculate inverse

    toW2 = toE2.invert(null);

    //      Matrix toCenterInW = Matrix.translationMatrix(origin, false);
    //      Matrix rotToW = Matrix.getRotate2D(theta);
    //
    //      toW2 = toCenterInW;
    //      Matrix.mult(toW2, rotToW, toW2);
    //      Tools.warn("just invert matrix here");
    //

    if (bisector) {
      valid = true;
    } else {
      // get the arm point in hyperbola space.
      FPoint2 workPt = toE2.apply(pt, null);

      double xs = workPt.x * workPt.x;
      double cs = c * c;

      Polyn q = new Polyn(1, -(cs + xs + workPt.y * workPt.y), cs * xs);
      if (db) {
        System.out.println("a2 quadratic:\n" + q);
      }
      final DArray qsoln = new DArray();
      q.solve(qsoln);
      if (db) {
        Streams.out.println(qsoln);
      }
      double val = q.c(1) * -.5;
      int ql = qsoln.size();
      if (ql >= 1) {
        val = qsoln.getDouble(0);
      }

      // choose the root that is less than c*c.

      if (ql == 2) {
        if (val > qsoln.getDouble(1)) {
          val = qsoln.getDouble(1);
          if (db) {
            System.out.println(" two roots, choosing smaller.");
          }
        }
      }
      if (db) {
        System.out.println(" root chosen=" + val);
      }

      a = Polyn.sqrt(val);
      A = a * a;
      B = A / (c * c - A);
    }
    valid = true;
    if (db) {
      System.out.println(" ==> " + this);
    }
  }