/*
GeoGebra - Dynamic Mathematics for Everyone
http://www.geogebra.org
This file is part of GeoGebra.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation.
*/
package org.geogebra.common.kernel.algos;
import org.geogebra.common.kernel.Construction;
import org.geogebra.common.kernel.ConstructionDefaults;
import org.geogebra.common.kernel.FixedPathRegionAlgo;
import org.geogebra.common.kernel.Path;
import org.geogebra.common.kernel.StringTemplate;
import org.geogebra.common.kernel.Matrix.Coords;
import org.geogebra.common.kernel.arithmetic.Function;
import org.geogebra.common.kernel.commands.Commands;
import org.geogebra.common.kernel.geos.GeoElement;
import org.geogebra.common.kernel.geos.GeoFunction;
import org.geogebra.common.kernel.kernelND.GeoPointND;
/**
* @author csilla
*
* Algo for intersection of path with point
*/
public class AlgoIntersectPathPoint extends AlgoElement
implements FixedPathRegionAlgo {
private Path path; // input
private GeoPointND point; // input
private GeoPointND P; // output
/**
* @param cons
* construction
* @param path
* path
* @param point
* point
*/
public AlgoIntersectPathPoint(Construction cons, Path path,
GeoPointND point) {
super(cons);
this.path = path;
this.point = point;
// create point on path and compute current location
createOutputPoint(cons, path);
// for AlgoElement
setInputOutput();
P.setVisualStyle(cons.getConstructionDefaults()
.getDefaultGeo(ConstructionDefaults.DEFAULT_POINT_DEPENDENT));
compute();
}
/**
* create the output point
*
* @param cons
* construction
* @param path
* path
*/
protected void createOutputPoint(Construction cons, Path path) {
P = point.copy();
P.setPath(path);
}
/**
* @param cons
* construction
* @param label
* label
* @param path
* path
* @param point
* point
*/
public AlgoIntersectPathPoint(Construction cons, String label, Path path,
GeoPointND point) {
this(cons, path, point);
P.setLabel(label);
}
@Override
public Commands getClassName() {
return Commands.Intersect;
}
// for AlgoElement
@Override
protected void setInputOutput() {
input = new GeoElement[2];
input[0] = path.toGeoElement();
input[1] = point.toGeoElement();
setOutputLength(1);
setOutput(0, (GeoElement) P);
setDependencies(); // done by AlgoElement
}
/**
*
* @return resulting point (same coords as input, may be undefined)
*/
public GeoPointND getP() {
return P;
}
/**
* set coords of closest point to input point coords
*/
protected void setCoords() {
P.set(point);
}
@Override
public final void compute() {
// if path and point are defined
if (input[0].isDefined() && point.isDefined()) {
// get the closest point on path to input point
if (path instanceof GeoFunction) {
Function fun = ((GeoFunction) path).getFunction()
.deepCopy(kernel);
Coords coords = point.getCoordsInD2();
double val = AlgoDistancePointObject
.getClosestFunctionValueToPoint(fun, coords.getX(),
coords.getY());
P.setCoords(val, fun.value(val), 1.0);
} else {
setCoords();
path.pointChanged(P);
}
P.updateCoords();
// if input point and output point has same coordinates
// return point
// else set output point undefined
if (!P.getCoords().equalsForKernel(point.getCoords())) {
P.setUndefined();
}
} else {
P.setUndefined();
}
}
@Override
final public String toString(StringTemplate tpl) {
return getLoc().getPlain("IntersectionOfAandB", input[0].getLabel(tpl),
input[1].getLabel(tpl));
}
@Override
public boolean isChangeable(GeoElement out) {
return false;
}
}