AlgoTangentCurve(Construction cons, String label, GeoPoint P, GeoCurveCartesian f) {
    super(cons);
    this.P = P;
    this.f = f;
    tangent = new GeoLine(cons);

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

    if (pointOnCurve) T = P;
    else T = new GeoPoint(cons);
    tangent.setStartPoint(T);

    // First derivative of curve f
    AlgoDerivative algo = new AlgoDerivative(cons, f);
    this.df = (GeoCurveCartesian) algo.getDerivative();

    cons.removeFromConstructionList(algo);
    setInputOutput(); // for AlgoElement
    compute();
    tangent.setLabel(label);
  }
  /**
   * @param cons construction
   * @param label label for output
   * @param n function parameter
   * @param f function
   */
  public AlgoTangentFunctionNumber(Construction cons, String label, NumberValue n, GeoFunction f) {
    super(cons);
    this.n = n;
    ngeo = n.toGeoElement();
    this.f = f;

    tangent = new GeoLine(cons);
    T = new GeoPoint(cons);
    tangent.setStartPoint(T);

    // derivative of f
    // now uses special non-CAS version of algo
    algo = new AlgoDerivative(cons, f, true);
    deriv = (GeoFunction) algo.getResult();
    cons.removeFromConstructionList(algo);

    setInputOutput(); // for AlgoElement
    compute();
    tangent.setLabel(label);
  }