Example #1
0
  // calc axes
  protected final void compute() {
    // only parabola has directrix
    if (c.type == GeoConic.CONIC_PARABOLA) {
      // directrix has direction of second eigenvector
      // through point (b - p/2* eigenvec1)
      directrix.x = -eigenvec[1].y;
      directrix.y = eigenvec[1].x;
      double px = b.x - c.p / 2.0 * eigenvec[0].x;
      double py = b.y - c.p / 2.0 * eigenvec[0].y;
      directrix.z = -(directrix.x * px + directrix.y * py);

      P.setCoords(px, py, 1.0);
    } else directrix.setUndefined();
  }
  // compute circle through A, B, C
  protected void compute() {
    // A, B or C undefined
    if (!getA().isFinite() || !getB().isFinite() || !getC().isFinite()) {
      circle.setUndefined();
      return;
    }

    // get inhomogenous coords of points
    ax = ((GeoPoint) getA()).inhomX;
    ay = ((GeoPoint) getA()).inhomY;
    bx = ((GeoPoint) getB()).inhomX;
    by = ((GeoPoint) getB()).inhomY;
    cx = ((GeoPoint) getC()).inhomX;
    cy = ((GeoPoint) getC()).inhomY;

    // A = B = C
    if (kernel.isEqual(ax, bx)
        && kernel.isEqual(ax, cx)
        && kernel.isEqual(ay, by)
        && kernel.isEqual(ay, cy)) {
      circle.setCircle((GeoPoint) getA(), 0.0); // single point
      return;
    }

    // calc vectors AB, AC, BC
    ABx = bx - ax;
    ABy = by - ay;
    ACx = cx - ax;
    ACy = cy - ay;
    BCx = cx - bx;
    BCy = cy - by;

    double lengthAB = GeoVec2D.length(ABx, ABy);
    double lengthAC = GeoVec2D.length(ACx, ACy);
    double lengthBC = GeoVec2D.length(BCx, BCy);

    // find the two bisectors with max intersection angle
    // i.e. maximum abs of determinant of directions
    // max( abs(det(AB, AC)), abs(det(AC, BC)), abs(det(AB, BC)) )
    det[0] = Math.abs(ABx * ACy - ABy * ACx) / (lengthAB * lengthAC);
    // AB, AC
    det[1] = Math.abs(ACx * BCy - ACy * BCx) / (lengthAC * lengthBC);
    // AC, BC
    det[2] = Math.abs(ABx * BCy - ABy * BCx) / (lengthAB * lengthBC);
    // AB, BC

    // take ip[0] as init minimum and find minimum case
    maxDet = det[0];
    casenr = 0;
    if (det[1] > maxDet) {
      casenr = 1;
      maxDet = det[1];
    }
    if (det[2] > maxDet) {
      casenr = 2;
      maxDet = det[2];
    }

    // A, B, C are collinear: set M to infinite point
    // in perpendicular direction of AB
    if (kernel.isZero(maxDet)) {
      center.setCoords(-ABy, ABx, 0.0d);
      circle.setCircle(center, (GeoPoint) getA());
    }
    // standard case
    else {
      // intersect two line bisectors according to casenr
      switch (casenr) {
        case 0: // bisectors of AB, AC
          s0.x = ABx;
          s0.y = ABy;
          s0.z = -((ax + bx) * s0.x + (ay + by) * s0.y) / 2.0;

          s1.x = ACx;
          s1.y = ACy;
          s1.z = -((ax + cx) * s1.x + (ay + cy) * s1.y) / 2.0;
          break;

        case 1: // bisectors of AC, BC
          s1.x = ACx;
          s1.y = ACy;
          s1.z = -((ax + cx) * s1.x + (ay + cy) * s1.y) / 2.0;

          s0.x = BCx;
          s0.y = BCy;
          s0.z = -((bx + cx) * s0.x + (by + cy) * s0.y) / 2.0;
          break;

        case 2: // bisectors of AB, BC
          s0.x = ABx;
          s0.y = ABy;
          s0.z = -((ax + bx) * s0.x + (ay + by) * s0.y) / 2.0;

          s1.x = BCx;
          s1.y = BCy;
          s1.z = -((bx + cx) * s1.x + (by + cy) * s1.y) / 2.0;
          break;
      }

      // intersect line bisectors to get midpoint
      GeoVec3D.cross(s0, s1, center);
      circle.setCircle(center, center.distance(getA()));
    }
  }