package org.geogebra.common.kernel.advanced;
import org.geogebra.common.kernel.Construction;
import org.geogebra.common.kernel.Kernel;
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.GeoElement;
import org.geogebra.common.kernel.geos.GeoFunction;
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 function 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 AlgoOsculatingCircle extends AlgoElement {
private GeoPoint A, R; // input A
private GeoFunction 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
AlgoCurvature algo;
AlgoCurvatureVector cv;
public AlgoOsculatingCircle(Construction cons, String label, GeoPoint A,
GeoFunction f) {
this(cons, A, f);
circle.setLabel(label);
}
public AlgoOsculatingCircle(Construction cons, GeoPoint A, GeoFunction 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 AlgoCurvature(cons, A, f);
cv = new AlgoCurvatureVector(cons, A, f);
curv = algo.getResult();
v = cv.getVector();
cons.removeFromConstructionList(algo);
cons.removeFromConstructionList(cv);
cons.removeFromAlgorithmList(algo);
cons.removeFromAlgorithmList(cv);
setInputOutput();
compute();
}
@Override
public Commands getClassName() {
return Commands.OsculatingCircle;
}
// for AlgoElement
@Override
protected void setInputOutput() {
input = new GeoElement[2];
input[0] = A;
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() {
// bugfix Michael Borcherds
// undefined unless A is a point on f
if (!f.isOnPath(A, Kernel.MIN_PRECISION)) {
circle.setUndefined();
return;
}
double radius = 1 / Math.abs(curv.getValue());
double r2 = radius * radius;
double x = r2 * v.x;
double y = r2 * v.y;
R.setCoords(A.inhomX + x, A.inhomY + 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();
}
}