package org.geogebra.common.kernel.barycentric;
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.GeoElement;
import org.geogebra.common.kernel.geos.GeoNumberValue;
import org.geogebra.common.kernel.geos.GeoPoint;
import org.geogebra.common.kernel.kernelND.GeoPointND;
import org.geogebra.common.main.AlgoKimberlingWeightsParams;
import org.geogebra.common.util.MyMath;
/**
* @author Zbynek Konecny, credit goes to Jason Cantarella of the Univerity of
* Georgia for creating a perl script which was used to create this
* class.
* @version 30-09-2011
*
* This class calculates n-th Kimberling center of a triangle.
*
*/
public class AlgoKimberling extends AlgoElement {
private GeoPointND A, B, C; // input
private GeoPointND M; // output
private GeoNumberValue n;
/**
* Creates new algo for triangle center
*
* @param cons
* construction
* @param label
* label
* @param A
* first point
* @param B
* second point
* @param C
* third point
* @param n
* index in ETC
*/
public AlgoKimberling(Construction cons, String label, GeoPointND A,
GeoPointND B, GeoPointND C, GeoNumberValue n) {
super(cons);
kernel.getApplication().getAlgoKimberlingWeights();
this.A = A;
this.B = B;
this.C = C;
this.n = n;
int dim = MyMath.max(A.getDimension(), B.getDimension(),
C.getDimension());
M = kernel.getGeoFactory().newPoint(dim, cons);
setInputOutput();
compute();
M.setLabel(label);
}
@Override
public Commands getClassName() {
return Commands.TriangleCenter;
}
// for AlgoElement
@Override
protected void setInputOutput() {
input = new GeoElement[4];
input[0] = A.toGeoElement();
input[1] = B.toGeoElement();
input[2] = C.toGeoElement();
input[3] = n.toGeoElement();
setOutputLength(1);
setOutput(0, M.toGeoElement());
setDependencies(); // done by AlgoElement
}
/**
* @return resulting point
*/
public GeoPointND getResult() {
return M;
}
@Override
public final void compute() {
// Check if the points are aligned
double c = A.distance(B);
double b = C.distance(A);
double a = B.distance(C);
double m = Math.min(Math.min(a, b), c);
a = a / m;
b = b / m;
c = c / m;
int k = (int) n.getDouble();
if (kernel.getApplication().getAlgoKimberlingWeights() == null) {
M.setUndefined();
} else {
double wA = kernel.getApplication().kimberlingWeight(
new AlgoKimberlingWeightsParams(k, a, b, c));
double wB = kernel.getApplication().kimberlingWeight(
new AlgoKimberlingWeightsParams(k, b, c, a));
double wC = kernel.getApplication().kimberlingWeight(
new AlgoKimberlingWeightsParams(k, c, a, b));
double w = wA + wB + wC;
if (Double.isNaN(w) || Kernel.isZero(w)) {
M.setUndefined();
} else {
GeoPoint.setBarycentric(A, B, C, wA, wB, wC, w, M);
}
}
}
}