/* GeoGebra - Dynamic Mathematics for Everyone http://www.geogebra.org This file is part of GeoGebra. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation. */ /* * AlgoDependentConic.java * * Created on 29. Oktober 2001 */ package org.geogebra.common.kernel.algos; import org.geogebra.common.kernel.Construction; import org.geogebra.common.kernel.StringTemplate; import org.geogebra.common.kernel.arithmetic.Equation; import org.geogebra.common.kernel.arithmetic.ExpressionNode; import org.geogebra.common.kernel.arithmetic.ExpressionValue; import org.geogebra.common.kernel.arithmetic.Inspecting; import org.geogebra.common.kernel.arithmetic.NumberValue; import org.geogebra.common.kernel.arithmetic.Polynomial; import org.geogebra.common.kernel.geos.GeoConic; import org.geogebra.common.kernel.geos.GeoPoint; /** * * @author Markus */ public class AlgoDependentConic extends AlgoElement implements EvaluateAtPoint, DependentAlgo { private Equation equation; private ExpressionValue[] ev = new ExpressionValue[6]; // input private GeoConic conic; // output /** * Creates new AlgoDependentConic * * @param cons * construction * @param equ * conic equation */ public AlgoDependentConic(Construction cons, Equation equ) { super(cons, false); // don't add to construction list yet equation = equ; Polynomial lhs = equ.getNormalForm(); ev[0] = lhs.getCoefficient("xx"); ev[1] = lhs.getCoefficient("xy"); ev[2] = lhs.getCoefficient("yy"); ev[3] = lhs.getCoefficient("x"); ev[4] = lhs.getCoefficient("y"); ev[5] = lhs.getConstantCoefficient(); // check coefficients for (int i = 0; i < 6; i++) { // find constant parts of input and evaluate them right now if (!ev[i].inspect(Inspecting.dynamicGeosFinder)) { ev[i] = ev[i].evaluate(StringTemplate.defaultTemplate); } // check that coefficient is a number: this may throw an exception ExpressionValue eval = ev[i] .evaluate(StringTemplate.defaultTemplate); ((NumberValue) eval).getDouble(); } // if we get here, all is ok: let's add this algorithm to the // construction list cons.addToConstructionList(this, false); conic = new GeoConic(cons); setInputOutput(); // for AlgoElement // compute value of dependent number compute(); } @Override public Algos getClassName() { return Algos.Expression; } // for AlgoElement @Override protected void setInputOutput() { input = equation.getGeoElementVariables(); super.setOutputLength(1); super.setOutput(0, conic); setDependencies(); // done by AlgoElement } /** * @return conic */ public GeoConic getConic() { return conic; } // calc the current value of the arithmetic tree @Override public final void compute() { try { ExpressionNode def = conic.getDefinition(); conic.setCoeffs(ev[0].evaluateDouble(), ev[1].evaluateDouble(), ev[2].evaluateDouble(), ev[3].evaluateDouble(), ev[4].evaluateDouble(), ev[5].evaluateDouble()); conic.setDefinition(def); } catch (Throwable e) { conic.setUndefined(); } } @Override final public double evaluate(GeoPoint P) { double mat0 = ev[0].evaluateDouble(); // x\u00b2 double mat1 = ev[2].evaluateDouble(); // y\u00b2 double mat2 = ev[5].evaluateDouble(); // constant double mat3 = ev[1].evaluateDouble() / 2.0; // xy double mat4 = ev[3].evaluateDouble() / 2.0; // x double mat5 = ev[4].evaluateDouble() / 2.0; return P.x * (mat0 * P.x + mat3 * P.y + mat4 * P.z) + P.y * (mat3 * P.x + mat1 * P.y + mat5 * P.z) + P.z * (mat4 * P.x + mat5 * P.y + mat2 * P.z); } @Override public final String toString(StringTemplate tpl) { if (conic.getDefinition() != null) { return conic.getDefinition().toString(tpl); } return equation.toString(tpl); } @Override public ExpressionNode getExpression() { return equation.wrap(); } }