package org.geogebra.common.kernel.advanced; import org.geogebra.common.kernel.Construction; import org.geogebra.common.kernel.Kernel; import org.geogebra.common.kernel.Matrix.Coords; import org.geogebra.common.kernel.algos.AlgoElement; import org.geogebra.common.kernel.commands.Commands; import org.geogebra.common.kernel.geos.GeoConic; import org.geogebra.common.kernel.geos.GeoCurveCartesian; import org.geogebra.common.kernel.geos.GeoElement; import org.geogebra.common.kernel.geos.GeoNumeric; import org.geogebra.common.kernel.geos.GeoPoint; import org.geogebra.common.kernel.geos.GeoVector; /** * @author Victor Franco Espino * @version 11-02-2007 * * Osculating Circle of a curve f in point A: center = A + (radius)^2 * * v radius = 1/abs(k(x)), k(x)=curvature of f v = curvature vector of * f in point A */ public class AlgoOsculatingCircleCurve extends AlgoElement { private GeoPoint A, R;// input A private GeoCurveCartesian f;// input private GeoVector v;// curvature vector of f in point A private GeoNumeric curv;// curvature of f in point A private GeoConic circle; // output private GeoConic gc = null; AlgoCurvatureCurve algo; AlgoCurvatureVectorCurve cv; public AlgoOsculatingCircleCurve(Construction cons, String label, GeoPoint A, GeoCurveCartesian f) { super(cons); this.A = A; this.f = f; R = new GeoPoint(cons);// R is the center of the circle circle = new GeoConic(cons); // Catch curvature and curvature vector algo = new AlgoCurvatureCurve(cons, A, f); cv = new AlgoCurvatureVectorCurve(cons, A, f); curv = algo.getResult(); v = cv.getVector(); cons.removeFromConstructionList(algo); cons.removeFromConstructionList(cv); setInputOutput(); compute(); circle.setLabel(label); } public AlgoOsculatingCircleCurve(Construction cons, String label, GeoPoint A, GeoConic geoConic) { super(cons); this.A = A; gc = geoConic; R = new GeoPoint(cons);// R is the center of the circle circle = new GeoConic(cons); // Catch curvature and curvature vector algo = new AlgoCurvatureCurve(cons, A, gc); cv = new AlgoCurvatureVectorCurve(cons, A, gc); curv = algo.getResult(); v = cv.getVector(); cons.removeFromConstructionList(algo); cons.removeFromConstructionList(cv); setInputOutput(); compute(); circle.setLabel(label); } @Override public Commands getClassName() { return Commands.OsculatingCircle; } // for AlgoElement @Override protected void setInputOutput() { input = new GeoElement[2]; input[0] = A; if (gc != null) { input[1] = gc; } else { input[1] = f; } super.setOutputLength(1); super.setOutput(0, circle); setDependencies(); // done by AlgoElement } // Return the resultant circle public GeoConic getCircle() { return circle; } @Override public final void compute() { // undefined unless A is a point on f if (gc == null && !f.isOnPath(A, Kernel.MIN_PRECISION)) { circle.setUndefined(); return; } if (gc != null) { if (!gc.isOnPath(A, Kernel.MIN_PRECISION)) { circle.setUndefined(); return; } // Catch curvature and curvature vector algo.compute(); cv.compute(); curv = algo.getResult(); v = cv.getVector(); } // bugfix Michael Borcherds double radius = 1 / Math.abs(curv.getValue()); double r2 = radius * radius; double x = r2 * v.x; double y = r2 * v.y; Coords coords = A.getCoordsInD2(); double ax = coords.getX() / coords.getZ(); double ay = coords.getY() / coords.getZ(); R.setCoords(ax + x, ay + y, 1.0); circle.setCircle(R, A); } @Override public void remove() { if (removed) { return; } super.remove(); f.removeAlgorithm(algo); f.removeAlgorithm(cv); A.removeAlgorithm(algo); A.removeAlgorithm(cv); // make sure all AlgoCASDerivatives get removed cv.remove(); } }