package org.geogebra.common.geogebra3D.euclidianFor3D;
import org.apache.commons.math3.analysis.UnivariateFunction;
import org.geogebra.common.geogebra3D.kernel3D.geos.GeoCurveCartesian3D;
import org.geogebra.common.kernel.Kernel;
import org.geogebra.common.kernel.geos.GeoElement;
import org.geogebra.common.kernel.kernelND.CurveEvaluable;
/**
* For 3D curve, evaluator that returns NaN when z != 0
*
* @author mathieu
*
*/
public class CurveEvaluableFor3D implements CurveEvaluable {
private GeoCurveCartesian3D parent;
private double[] parentOut;
private FunMustBeZero funZ;
/**
* Function that returns NaN if parent z != 0
*
* @author mathieu
*
*/
private static class FunMustBeZero implements UnivariateFunction {
private UnivariateFunction parentFun;
protected FunMustBeZero() {
}
public void setParentFun(UnivariateFunction parentFun) {
this.parentFun = parentFun;
}
@Override
public double value(double t) {
double z = parentFun.value(t);
if (!Kernel.isZero(z)) {
return Double.NaN;
}
return 0;
}
}
/**
* constructor
*
* @param parent
* curve
*/
public CurveEvaluableFor3D(GeoCurveCartesian3D parent) {
this.parent = parent;
parentOut = new double[3];
funZ = new FunMustBeZero();
}
@Override
public void evaluateCurve(double t, double[] out) {
parent.evaluateCurve(t, parentOut);
double z = parentOut[2];
if (Double.isInfinite(z) || Double.isNaN(z) || !Kernel.isZero(z)) {
out[0] = Double.NaN;
} else {
for (int i = 0; i < out.length; i++) {
out[i] = parentOut[i];
}
}
}
@Override
public double[] getDefinedInterval(double a, double b) {
funZ.setParentFun(parent.getFun(2));
return GeoCurveCartesian3D.getDefinedInterval(a, b, parent.getFun(0),
parent.getFun(1), funZ);
}
@Override
public double[] newDoubleArray() {
return new double[2];
}
@Override
public double getMinParameter() {
return parent.getMinParameter();
}
@Override
public double getMaxParameter() {
return parent.getMaxParameter();
}
@Override
public boolean getTrace() {
return parent.getTrace();
}
@Override
public boolean isClosedPath() {
return parent.isClosedPath();
}
@Override
public boolean isFunctionInX() {
return parent.isFunctionInX();
}
@Override
public GeoElement toGeoElement() {
return parent.toGeoElement();
}
@Override
public double distanceMax(double[] p1, double[] p2) {
return Math.max(Math.abs(p1[0] - p2[0]), Math.abs(p1[1] - p2[1]));
}
}