/*
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.
*/
/*
* AlgoIntersectLines.java
*
* Created on 30. August 2001, 21:37
*/
package org.geogebra.common.kernel.algos;
import org.geogebra.common.euclidian.EuclidianConstants;
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.arithmetic.ExpressionNode;
import org.geogebra.common.kernel.arithmetic.FunctionVariable;
import org.geogebra.common.kernel.arithmetic.MyDouble;
import org.geogebra.common.kernel.commands.Commands;
import org.geogebra.common.kernel.geos.GeoCurveCartesian;
import org.geogebra.common.kernel.geos.GeoElement;
import org.geogebra.common.kernel.geos.GeoLine;
import org.geogebra.common.kernel.geos.GeoPoint;
import org.geogebra.common.kernel.kernelND.GeoPointND;
import org.geogebra.common.plugin.Operation;
/**
* Algo for intersection of a line with a curve adapted from
* AlgoIntersectLinePolyLine
*
* @author Michael
*/
public class AlgoIntersectLineCurve extends AlgoIntersectCoordSysCurve {
private GeoLine line; // input
@SuppressWarnings("javadoc")
protected OutputHandler<GeoElement> outputPoints; // output
/**
* common constructor
*
* @param c
* Construction
* @param labels
* labels
* @param l
* line
* @param p
* curve
*/
public AlgoIntersectLineCurve(Construction c, String[] labels, GeoLine l,
GeoCurveCartesian p) {
super(c);
outputPoints = createOutputPoints();
this.line = l;
this.curve = p;
compute();
setInputOutput(); // for AlgoElement
outputPoints.setLabelsMulti(labels);
update();
}
/**
* @param c
* cons
*/
public AlgoIntersectLineCurve(Construction c) {
super(c);
}
/**
*
* @return handler for output points
*/
protected OutputHandler<GeoElement> createOutputPoints() {
return new OutputHandler<GeoElement>(new elementFactory<GeoElement>() {
@Override
public GeoPoint newElement() {
GeoPoint p = new GeoPoint(cons);
p.setCoords(0, 0, 1);
p.setParentAlgorithm(AlgoIntersectLineCurve.this);
return p;
}
});
}
@Override
public Commands getClassName() {
return Commands.Intersect;
}
@Override
public int getRelatedModeID() {
return EuclidianConstants.MODE_INTERSECT;
}
// for AlgoElement
@Override
protected void setInputOutput() {
input = new GeoElement[2];
input[0] = line;
input[1] = curve;
setDependencies(); // done by AlgoElement
}
@Override
public void compute() {
Coords coeffs = line.getCoords();
ExpressionNode xFun = curve.getFun(0).getExpression();
ExpressionNode yFun = curve.getFun(1).getExpression();
FunctionVariable fv = curve.getFun(0).getFunctionVariable();
// substitute x = x(t), y=y(t) into
// ax + by + c
ExpressionNode enx, eny;
if (Kernel.isZero(coeffs.getZ())) {
enx = new ExpressionNode(kernel,
new MyDouble(kernel, coeffs.getX()), Operation.MULTIPLY,
xFun);
eny = new ExpressionNode(kernel,
new MyDouble(kernel, coeffs.getY()), Operation.MULTIPLY,
yFun);
enx = enx.plus(eny);
} else {
// Normalizing to (a/c)x + (b/c)y + 1 seems to work better
enx = new ExpressionNode(kernel,
new MyDouble(kernel, coeffs.getX() / coeffs.getZ()),
Operation.MULTIPLY, xFun);
eny = new ExpressionNode(kernel,
new MyDouble(kernel, coeffs.getY() / coeffs.getZ()),
Operation.MULTIPLY, yFun);
enx = enx.plus(eny).plus(1);
}
findIntersections(enx, fv);
}
@Override
protected void updatePoint(GeoPointND point, double paramVal,
FunctionVariable fv) {
ExpressionNode xFun = curve.getFun(0).getExpression();
ExpressionNode yFun = curve.getFun(1).getExpression();
fv.set(paramVal);
point.setCoords(xFun.evaluateDouble(), yFun.evaluateDouble(), 1.0);
}
@Override
protected boolean inCoordSys(GeoPointND point) {
return line.isIntersectionPointIncident((GeoPoint) point,
Kernel.MIN_PRECISION);
}
@Override
public String toString(StringTemplate tpl) {
return getLoc().getPlain("IntersectionPointOfAB",
((GeoElement) line).getLabel(tpl),
((GeoElement) curve).getLabel(tpl));
}
@Override
protected OutputHandler<GeoElement> getOutputPoints() {
return outputPoints;
}
}