package org.geogebra.common.kernel.commands; import org.geogebra.common.kernel.CircularDefinitionException; import org.geogebra.common.kernel.Kernel; import org.geogebra.common.kernel.algos.AlgoSpline; import org.geogebra.common.kernel.arithmetic.Command; import org.geogebra.common.kernel.geos.GeoElement; import org.geogebra.common.kernel.geos.GeoFunctionNVar; import org.geogebra.common.kernel.geos.GeoList; import org.geogebra.common.kernel.geos.GeoNumberValue; import org.geogebra.common.kernel.geos.GeoNumeric; import org.geogebra.common.kernel.kernelND.GeoCurveCartesianND; import org.geogebra.common.main.MyError; import org.geogebra.common.plugin.GeoClass; /** * * Spline [<list of points>] * * @author Giuliano Bellucci * */ public class CmdSpline extends CommandProcessor { /** * @param kernel * kernel */ public CmdSpline(Kernel kernel) { super(kernel); } @Override public GeoElement[] process(Command c) throws MyError, CircularDefinitionException { int n = c.getArgumentNumber(); GeoElement[] arg; arg = resArgs(c); switch (n) { case 0: throw argNumErr(app, c, n); case 1: arg = resArgs(c); if (arg[0].isGeoList() && arePoint((GeoList) arg[0])) { GeoElement[] ret = { Spline(c.getLabel(), (GeoList) arg[0]) }; return ret; } throw argErr(app, c, arg[0]); case 2: arg = resArgs(c); if (arg[0].isGeoList() && arePoint((GeoList) arg[0])) { int degree = (int) c.getArgument(1).evaluateDouble(); if (Double.isNaN(degree) || degree > ((GeoList) arg[0]).size() || degree < 3) { throw argErr(app, c, c.getArgument(1)); } GeoNumberValue degreeNum = (GeoNumberValue) arg[1]; AlgoSpline algo = new AlgoSpline(cons, c.getLabel(), (GeoList) arg[0], degreeNum, null); GeoCurveCartesianND list = algo.getSpline(); GeoElement[] ret = { list }; return ret; } throw argErr(app, c, arg[0]); case 3: arg = resArgs(c); if (!arg[2].isGeoFunctionNVar()) { throw argErr(app, c, arg[2]); } if (arg[0].isGeoList() && arePoint((GeoList) arg[0])) { int degree = (int) c.getArgument(1).evaluateDouble(); if (Double.isNaN(degree) || degree > ((GeoList) arg[0]).size() || degree < 3) { throw argErr(app, c, c.getArgument(1)); } GeoNumberValue degreeNum = (GeoNumberValue) arg[1]; AlgoSpline algo = new AlgoSpline(cons, c.getLabel(), (GeoList) arg[0], degreeNum, (GeoFunctionNVar) arg[2]); GeoCurveCartesianND list = algo.getSpline(); GeoElement[] ret = { list }; return ret; } throw argErr(app, c, arg[0]); default: GeoList list = wrapInList(kernelA, arg, arg.length, GeoClass.POINT); if (list != null) { GeoElement[] ret = { Spline(c.getLabel(), list) }; return ret; } throw argNumErr(app, c, n); } } private GeoCurveCartesianND Spline(String label, GeoList list) { AlgoSpline algo = new AlgoSpline(cons, label, list, new GeoNumeric(cons, 3), null); return algo.getSpline(); } private static boolean arePoint(GeoList geoList) { for (int i = 0; i < geoList.size() - 1; i++) { if (!geoList.get(i).isGeoPoint()) { return false; } } return true; } }