/*
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.
*/
/*
* AlgoTranslatePoint.java
*
* Created on 24. September 2001, 21:37
*/
package org.geogebra.common.kernel.algos;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.HashSet;
import org.geogebra.common.euclidian.EuclidianConstants;
import org.geogebra.common.kernel.Construction;
import org.geogebra.common.kernel.StringTemplate;
import org.geogebra.common.kernel.Matrix.Coords;
import org.geogebra.common.kernel.commands.Commands;
import org.geogebra.common.kernel.geos.GeoElement;
import org.geogebra.common.kernel.geos.GeoList;
import org.geogebra.common.kernel.geos.GeoPoint;
import org.geogebra.common.kernel.geos.GeoVec3D;
import org.geogebra.common.kernel.geos.GeoVector;
import org.geogebra.common.kernel.geos.Translateable;
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;
/**
*
* @author Markus
*/
public class AlgoTranslate extends AlgoTransformation
implements SymbolicParametersAlgo, SymbolicParametersBotanaAlgo {
private Translateable out;
protected GeoElement inGeo;
protected GeoElement outGeo;
protected GeoElement v; // input
private PPolynomial[] polynomials;
private PPolynomial[] botanaPolynomials;
private PVariable[] botanaVars;
/**
* Creates labeled translation algo
*
* @param cons
* @param label
* @param in
* @param v
*/
public AlgoTranslate(Construction cons, String label, GeoElement in,
GeoVec3D v) {
this(cons, in, v);
outGeo.setLabel(label);
}
/**
* Creates unlabeled translation algo
*
* @param cons
* @param in
* @param v
*/
public AlgoTranslate(Construction cons, GeoElement in, GeoElement v) {
super(cons);
this.v = v;
inGeo = in;
// create output object
outGeo = getResultTemplate(inGeo);
if (outGeo instanceof Translateable) {
out = (Translateable) outGeo;
}
setInputOutput();
compute();
}
@Override
public Commands getClassName() {
return Commands.Translate;
}
@Override
public int getRelatedModeID() {
return EuclidianConstants.MODE_TRANSLATE_BY_VECTOR;
}
// for AlgoElement
@Override
protected void setInputOutput() {
input = new GeoElement[2];
input[0] = inGeo;
input[1] = v;
setOutputLength(1);
setOutput(0, outGeo);
setDependencies(); // done by AlgoElement
}
@Override
public GeoElement getResult() {
return outGeo;
}
// calc translated point
@Override
public final void compute() {
if (inGeo.isGeoList()) {
transformList((GeoList) inGeo, (GeoList) outGeo);
return;
}
if (!v.isDefined()) {
out.setUndefined();
return;
}
setOutGeo();
if (!out.isDefined()) {
return;
}
out.translate(getVectorCoords());
if (inGeo.isLimitedPath()) {
this.transformLimitedPath(inGeo, outGeo);
}
}
/**
* set inGeo to outGeo
*/
protected void setOutGeo() {
outGeo.set(inGeo);
}
protected Coords getVectorCoords() {
GeoVec3D vec = (GeoVec3D) v;
return new Coords(vec.x, vec.y, vec.z);
}
@Override
final public String toString(StringTemplate tpl) {
// Michael Borcherds 2008-03-24 simplified code!
return getLoc().getPlain("TranslationOfAbyB", inGeo.getLabel(tpl),
v.getLabel(tpl));
}
@Override
protected void setTransformedObject(GeoElement g, GeoElement g2) {
inGeo = g;
outGeo = g2;
if (!(outGeo instanceof GeoList)) {
out = (Translateable) outGeo;
}
}
@Override
public SymbolicParameters getSymbolicParameters() {
return new SymbolicParameters(this);
}
@Override
public void getFreeVariables(HashSet<PVariable> variables)
throws NoSymbolicParametersException {
if (inGeo instanceof GeoPoint && v instanceof GeoVector) {
((SymbolicParametersAlgo) inGeo).getFreeVariables(variables);
((SymbolicParametersAlgo) v).getFreeVariables(variables);
return;
}
throw new NoSymbolicParametersException();
}
@Override
public int[] getDegrees() throws NoSymbolicParametersException {
if (inGeo instanceof GeoPoint && v instanceof GeoVector) {
int[] degree1 = ((SymbolicParametersAlgo) inGeo).getDegrees();
int[] degree2 = ((SymbolicParametersAlgo) v).getDegrees();
int[] result = new int[3];
result[0] = Math.max(degree1[0] + degree2[2],
degree2[0] + degree1[2]);
result[1] = Math.max(degree1[1] + degree2[2],
degree2[1] + degree1[2]);
result[2] = degree2[2] + degree1[2];
return result;
}
throw new NoSymbolicParametersException();
}
@Override
public BigInteger[] getExactCoordinates(
final HashMap<PVariable, BigInteger> values)
throws NoSymbolicParametersException {
if (inGeo instanceof GeoPoint && v instanceof GeoVector) {
BigInteger[] coords1 = ((SymbolicParametersAlgo) inGeo)
.getExactCoordinates(values);
BigInteger[] coords2 = ((SymbolicParametersAlgo) v)
.getExactCoordinates(values);
BigInteger[] result = new BigInteger[3];
result[0] = coords1[0].multiply(coords2[2])
.add(coords2[0].multiply(coords1[2]));
result[1] = coords1[1].multiply(coords2[2])
.add(coords2[1].multiply(coords1[2]));
result[2] = coords1[2].multiply(coords2[2]);
return SymbolicParameters.reduce(result);
}
return null;
}
@Override
public PPolynomial[] getPolynomials() throws NoSymbolicParametersException {
if (polynomials != null) {
return polynomials;
}
if (inGeo instanceof GeoPoint && v instanceof GeoVector) {
PPolynomial[] coords1 = ((SymbolicParametersAlgo) inGeo)
.getPolynomials();
PPolynomial[] coords2 = ((SymbolicParametersAlgo) v)
.getPolynomials();
polynomials = new PPolynomial[3];
polynomials[0] = coords1[0].multiply(coords2[2])
.add(coords2[0].multiply(coords1[2]));
polynomials[1] = coords1[1].multiply(coords2[2])
.add(coords2[1].multiply(coords1[2]));
polynomials[2] = coords1[2].multiply(coords2[2]);
return polynomials;
}
throw new NoSymbolicParametersException();
}
@Override
public double getAreaScaleFactor() {
return 1;
}
@Override
public PVariable[] getBotanaVars(GeoElementND geo) {
return botanaVars;
}
@Override
public PPolynomial[] getBotanaPolynomials(GeoElementND geo)
throws NoSymbolicParametersException {
if (botanaPolynomials != null) {
return botanaPolynomials;
}
GeoPoint P = (GeoPoint) inGeo;
GeoVector u = (GeoVector) v;
if (P != null && v != null) {
PVariable[] vP = P.getBotanaVars(P);
PVariable[] vv = u.getBotanaVars(u);
if (botanaVars == null) {
botanaVars = new PVariable[6];
// A'
botanaVars[0] = new PVariable(kernel);
botanaVars[1] = new PVariable(kernel);
// P
botanaVars[2] = vP[0];
botanaVars[3] = vP[1];
// v
botanaVars[4] = vv[0];
botanaVars[5] = vv[1];
}
botanaPolynomials = new PPolynomial[2];
PPolynomial p1 = new PPolynomial(vP[0]);
PPolynomial p2 = new PPolynomial(vP[1]);
PPolynomial u1 = new PPolynomial(vv[0]);
PPolynomial u2 = new PPolynomial(vv[1]);
PPolynomial p_1 = new PPolynomial(botanaVars[0]);
PPolynomial p_2 = new PPolynomial(botanaVars[1]);
botanaPolynomials[0] = p1.add(u1).subtract(p_1);
botanaPolynomials[1] = p2.add(u2).subtract(p_2);
return botanaPolynomials;
}
throw new NoSymbolicParametersException();
}
}