// calc tangent at x=a
  public final void compute() {
    if (!(f.isDefined() && P.isDefined() && deriv.isDefined())) {
      tangent.setUndefined();
      return;
    }

    // calc the tangent;
    double a = P.inhomX;
    double fa = f.evaluate(a);
    double slope = deriv.evaluate(a);
    tangent.setCoords(-slope, 1.0, a * slope - fa);

    if (!pointOnFunction) T.setCoords(a, fa, 1.0);
  }
  // calc axes
  @Override
  public final void compute() {
    // only parabola has directrix
    if (c.type == GeoConicNDConstants.CONIC_PARABOLA) {
      // directrix has direction of second eigenvector
      // through point (b - p/2* eigenvec1)
      directrix.x = -eigenvec[1].getY();
      directrix.y = eigenvec[1].getX();
      double px = b.getX() - c.p / 2.0 * eigenvec[0].getX();
      double py = b.getY() - c.p / 2.0 * eigenvec[0].getY();
      directrix.z = -(directrix.x * px + directrix.y * py);

      P.setCoords(px, py, 1.0);
    } else directrix.setUndefined();
  }
  public AlgoDirectrix(Construction cons, String label, GeoConic c) {
    super(cons);
    this.c = c;

    eigenvec = c.eigenvec;
    b = c.b;

    directrix = new GeoLine(cons);
    P = new GeoPoint(cons);
    directrix.setStartPoint(P);

    setInputOutput(); // for AlgoElement
    compute();
    directrix.setLabel(label);
  }
  public AlgoTangentFunctionPoint(Construction cons, GeoPoint2 P, GeoFunction f) {
    super(cons);
    this.P = P;
    this.f = f;

    tangent = new GeoLine(cons);

    // check if P is defined as a point of the function's graph
    pointOnFunction = false;
    if (P.getParentAlgorithm() instanceof AlgoPointOnPath) {
      AlgoPointOnPath algo = (AlgoPointOnPath) P.getParentAlgorithm();
      pointOnFunction = algo.getPath() == f;
    }

    if (pointOnFunction) T = P;
    else T = new GeoPoint2(cons);
    tangent.setStartPoint(T);

    // derivative of f
    algoCAS = new AlgoDerivative(cons, f);
    deriv = (GeoFunction) ((AlgoDerivative) algoCAS).getResult();
    cons.removeFromConstructionList(algoCAS);

    setInputOutput(); // for AlgoElement
    compute();
  }
 /**
  * Set the end point of the wrapped GeoLine
  *
  * @param point the new end point
  */
 public static void setEndPoint(GeoLine geo, GeoPoint point) {
   geo.setEndPoint(point);
 }
 /** @return the end point of the wrapped GeoLine */
 public static GeoPoint getEndPoint(GeoLine geo) {
   return geo.getEndPoint();
 }
 /** @return the start point of the wrapped geoLine */
 public static GeoPoint getStartPoint(GeoLine geo) {
   return geo.getStartPoint();
 }
 public AlgoTangentFunctionPoint(Construction cons, String label, GeoPoint2 P, GeoFunction f) {
   this(cons, P, f);
   tangent.setLabel(label);
 }