package org.geogebra.common.geogebra3D.kernel3D.implicit3D; import org.geogebra.common.kernel.Construction; import org.geogebra.common.kernel.Kernel; import org.geogebra.common.kernel.StringTemplate; import org.geogebra.common.kernel.Matrix.Coords; import org.geogebra.common.kernel.algos.AlgoElement; import org.geogebra.common.kernel.algos.GetCommand; import org.geogebra.common.kernel.arithmetic.Equation; import org.geogebra.common.kernel.arithmetic.ExpressionNode; import org.geogebra.common.kernel.arithmetic.FunctionVariable; import org.geogebra.common.kernel.arithmetic.Traversing.VariableReplacer; import org.geogebra.common.kernel.commands.Commands; import org.geogebra.common.kernel.commands.HasShortSyntax; import org.geogebra.common.kernel.geos.GeoElement; import org.geogebra.common.kernel.kernelND.GeoPlaneND; /** * Finds intersection path of surface and plane * * @author zbynek * */ public class AlgoIntersectImplicitSurfacePlane extends AlgoElement implements HasShortSyntax { private GeoImplicitSurface surface; private GeoPlaneND plane; private GeoImplicitCurve3D curve; private boolean shortSyntax; /** * @param c * construction * @param surface * surface * @param plane * plane */ public AlgoIntersectImplicitSurfacePlane(Construction c, GeoImplicitSurface surface, GeoPlaneND plane) { super(c); this.surface = surface; this.plane = plane; this.curve = new GeoImplicitCurve3D(c); setInputOutput(); compute(); } @Override protected void setInputOutput() { this.input = new GeoElement[] { (GeoElement) plane, surface }; setOnlyOutput(curve); setDependencies(); } @Override public void compute() { VariableReplacer vr = VariableReplacer.getReplacer(kernel); // a*x+b*y+c*z=d, z=d/c-a/c*x-b/c*y Coords norm = plane.getCoordSys().getEquationVector(); curve.setPlaneEquation(norm); FunctionVariable x = surface.getExpression().getFunctionVariables()[0]; FunctionVariable y = surface.getExpression().getFunctionVariables()[1]; if (!Kernel.isZero(norm.getZ())) { double a = norm.getX() / norm.getZ(); double b = norm.getY() / norm.getZ(); double d = norm.getW() / norm.getZ(); ExpressionNode substZ = x.wrap().multiply(a) .plus(y.wrap().multiply(b).plus(d)); VariableReplacer.addVars("z", substZ); curve.getTransformedCoordSys().setZequal(a, b, 1, d); } else { if (Kernel.isZero(norm.getY())) { double a = norm.getW() / norm.getX(); ExpressionNode substX = new ExpressionNode(kernel, a); VariableReplacer.addVars("x", substX); VariableReplacer.addVars("y", new FunctionVariable(kernel, "x")); VariableReplacer.addVars("z", new FunctionVariable(kernel, "y")); curve.getTransformedCoordSys().setXequal(a); } else { double a = norm.getX() / norm.getY(); double b = norm.getW() / norm.getY(); ExpressionNode substY = x.wrap().multiply(a).plus(b); VariableReplacer.addVars("y", substY); VariableReplacer.addVars("z", new FunctionVariable(kernel, "y")); curve.getTransformedCoordSys().setYequal(a, 1, b); } } ExpressionNode exp = surface.getExpression().getFunctionExpression() .getCopy(kernel); exp = exp.traverse(vr).wrap(); curve.fromEquation( new Equation(kernel, exp, new ExpressionNode(kernel, 0)), null); // TODO Auto-generated method stub } @Override public GetCommand getClassName() { return Commands.IntersectPath; } @Override final public String getDefinition(StringTemplate tpl) { if (shortSyntax) { return "(" + surface.getLabel(tpl) + "," + plane.getLabel(tpl) + ")"; } return super.getDefinition(tpl); } public void setShortSyntax(boolean b) { this.shortSyntax = b; } }