/* 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. */ /* * AlgoDependentPoint.java * * Created on 30. August 2001, 21:37 */ package org.geogebra.common.kernel.algos; import org.geogebra.common.kernel.Construction; import org.geogebra.common.kernel.Kernel; import org.geogebra.common.kernel.StringTemplate; import org.geogebra.common.kernel.arithmetic.ExpressionNode; import org.geogebra.common.kernel.arithmetic.VectorValue; import org.geogebra.common.kernel.geos.GeoElement; import org.geogebra.common.kernel.geos.GeoPoint; import org.geogebra.common.kernel.geos.GeoVec2D; import org.geogebra.common.kernel.geos.GeoVector; import org.geogebra.common.kernel.kernelND.GeoElementND; import org.geogebra.common.kernel.prover.NoSymbolicParametersException; import org.geogebra.common.kernel.prover.polynomial.PPolynomial; import org.geogebra.common.kernel.prover.polynomial.PVariable; import org.geogebra.common.plugin.Operation; /** * * @author Markus */ public class AlgoDependentPoint extends AlgoElement implements DependentAlgo, SymbolicParametersBotanaAlgo { private GeoPoint P; // output private PVariable[] botanaVars; private PPolynomial[] botanaPolynomials; private GeoVec2D temp; /** * Creates new dependent point algo * * @param cons * construction * @param label * output label * @param root * expression defining the result * @param complex * true if result is complex number */ public AlgoDependentPoint(Construction cons, String label, ExpressionNode root, boolean complex) { this(cons, root, complex); P.setLabel(label); } /** * @param cons * construction * @param root * expression * @param complex * whether output is complex */ public AlgoDependentPoint(Construction cons, ExpressionNode root, boolean complex) { super(cons); P = new GeoPoint(cons); P.setDefinition(root); setInputOutput(); // for AlgoElement if (complex) { P.setMode(Kernel.COORD_COMPLEX); } // compute value of dependent number compute(); } @Override public Algos getClassName() { return Algos.Expression; } // for AlgoElement @Override protected void setInputOutput() { input = P.getDefinition().getGeoElementVariables(); setOutputLength(1); setOutput(0, P); setDependencies(); // done by AlgoElement } /** * @return result */ public GeoPoint getPoint() { return P; } @Override public ExpressionNode getExpression() { return P.getDefinition(); } // calc the current value of the arithmetic tree @Override public final void compute() { try { temp = ((VectorValue) P.getDefinition() .evaluate(StringTemplate.defaultTemplate)).getVector(); if (Double.isInfinite(temp.getX()) || Double.isInfinite(temp.getY())) { P.setUndefined(); } else { ExpressionNode def = P.getDefinition(); P.setCoords(temp.getX(), temp.getY(), 1.0); P.setDefinition(def); } // P.setMode(temp.getMode()); } catch (Exception e) { P.setUndefined(); } } @Override final public String toString(StringTemplate tpl) { return P.getDefinition() == null ? "?" : P.getDefinition().toString(tpl); } @Override public PVariable[] getBotanaVars(GeoElementND geo) throws NoSymbolicParametersException { return botanaVars; } @Override public PPolynomial[] getBotanaPolynomials(GeoElementND geo) throws NoSymbolicParametersException { if (botanaVars == null) { botanaVars = new PVariable[2]; botanaVars[0] = new PVariable(kernel); botanaVars[1] = new PVariable(kernel); GeoElement left = (GeoElement) P.getDefinition().getLeft(); GeoElement right = (GeoElement) P.getDefinition().getRight(); Operation op = P.getDefinition().getOperation(); if (op == Operation.NO_OPERATION && left != null) { PVariable[] leftBotanaVars = ((SymbolicParametersBotanaAlgo) left) .getBotanaVars(left); botanaPolynomials = new PPolynomial[2]; botanaPolynomials[0] = new PPolynomial(botanaVars[0]) .subtract(new PPolynomial(leftBotanaVars[0])); botanaPolynomials[1] = new PPolynomial(botanaVars[1]) .subtract(new PPolynomial(leftBotanaVars[1])); } if (op == Operation.PLUS && left != null && right != null) { if (left instanceof GeoPoint && right instanceof GeoVector) { PVariable[] leftBotanaVars = ((SymbolicParametersBotanaAlgo) left) .getBotanaVars(left); PVariable[] rightBotanaVars = ((SymbolicParametersBotanaAlgo) right) .getBotanaVars(right); botanaPolynomials = new PPolynomial[2]; /* P=left+right => P-left-right=0 */ botanaPolynomials[0] = new PPolynomial(botanaVars[0]) .subtract(new PPolynomial(leftBotanaVars[0])) .subtract(new PPolynomial(rightBotanaVars[0])); botanaPolynomials[1] = new PPolynomial(botanaVars[1]) .subtract(new PPolynomial(leftBotanaVars[1])) .subtract(new PPolynomial(rightBotanaVars[1])); } } if (op == Operation.MINUS && left != null && right != null) { if (left instanceof GeoPoint && right instanceof GeoVector) { PVariable[] leftBotanaVars = ((SymbolicParametersBotanaAlgo) left) .getBotanaVars(left); PVariable[] rightBotanaVars = ((SymbolicParametersBotanaAlgo) right) .getBotanaVars(right); botanaPolynomials = new PPolynomial[2]; /* P=left-right => P-left+right=0 */ botanaPolynomials[0] = new PPolynomial(botanaVars[0]) .subtract(new PPolynomial(leftBotanaVars[0])) .add(new PPolynomial(rightBotanaVars[0])); botanaPolynomials[1] = new PPolynomial(botanaVars[1]) .subtract(new PPolynomial(leftBotanaVars[1])) .add(new PPolynomial(rightBotanaVars[1])); } } /* FIXME: This code does not handle *many* other cases yet. */ } return botanaPolynomials; } }