package org.geogebra.common.kernel.commands;
import org.geogebra.common.kernel.Kernel;
import org.geogebra.common.kernel.algos.AlgoCurveCartesian;
import org.geogebra.common.kernel.algos.AlgoDependentNumber;
import org.geogebra.common.kernel.arithmetic.Command;
import org.geogebra.common.kernel.arithmetic.ExpressionNode;
import org.geogebra.common.kernel.arithmetic.VectorArithmetic;
import org.geogebra.common.kernel.arithmetic.VectorNDValue;
import org.geogebra.common.kernel.geos.GeoElement;
import org.geogebra.common.kernel.geos.GeoNumberValue;
import org.geogebra.common.kernel.geos.GeoNumeric;
import org.geogebra.common.main.MyError;
/**
* Curve[ <x-coord expression>, <y-coord expression>, <number-var>, <from>,
* <to> ]
*/
public class CmdCurveCartesian extends CommandProcessor {
/**
* Create new command processor
*
* @param kernel
* kernel
*/
public CmdCurveCartesian(Kernel kernel) {
super(kernel);
}
@Override
public GeoElement[] process(Command c) throws MyError {
int n = c.getArgumentNumber();
boolean[] ok = new boolean[n];
switch (n) {
// Curve[ <x-coord expression>, <y-coord expression>, <number-var>,
// <from>, <to> ]
// Note: x and y coords are numbers dependent on number-var
// Curve[t*(1-t)*A+t*t*B+(1-t)*(1-t)*C,t,0,1]
case 4:
GeoElement[] arg = resArgsLocalNumVar(c, 1, 2);
if ((ok[0] = arg[0] instanceof VectorNDValue)
&& (ok[1] = arg[1].isGeoNumeric())
&& (ok[2] = arg[2] instanceof GeoNumberValue)
&& (ok[3] = arg[3] instanceof GeoNumberValue)) {
ExpressionNode exp = kernelA
.convertNumberValueToExpressionNode(arg[0]);
int dim = ((VectorNDValue) arg[0]).getDimension();
GeoNumberValue[] coords = new GeoNumberValue[dim];
for (int i = 0; i < dim; i++) {
ExpressionNode cx = VectorArithmetic.computeCoord(exp, i);
AlgoDependentNumber nx = new AlgoDependentNumber(cons, cx,
false);
cons.removeFromConstructionList(nx);
coords[i] = nx.getNumber();
}
AlgoCurveCartesian algo = getCurveAlgo(exp, coords, arg);
algo.getCurve().setLabel(c.getLabel());
GeoElement[] ret = { algo.getCurve() };
return ret;
}
case 5:
// create local variable at position 2 and resolve arguments
arg = resArgsLocalNumVar(c, 2, 3);
if ((ok[0] = arg[0] instanceof GeoNumberValue)
&& (ok[1] = arg[1] instanceof GeoNumberValue)
&& (ok[2] = arg[2].isGeoNumeric())
&& (ok[3] = arg[3] instanceof GeoNumberValue)
&& (ok[4] = arg[4] instanceof GeoNumberValue)) {
// make sure Curve[i,i,i,i,i] gives an error
checkDependency(arg, c, 3, 2);
checkDependency(arg, c, 4, 2);
AlgoCurveCartesian algo = new AlgoCurveCartesian(cons, null,
new GeoNumberValue[] { (GeoNumberValue) arg[0],
(GeoNumberValue) arg[1] },
(GeoNumeric) arg[2], (GeoNumberValue) arg[3],
(GeoNumberValue) arg[4]);
algo.getCurve().setLabel(c.getLabel());
GeoElement[] ret = { algo.getCurve() };
return ret;
}
for (int i = 0; i < n; i++) {
if (!ok[i]) {
throw argErr(app, c, arg[i]);
}
}
default:
throw argNumErr(app, c, n);
}
}
/**
* @param point
* point expression
* @param coords
* coordinates
* @param arg
* arguments (contains variables)
* @return curve algo
*/
protected AlgoCurveCartesian getCurveAlgo(ExpressionNode point,
GeoNumberValue[] coords, GeoElement[] arg) {
return new AlgoCurveCartesian(cons, point, coords, (GeoNumeric) arg[1],
(GeoNumberValue) arg[2], (GeoNumberValue) arg[3]);
}
@Override
protected String[] replaceXYarguments(ExpressionNode[] arg) {
String[] newXYZ = new String[3];
if (arg.length == 4 || arg.length == 5 || arg.length == 6) {
int offset = arg.length - 3;
// we have to replace "x"
newXYZ[0] = checkReplaced(arg, offset, "x", "u", offset);
if (newXYZ[0] == null) {
newXYZ[0] = checkReplaced(arg, offset, "y", "v", offset);
}
}
return newXYZ;
}
}