package org.geogebra.common.geogebra3D.kernel3D.algos; import org.geogebra.common.kernel.Construction; import org.geogebra.common.kernel.StringTemplate; import org.geogebra.common.kernel.arithmetic.ExpressionNode; import org.geogebra.common.kernel.arithmetic.FunctionNVar; import org.geogebra.common.kernel.arithmetic.FunctionVariable; import org.geogebra.common.kernel.arithmetic.NumberValue; import org.geogebra.common.kernel.commands.Commands; import org.geogebra.common.kernel.geos.GeoElement; import org.geogebra.common.kernel.geos.GeoFunctionNVar; import org.geogebra.common.kernel.geos.GeoNumberValue; import org.geogebra.common.kernel.geos.GeoNumeric; /** * @author ggb3D * */ public class AlgoFunctionNVarND extends AlgoElement3D { /** input function */ protected GeoFunctionNVar inputFunction; /** output function */ protected GeoFunctionNVar function; // private NumberValue[] coords; // input : expression for each coord x, y, // z, ... /** input : "from" values for each var */ protected NumberValue[] from; /** input : "to" values for each var */ protected NumberValue[] to; // private GeoNumeric[] localVar; // input : variables u, v, ... private AlgoFunctionNVarND(Construction cons, NumberValue[] from, NumberValue[] to) { super(cons); // this.coords = coords; this.from = from; this.to = to; // this.localVar = localVar; } /** * Construct a function * * @param cons * construction * @param label * label * @param coords * description of the function * @param localVar * var of the function * @param from * "from" values for each var * @param to * "to" values for each var * */ public AlgoFunctionNVarND(Construction cons, String label, GeoNumberValue[] coords, GeoNumeric[] localVar, GeoNumberValue[] from, GeoNumberValue[] to) { this(cons, from, to); // we need to create Function objects for the coord NumberValues, // so let's get the expressions of xcoord and ycoord and replace // the localVar by a functionVar FunctionVariable[] funVar = new FunctionVariable[localVar.length]; for (int i = 0; i < localVar.length; i++) { funVar[i] = new FunctionVariable(kernel); funVar[i].setVarString( localVar[i].getLabel(StringTemplate.defaultTemplate)); } ExpressionNode[] exp = new ExpressionNode[coords.length]; FunctionNVar[] fun = new FunctionNVar[coords.length]; for (int i = 0; i < coords.length; i++) { exp[i] = kernel.convertNumberValueToExpressionNode( coords[i].toGeoElement()); for (int j = 0; j < localVar.length; j++) { exp[i] = exp[i].replace(localVar[j], funVar[j]).wrap(); } fun[i] = new FunctionNVar(exp[i], funVar); } // create the function function = new GeoFunctionNVar(cons, fun[0]); // end of construction setInputOutput(coords, localVar); compute(); function.setLabel(label); } /** * Construct a function * * @param cons * construction * @param label * label * @param f * (x,y) function * @param from * "from" values for each var * @param to * "to" values for each var * */ public AlgoFunctionNVarND(Construction cons, String label, GeoFunctionNVar f, GeoNumberValue[] from, GeoNumberValue[] to) { this(cons, from, to); inputFunction = f; // function = new GeoFunctionNVar(cons, // inputFunction.getFunction());//(GeoFunctionNVar) // inputFunction.copy(); function = (GeoFunctionNVar) inputFunction.copy(); // end of construction setInputOutput((GeoNumberValue[]) null, (GeoNumeric[]) null); compute(); function.setLabel(label); } private void setInputOutput(GeoNumberValue[] coords, GeoNumeric[] localVar) { int inputLength = from.length + to.length; if (coords != null) { inputLength += coords.length; } else { inputLength += 1; // for the function } if (localVar != null) { inputLength += localVar.length; } GeoElement[] inputElements = new GeoElement[inputLength]; int index = 0; if (coords != null) { for (int i = 0; i < coords.length; i++) { inputElements[index] = (GeoElement) coords[i]; index++; } } else { inputElements[index] = inputFunction; index++; } for (int i = 0; i < from.length; i++) { if (localVar != null) { inputElements[index] = localVar[i]; index++; } inputElements[index] = (GeoElement) from[i]; index++; inputElements[index] = (GeoElement) to[i]; index++; } super.setInputOutput(inputElements, new GeoElement[] { function }); } /** * @return the function */ public GeoFunctionNVar getFunction() { return function; } @Override public void compute() { if (inputFunction != null) { function.set(inputFunction); } function.setInterval(getDouble(from), getDouble(to)); // Application.debug(function.getFunction().evaluate(new double[] // {1,1})); } private static double[] getDouble(NumberValue[] values) { double[] ret = new double[values.length]; for (int i = 0; i < values.length; i++) { ret[i] = values[i].getDouble(); // Application.debug("ret["+i+"]="+ret[i]); } return ret; } @Override public Commands getClassName() { return Commands.Function; } }