package org.geogebra.common.kernel.advanced; import org.geogebra.common.kernel.CircularDefinitionException; import org.geogebra.common.kernel.Construction; import org.geogebra.common.kernel.algos.AlgoElement; import org.geogebra.common.kernel.cas.AlgoDerivative; import org.geogebra.common.kernel.commands.Commands; import org.geogebra.common.kernel.commands.EvalInfo; import org.geogebra.common.kernel.geos.GeoElement; import org.geogebra.common.kernel.geos.GeoFunction; import org.geogebra.common.kernel.geos.GeoPoint; import org.geogebra.common.kernel.geos.GeoVector; /** * @author Victor Franco Espino * @version 11-02-2007 * * Calculate Curvature Vector for function: c(x) = * (1/T^4)*(-f'*f'',f''), T = sqrt(1+(f')^2) */ public class AlgoCurvatureVector extends AlgoElement { private GeoPoint A; // input private GeoFunction f, f1, f2; // f = f(x), f1 is f'(x), f2 is f''(x) private GeoVector v; // output AlgoDerivative algoCAS, algoCAS2; public AlgoCurvatureVector(Construction cons, String label, GeoPoint A, GeoFunction f) { this(cons, A, f); if (label != null) { v.setLabel(label); } else { // if we don't have a label we could try c v.setLabel("c"); } } AlgoCurvatureVector(Construction cons, GeoPoint A, GeoFunction f) { super(cons); this.A = A; this.f = f; // create new vector v = new GeoVector(cons); try { v.setStartPoint(A); } catch (CircularDefinitionException e) { } EvalInfo info = new EvalInfo(false); // First derivative of function f algoCAS = new AlgoDerivative(cons, f, info); cons.removeFromConstructionList(algoCAS); this.f1 = (GeoFunction) algoCAS.getResult(); // Second derivative of function f algoCAS2 = new AlgoDerivative(cons, f1, info); cons.removeFromConstructionList(algoCAS2); this.f2 = (GeoFunction) algoCAS2.getResult(); setInputOutput(); compute(); } @Override public Commands getClassName() { return Commands.CurvatureVector; } // for AlgoElement @Override protected void setInputOutput() { input = new GeoElement[2]; input[0] = A; input[1] = f; super.setOutputLength(1); super.setOutput(0, v); setDependencies(); // done by AlgoElement } // Return the resultant vector public GeoVector getVector() { return v; } @Override public final void compute() { try { double f1eval = f1.value(A.inhomX); double f2eval = f2.value(A.inhomX); double t = Math.sqrt(1 + f1eval * f1eval); double t4 = t * t * t * t; double x = A.inhomX - (f1eval * f2eval) / t4; double y = A.inhomY + f2eval / t4; v.x = x - A.inhomX; v.y = y - A.inhomY; v.z = 0.0; } catch (Exception e) { // in case something went wrong, e.g. derivatives not defined v.setUndefined(); } } @Override public void remove() { if (removed) { return; } super.remove(); A.removeAlgorithm(algoCAS); f.removeAlgorithm(algoCAS); A.removeAlgorithm(algoCAS2); f.removeAlgorithm(algoCAS2); } }