package org.geogebra.common.geogebra3D.kernel3D.algos;
import org.geogebra.common.euclidian.EuclidianConstants;
import org.geogebra.common.geogebra3D.kernel3D.geos.GeoPoint3D;
import org.geogebra.common.kernel.commands.Commands;
import org.geogebra.common.kernel.geos.GeoElement;
import org.geogebra.common.kernel.geos.GeoNumeric;
import org.geogebra.common.kernel.kernelND.GeoPointND;
/**
* Single intersection point
*/
public class AlgoIntersectSingle3D extends AlgoIntersect3D {
// input
private AlgoIntersect3D algo;
private int index; // index of point in algo
private GeoPointND refPoint;
// output
private GeoPoint3D point;
private GeoPoint3D[] parentOutput;
/**
* intersection point is the (a) nearest to refPoint
*
* @param label
* output label
* @param algo
* generic intersect algo
* @param refPoint
* closest point
*/
AlgoIntersectSingle3D(String label, AlgoIntersect3D algo,
GeoPointND refPoint) {
super(algo.getConstruction());
this.algo = algo;
algo.addUser(); // this algorithm is a user of algo
this.refPoint = refPoint;
point = new GeoPoint3D(algo.getConstruction());
setInputOutput();
initForNearToRelationship();
compute();
point.setLabel(label);
}
/**
* intersection point is index-th intersection point of algo
*
* @param label
* output label
* @param algo
* intersect algo
* @param index0
* output index
*/
AlgoIntersectSingle3D(String label, AlgoIntersect3D algo, int index0) {
super(algo.getConstruction());
this.algo = algo;
algo.addUser(); // this algorithm is a user of algo
// check index
if (index0 < 0) {
this.index = 0;
} else {
this.index = index0;
}
point = new GeoPoint3D(algo.getConstruction());
setInputOutput();
initForNearToRelationship();
compute();
point.setLabel(label);
}
@Override
protected boolean showUndefinedPointsInAlgebraView() {
return true;
}
@Override
public Commands getClassName() {
return Commands.Intersect;
}
@Override
public int getRelatedModeID() {
return EuclidianConstants.MODE_INTERSECT;
}
// for AlgoElement
@Override
public void setInputOutput() {
if (refPoint == null) {
input = new GeoElement[3];
input[0] = algo.getInput()[0];
input[1] = algo.getInput()[1];
// dummy value to store the index of the intersection point
// index + 1 is used here to let numbering start at 1
input[2] = new GeoNumeric(cons, index + 1);
} else {
input = new GeoElement[3];
input[0] = algo.getInput()[0];
input[1] = algo.getInput()[1];
input[2] = (GeoElement) refPoint;
}
setOutputLength(1);
this.setOutput(0, point);
setDependencies(); // done by AlgoElement
}
/**
* @return intersection point
*/
public GeoPoint3D getPoint() {
return point;
}
@Override
public GeoPoint3D[] getIntersectionPoints() {
return (GeoPoint3D[]) getOutput();
}
@Override
protected GeoPoint3D[] getLastDefinedIntersectionPoints() {
return null;
}
@Override
public boolean isNearToAlgorithm() {
return true;
}
@Override
public final void initForNearToRelationship() {
parentOutput = algo.getIntersectionPoints();
// tell parent algorithm about the loaded position;
// this is needed for initing the intersection algo with
// the intersection point stored in XML files
algo.initForNearToRelationship();
algo.setIntersectionPoint(index, point);
algo.compute();
}
@Override
public void compute() {
parentOutput = algo.getIntersectionPoints();
if (refPoint != null) {
if (refPoint.isDefined()) {
index = algo.getClosestPointIndex(refPoint);
}
}
if (input[0].isDefined() && input[1].isDefined()
&& index < parentOutput.length) {
// get coordinates from helper algorithm
point.setCoords(parentOutput[index].getCoords());
} else {
point.setUndefined();
}
}
@Override
public void remove() {
super.remove();
algo.removeUser(); // this algorithm was a user of algo
}
}