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.arithmetic.Equation; import org.geogebra.common.kernel.arithmetic.ExpressionNode; import org.geogebra.common.kernel.arithmetic.ExpressionNodeConstants; import org.geogebra.common.kernel.arithmetic.FunctionVariable; import org.geogebra.common.kernel.arithmetic.Traversing.Replacer; import org.geogebra.common.kernel.commands.Commands; 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.implicit.AlgoDependentImplicitPoly; import org.geogebra.common.kernel.implicit.GeoImplicit; import org.geogebra.common.plugin.Operation; /** * @author Darko Drakulic * @version 23-10-2011 * * This class makes a curve in barycentric coordinates * */ public class AlgoTriangleCurve extends AlgoElement implements ExpressionNodeConstants { private GeoPoint A, B, C; // input private GeoImplicit n; // number of curve private GeoElement poly; // output private Equation eq; private GeoNumeric[] xcoef, ycoef, constant; private AlgoDependentImplicitPoly dd; /** * @param cons * construction * @param label * label * @param A * first point * @param B * second point * @param C * third point * @param e * equation in A,B,C * @param a * variable "A" * @param b * variable "B" * @param c * variable "C" */ public AlgoTriangleCurve(Construction cons, String label, GeoPoint A, GeoPoint B, GeoPoint C, GeoImplicit e, GeoNumeric a, GeoNumeric b, GeoNumeric c) { super(cons); this.A = A; this.B = B; this.C = C; this.n = e; AlgoElement d = n.getParentAlgorithm(); cons.removeFromConstructionList(d); ExpressionNode lhs = ((AlgoDependentImplicitPoly) d).getEquation() .getLHS() .deepCopy(kernel); ExpressionNode rhs = ((AlgoDependentImplicitPoly) d).getEquation() .getRHS() .deepCopy(kernel); ExpressionNode[] abcExp = new ExpressionNode[3]; FunctionVariable x = new FunctionVariable(kernel, "x"); FunctionVariable y = new FunctionVariable(kernel, "y"); xcoef = new GeoNumeric[3]; ycoef = new GeoNumeric[3]; constant = new GeoNumeric[3]; for (int i = 0; i < 3; i++) { xcoef[i] = new GeoNumeric(cons); ycoef[i] = new GeoNumeric(cons); constant[i] = new GeoNumeric(cons); abcExp[i] = new ExpressionNode(kernel, new ExpressionNode(kernel, new ExpressionNode(kernel, xcoef[i], Operation.MULTIPLY, x), Operation.PLUS, new ExpressionNode(kernel, ycoef[i], Operation.MULTIPLY, y)), Operation.PLUS, constant[i]); } eq = new Equation(kernel, lhs, rhs); eq.traverse(Replacer.getReplacer(a, abcExp[0])); eq.traverse(Replacer.getReplacer(b, abcExp[1])); eq.traverse(Replacer.getReplacer(c, abcExp[2])); eq.setForceImplicitPoly(); eq.initEquation(); boolean flag = cons.isSuppressLabelsActive(); dd = new AlgoDependentImplicitPoly(cons, eq, eq.wrap(), false); cons.removeFromConstructionList(dd); poly = ((AlgoElement) dd).getOutput()[0]; setInputOutput(); compute(); cons.setSuppressLabelCreation(flag); poly.setLabel(label); } @Override public Commands getClassName() { return Commands.TriangleCurve; } // for AlgoElement @Override protected void setInputOutput() { input = new GeoElement[4]; input[0] = A; input[1] = B; input[2] = C; input[3] = n.toGeoElement(); setOutputLength(1); setOutput(0, poly); setDependencies(); // done ycoef[1] AlgoElement } /** * @return resulting implicit polynomial */ public GeoElement getResult() { return poly; } @Override public final void compute() { // Check if the points are aligned double x1 = -A.inhomX; double y1 = -A.inhomY; double x2 = -B.inhomX; double y2 = -B.inhomY; double x3 = -C.inhomX; double y3 = -C.inhomY; double det = (x2 - x3) * (y1 - y3) + (x3 - x1) * (y2 - y3); if (Kernel.isZero(det)) { poly.setUndefined(); } else { ycoef[0].setValue((x3 - x2) / det); xcoef[0].setValue((y2 - y3) / det); constant[0].setValue(((x3 - x2) * y3 + (y2 - y3) * x3) / det); ycoef[1].setValue((x1 - x3) / det); xcoef[1].setValue((y3 - y1) / det); constant[1].setValue(((x1 - x3) * y1 + (y3 - y1) * x1) / det); ycoef[2].setValue((x2 - x1) / det); xcoef[2].setValue((y1 - y2) / det); constant[2].setValue(((x2 - x1) * y2 + (y1 - y2) * x2) / det); ((AlgoElement) dd).update(); poly.update(); } } }