Exemplo n.º 1
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);
    }
  }