package org.geogebra.common.kernel.algos;
import java.util.ArrayList;
import org.geogebra.common.euclidian.EuclidianViewInterfaceCommon;
import org.geogebra.common.kernel.Construction;
import org.geogebra.common.kernel.ConstructionDefaults;
import org.geogebra.common.kernel.Kernel;
import org.geogebra.common.kernel.KernelCAS;
import org.geogebra.common.kernel.Path;
import org.geogebra.common.kernel.Region;
import org.geogebra.common.kernel.Transform;
import org.geogebra.common.kernel.TransformDilate;
import org.geogebra.common.kernel.TransformMirror;
import org.geogebra.common.kernel.TransformRotate;
import org.geogebra.common.kernel.TransformTranslate;
import org.geogebra.common.kernel.Matrix.Coords;
import org.geogebra.common.kernel.arithmetic.Function;
import org.geogebra.common.kernel.commands.EvalInfo;
import org.geogebra.common.kernel.geos.GeoAngle;
import org.geogebra.common.kernel.geos.GeoAngle.AngleStyle;
import org.geogebra.common.kernel.geos.GeoBoolean;
import org.geogebra.common.kernel.geos.GeoConic;
import org.geogebra.common.kernel.geos.GeoConicPart;
import org.geogebra.common.kernel.geos.GeoCurveCartesian;
import org.geogebra.common.kernel.geos.GeoElement;
import org.geogebra.common.kernel.geos.GeoFunction;
import org.geogebra.common.kernel.geos.GeoFunctionNVar;
import org.geogebra.common.kernel.geos.GeoInputBox;
import org.geogebra.common.kernel.geos.GeoLine;
import org.geogebra.common.kernel.geos.GeoList;
import org.geogebra.common.kernel.geos.GeoLocus;
import org.geogebra.common.kernel.geos.GeoLocusable;
import org.geogebra.common.kernel.geos.GeoNumberValue;
import org.geogebra.common.kernel.geos.GeoNumeric;
import org.geogebra.common.kernel.geos.GeoPoint;
import org.geogebra.common.kernel.geos.GeoPoly;
import org.geogebra.common.kernel.geos.GeoPolyLine;
import org.geogebra.common.kernel.geos.GeoPolygon;
import org.geogebra.common.kernel.geos.GeoRay;
import org.geogebra.common.kernel.geos.GeoSegment;
import org.geogebra.common.kernel.geos.GeoVec3D;
import org.geogebra.common.kernel.geos.GeoVector;
import org.geogebra.common.kernel.implicit.AlgoImplicitCurveFunction;
import org.geogebra.common.kernel.implicit.AlgoImplicitPolyFunction;
import org.geogebra.common.kernel.implicit.AlgoIntersectImplicitpolyParametric;
import org.geogebra.common.kernel.implicit.AlgoIntersectImplicitpolyPolyLine;
import org.geogebra.common.kernel.implicit.AlgoIntersectImplicitpolys;
import org.geogebra.common.kernel.implicit.AlgoTangentImplicitpoly;
import org.geogebra.common.kernel.implicit.GeoImplicit;
import org.geogebra.common.kernel.implicit.GeoImplicitCurve;
import org.geogebra.common.kernel.kernelND.GeoConicND;
import org.geogebra.common.kernel.kernelND.GeoElementND;
import org.geogebra.common.kernel.kernelND.GeoImplicitSurfaceND;
import org.geogebra.common.kernel.kernelND.GeoLineND;
import org.geogebra.common.kernel.kernelND.GeoPointND;
import org.geogebra.common.kernel.kernelND.GeoVectorND;
import org.geogebra.common.main.Feature;
import org.geogebra.common.plugin.Operation;
import org.geogebra.common.util.debug.Log;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
public class AlgoDispatcher {
protected Construction cons;
public AlgoDispatcher(Construction cons) {
this.cons = cons;
}
/*
* to avoid multiple calculations of the intersection points of the same two
* objects, we remember all the intersection algorithms created
*/
protected ArrayList<AlgoIntersectAbstract> intersectionAlgos = new ArrayList<AlgoIntersectAbstract>();
public void removeIntersectionAlgorithm(AlgoIntersectAbstract algo) {
intersectionAlgos.remove(algo);
}
public void addIntersectionAlgorithm(AlgoIntersectAbstract algo) {
if (cons.getKernel().isSilentMode()) {
return;
}
intersectionAlgos.add(algo);
}
/** Point label with cartesian coordinates (x,y) */
final public GeoPoint Point(double x, double y,
boolean complex) {
int mode = complex ? Kernel.COORD_COMPLEX : Kernel.COORD_CARTESIAN;
GeoPoint p = new GeoPoint(cons, mode);
p.setCoords(x, y, 1.0);
return p;
}
public GeoVectorND Vector(String label) {
GeoVectorND ret = Vector(0, 0);
ret.setLabel(label);
return ret;
}
public GeoVectorND Vector() {
return Vector(0, 0);
}
/** Vector label with cartesian coordinates (x,y) */
final public GeoVector Vector(double x, double y) {
GeoVector v = new GeoVector(cons);
v.setCoords(x, y, 0.0);
v.setMode(Kernel.COORD_CARTESIAN);
return v;
}
/** Point on path with cartesian coordinates (x,y) */
final public GeoPoint Point(String label, Path path, double x, double y,
boolean addToConstruction, boolean complex, boolean coords2D) {
AlgoPointOnPath algo;
algo = new AlgoPointOnPath(cons, path, x, y, 0, addToConstruction);
GeoPoint p = (GeoPoint) algo.getP();
if (complex) {
p.setMode(Kernel.COORD_COMPLEX);
} else if (!coords2D) {
p.setCartesian3D();
}
if (addToConstruction) {
p.setLabel(label);
}
return p;
}
public GeoPointND Point(String label, Path path, Coords coords,
boolean addToConstruction, boolean complex, boolean coords2D) {
return Point(label, path, coords.getX(), coords.getY(),
addToConstruction, complex, coords2D);
}
/** Point anywhere on path with */
final public GeoPoint Point(String label, Path path, GeoNumberValue param) {
// try (0,0)
AlgoPointOnPath algo = null;
if (param == null) {
algo = new AlgoPointOnPath(cons, path, 0, 0);
} else {
algo = new AlgoPointOnPath(cons, path, param);
}
GeoPoint p = (GeoPoint) algo.getP();
// try (1,0)
if (!p.isDefined()) {
p.setCoords(1, 0, 1);
}
// try (random(),0)
if (!p.isDefined()) {
p.setCoords(Math.random(), 0, 1);
}
p.setLabel(label);
return p;
}
/********************
* ALGORITHMIC PART *
********************/
/**
* Line named label through Points P and Q
*/
final public GeoLine line(String label, GeoPoint P, GeoPoint Q) {
AlgoJoinPoints algo = new AlgoJoinPoints(cons, label, P, Q);
GeoLine g = algo.getLine();
return g;
}
/**
* Ray named label through Points P and Q
*/
final public GeoRay ray(String label, GeoPoint P, GeoPoint Q) {
AlgoJoinPointsRay algo = new AlgoJoinPointsRay(cons, label, P, Q);
return algo.getRay();
}
/**
* Ray named label through Point P with direction of vector v
*/
final public GeoRay ray(String label, GeoPoint P, GeoVector v) {
AlgoRayPointVector algo = new AlgoRayPointVector(cons, label, P, v);
return algo.getRay();
}
/**
* Line named label through Point P parallel to Line l
*/
final public GeoLine Line(String label, GeoPoint P, GeoLine l) {
AlgoLinePointLine algo = new AlgoLinePointLine(cons, label, P, l);
GeoLine g = algo.getLine();
return g;
}
/**
* Line named label through Point P orthogonal to vector v
*/
final public GeoLine OrthogonalLine(String label, GeoPoint P, GeoVector v) {
AlgoOrthoLinePointVector algo = new AlgoOrthoLinePointVector(cons,
label, P, v);
GeoLine g = algo.getLine();
return g;
}
/**
* Line named label through Point P orthogonal to line l
*/
final public GeoLine OrthogonalLine(String label, GeoPoint P, GeoLine l) {
AlgoOrthoLinePointLine algo = new AlgoOrthoLinePointLine(cons, label, P,
l);
GeoLine g = algo.getLine();
return g;
}
/**
* Line bisector of points A, B
*/
final public GeoLine LineBisector(String label, GeoPoint A, GeoPoint B) {
AlgoLineBisector algo = new AlgoLineBisector(cons, label, A, B);
GeoLine g = algo.getLine();
return g;
}
/**
* Line bisector of segment s
*/
final public GeoLine LineBisector(String label, GeoSegment s) {
AlgoLineBisectorSegment algo = new AlgoLineBisectorSegment(cons, label,
s);
GeoLine g = algo.getLine();
return g;
}
/**
* Angular bisector of points A, B, C
*/
final public GeoLine AngularBisector(String label, GeoPoint A, GeoPoint B,
GeoPoint C) {
AlgoAngularBisectorPoints algo = new AlgoAngularBisectorPoints(cons,
label, A, B, C);
GeoLine g = algo.getLine();
return g;
}
/**
* Angular bisectors of lines g, h
*/
final public GeoLine[] AngularBisector(String[] labels, GeoLine g,
GeoLine h) {
AlgoAngularBisectorLines algo = new AlgoAngularBisectorLines(cons,
labels, g, h);
GeoLine[] lines = algo.getLines();
return lines;
}
/**
* Vector named label from Point P to Q
*/
final public GeoVector Vector(String label, GeoPoint P, GeoPoint Q) {
AlgoVector algo = new AlgoVector(cons, label, P, Q);
GeoVector v = (GeoVector) algo.getVector();
v.setEuclidianVisible(true);
v.update();
// notifyUpdate(v);
return v;
}
/**
* Vector (0,0) to P
*/
final public GeoVectorND Vector(String label, GeoPointND P) {
GeoVectorND v = createVector(label, P);
v.setEuclidianVisible(true);
v.update();
// notifyUpdate(v);
return v;
}
protected GeoVectorND createVector(String label, GeoPointND P) {
AlgoVectorPoint algo = new AlgoVectorPoint(cons, label, P);
return algo.getVector();
}
/**
* Slope of line g
*/
final public GeoNumeric Slope(String label, GeoLine g, GeoFunction f) {
AlgoSlope algo = new AlgoSlope(cons, g, f);
GeoNumeric slope = algo.getSlope();
slope.setLabel(label);
return slope;
}
/**
* LineSegment named label from Point P to Point Q
*/
final public GeoSegment Segment(String label, GeoPoint P, GeoPoint Q) {
AlgoJoinPointsSegment algo = new AlgoJoinPointsSegment(cons, label, P,
Q);
GeoSegment s = algo.getSegment();
return s;
}
/**
* Creates a free list object with the given
*
* @param label
* @param geoElementList
* list of GeoElement objects
* @return
*/
final public GeoList List(String label,
ArrayList<GeoElement> geoElementList, boolean isIndependent) {
if (isIndependent) {
GeoList list = new GeoList(cons);
int size = geoElementList.size();
for (int i = 0; i < size; i++) {
list.add(geoElementList.get(i));
}
list.setLabel(label);
return list;
}
AlgoDependentList algoList = new AlgoDependentList(cons, label,
geoElementList);
return algoList.getGeoList();
}
/**
* Function dependent on coefficients of arithmetic expressions with
* variables, represented by trees.
*/
final public GeoFunction DependentFunction(Function fun, EvalInfo info) {
AlgoDependentFunction algo = new AlgoDependentFunction(cons, fun,
info.isLabelOutput(), !info.isUsingCAS());
// auto label for f'' to be f'' etc
return algo.getFunction();
}
public GeoInputBox textfield(String label, GeoElement geoElement) {
AlgoInputBox at = new AlgoInputBox(cons, label, geoElement);
return at.getResult();
}
/**
* Line named label through Point P with direction of vector v
*/
final public GeoLine Line(String label, GeoPoint P, GeoVector v) {
AlgoLinePointVector algo = new AlgoLinePointVector(cons, label, P, v);
GeoLine g = algo.getLine();
return g;
}
/**
* Creates new point B with distance n from A and new segment AB The
* labels[0] is for the segment, labels[1] for the new point
*/
final public GeoElement[] Segment(String[] labels, GeoPointND A,
GeoNumberValue n) {
// this is actually a macro
String pointLabel = null, segmentLabel = null;
if (labels != null) {
switch (labels.length) {
case 2:
segmentLabel = labels[0];
pointLabel = labels[1];
break;
case 1:
segmentLabel = labels[0];
break;
default:
}
}
return SegmentFixed(pointLabel, segmentLabel, A, n);
}
protected GeoElement[] SegmentFixed(String pointLabel, String segmentLabel,
GeoPointND a, GeoNumberValue n) {
GeoPoint A = (GeoPoint) a;
// create a circle around A with radius n
AlgoCirclePointRadius algoCircle = new AlgoCirclePointRadius(cons, A,
n);
cons.removeFromConstructionList(algoCircle);
// place the new point on the circle
AlgoPointOnPath algoPoint = new AlgoPointOnPath(cons,
algoCircle.getCircle(), A.inhomX + n.getDouble(), A.inhomY);
algoPoint.getP().setLabel(pointLabel);
// return segment and new point
GeoElement[] ret = {
Segment(segmentLabel, A, (GeoPoint) algoPoint.getP()),
(GeoElement) algoPoint.getP() };
return ret;
}
/**
* Creates a new point C by rotating B around A using angle alpha and a new
* angle BAC (for positive orientation) resp. angle CAB (for negative
* orientation). The labels[0] is for the angle, labels[1] for the new point
*/
@SuppressFBWarnings({ "SF_SWITCH_FALLTHROUGH",
"missing break is deliberate" })
final public GeoElement[] Angle(String[] labels, GeoPoint B, GeoPoint A,
GeoNumberValue alpha, boolean posOrientation) {
// this is actually a macro
String pointLabel = null, angleLabel = null;
if (labels != null) {
switch (labels.length) {
default:
// do nothing
break;
case 2:
pointLabel = labels[1];
// fall through
case 1:
angleLabel = labels[0];
}
}
// rotate B around A using angle alpha
GeoPoint C = (GeoPoint) Rotate(pointLabel, B, alpha, A)[0];
// create angle according to orientation
GeoAngle angle;
if (posOrientation) {
angle = Angle(angleLabel, B, A, C);
} else {
angle = Angle(angleLabel, C, A, B);
}
// ensure we won't get angle e.g. in 0-180degrees due to default
angle.setAngleStyle(AngleStyle.ANTICLOCKWISE);
// return angle and new point
GeoElement[] ret = { angle, C };
return ret;
}
/**
* rotate geoRot by angle phi around Q
*/
public GeoElement[] Rotate(String label, GeoElement geoRot,
GeoNumberValue phi, GeoPointND Q) {
Transform t = new TransformRotate(cons, phi, Q);
return t.transform(geoRot, label);
}
/**
* Angle named label between line g and line h
*/
final public GeoAngle Angle(String label, GeoLine g, GeoLine h) {
AlgoAngleLines algo = new AlgoAngleLines(cons, label, g, h);
GeoAngle angle = algo.getAngle();
return angle;
}
/**
* Angle named label between vector v and vector w
*/
final public GeoAngle Angle(String label, GeoVector v, GeoVector w) {
AlgoAngleVectors algo = new AlgoAngleVectors(cons, label, v, w);
GeoAngle angle = algo.getAngle();
return angle;
}
/**
* Angle named label between three points
*/
final public GeoAngle Angle(String label, GeoPoint A, GeoPoint B,
GeoPoint C) {
AlgoAnglePoints algo = new AlgoAnglePoints(cons, label, A, B, C);
GeoAngle angle = algo.getAngle();
return angle;
}
/**
* all angles of given polygon
*/
final public GeoElement[] Angles(String[] labels, GeoPolygon poly) {
AlgoAnglePolygon algo = new AlgoAnglePolygon(cons, labels, poly);
GeoElement[] angles = algo.getAngles();
// for (int i=0; i < angles.length; i++) {
// angles[i].setAlphaValue(0.0f);
// }
return angles;
}
public GeoNumeric getDefaultNumber(boolean isAngle) {
return (GeoNumeric) cons.getConstructionDefaults()
.getDefaultGeo(isAngle ? ConstructionDefaults.DEFAULT_ANGLE
: ConstructionDefaults.DEFAULT_NUMBER);
}
/**
* circle with through points A, B, C
*/
final public GeoConic Circle(String label, GeoPoint A, GeoPoint B,
GeoPoint C) {
AlgoCircleThreePoints algo = new AlgoCircleThreePoints(cons, label, A,
B, C);
GeoConic circle = (GeoConic) algo.getCircle();
circle.setToSpecific();
circle.update();
// notifyUpdate(circle);
return circle;
}
/**
* circle arc from three points
*/
final public GeoConicPart CircumcircleArc(String label, GeoPoint A,
GeoPoint B, GeoPoint C) {
AlgoConicPartCircumcircle algo = new AlgoConicPartCircumcircle(cons,
label, A, B, C, GeoConicPart.CONIC_PART_ARC);
return algo.getConicPart();
}
/**
* circle sector from three points
*/
final public GeoConicPart CircumcircleSector(String label, GeoPoint A,
GeoPoint B, GeoPoint C) {
AlgoConicPartCircumcircle algo = new AlgoConicPartCircumcircle(cons,
label, A, B, C, GeoConicPart.CONIC_PART_SECTOR);
return algo.getConicPart();
}
/**
* circle arc/sector from center and two points on arc/sector
*/
final public GeoConicPart CircleArcSector(String label, GeoPoint A,
GeoPoint B, GeoPoint C, int type) {
AlgoConicPartCircle algo = new AlgoConicPartCircle(cons, label, A, B, C,
type);
return algo.getConicPart();
}
/**
* Center of conic
*/
final public GeoPointND Center(String label, GeoConicND c) {
AlgoCenterConic algo = new AlgoCenterConic(cons, label, c);
GeoPointND midpoint = algo.getPoint();
return midpoint;
}
/*********************************************
* CONIC PART
*********************************************/
/**
* circle with midpoint M and radius r
*/
public GeoConicND Circle(String label, GeoPointND M, GeoNumberValue r) {
AlgoCirclePointRadius algo = new AlgoCirclePointRadius(cons,
(GeoPoint) M, r);
GeoConic circle = algo.getCircle();
circle.setToSpecific();
circle.setLabel(label);
return circle;
}
/**
* circle with midpoint M and radius segment Michael Borcherds 2008-03-15
*/
final public GeoConic Circle(String label, GeoPoint A, GeoSegment segment) {
AlgoCirclePointRadius algo = new AlgoCirclePointRadius(cons, A, segment);
GeoConic circle = algo.getCircle();
circle.setToSpecific();
circle.setLabel(label);
return circle;
}
/**
* circle with midpoint M through point P
*/
final public GeoConic Circle(String label, GeoPoint M, GeoPoint P) {
AlgoCircleTwoPoints algo = new AlgoCircleTwoPoints(cons, M, P);
GeoConic circle = algo.getCircle();
circle.setToSpecific();
circle.setLabel(label);
return circle;
}
/**
* semicircle with midpoint M through point P
*/
final public GeoConicPart Semicircle(String label, GeoPoint M, GeoPoint P) {
AlgoSemicircle algo = new AlgoSemicircle(cons, label, M, P);
return algo.getSemicircle();
}
/**
* parabola with focus F and line l
*/
final public GeoConicND Parabola(String label, GeoPointND F, GeoLineND l) {
AlgoParabolaPointLine algo = new AlgoParabolaPointLine(cons, label, F,
l);
return algo.getParabola();
}
/**
* ellipse with foci A, B and length of first half axis a
*/
final public GeoConicND Ellipse(String label, GeoPointND A, GeoPointND B,
GeoNumberValue a) {
AlgoEllipseFociLength algo = new AlgoEllipseFociLength(cons, label, A,
B, a);
return algo.getConic();
}
/**
* ellipse with foci A, B passing thorugh C Michael Borcherds 2008-04-06
*/
final public GeoConicND EllipseHyperbola(String label, GeoPointND A,
GeoPointND B, GeoPointND C, final int type) {
AlgoEllipseHyperbolaFociPoint algo = new AlgoEllipseHyperbolaFociPoint(
cons, label, A, B, C, type);
return algo.getConic();
}
/**
* hyperbola with foci A, B and length of first half axis a
*/
final public GeoConicND Hyperbola(String label, GeoPointND A, GeoPointND B,
GeoNumberValue a) {
AlgoHyperbolaFociLength algo = new AlgoHyperbolaFociLength(cons, label,
A, B, a);
return algo.getConic();
}
/**
* conic through five points
*/
final public GeoConicND Conic(String label, GeoPoint[] points) {
AlgoConicFivePoints algo = new AlgoConicFivePoints(cons, label, points);
GeoConicND conic = algo.getConic();
return conic;
}
/**
* diameter line conjugate to direction of g relative to c
*/
final public GeoElement DiameterLine(String label, GeoLineND g,
GeoConicND c) {
AlgoDiameterLine algo = new AlgoDiameterLine(cons, label, c, g);
return (GeoElement) algo.getDiameter();
}
/**
* diameter line conjugate to v relative to c
*/
final public GeoElement DiameterLine(String label, GeoVectorND v,
GeoConicND c) {
AlgoDiameterVector algo = new AlgoDiameterVector(cons, label, c, v);
return (GeoElement) algo.getDiameter();
}
/**
* Regular polygon with vertices A and B and n total vertices. The labels
* name the polygon itself, its segments and points
*/
final public GeoElement[] RegularPolygon(String[] labels, GeoPointND A,
GeoPointND B, GeoNumberValue n) {
AlgoPolygonRegular algo = new AlgoPolygonRegular(cons, labels, A, B, n);
return algo.getOutput();
}
/**
* Area named label of conic
*/
final public GeoNumeric Area(String label, GeoConicND c) {
AlgoAreaConic algo = new AlgoAreaConic(cons, label, c);
GeoNumeric num = algo.getArea();
return num;
}
/**
* Perimeter named label of GeoPolygon
*/
final public GeoNumeric Perimeter(String label, GeoPolygon polygon) {
AlgoPerimeterPoly algo = new AlgoPerimeterPoly(cons, label, polygon);
return algo.getCircumference();
}
/**
* Circumference named label of GeoConic
*/
final public GeoNumeric Circumference(String label, GeoConicND conic) {
AlgoCircumferenceConic algo = new AlgoCircumferenceConic(cons, label,
conic);
return algo.getCircumference();
}
/**
* dilate geoRot by r from S
*/
final public GeoElement[] Dilate(String label, GeoElement geoDil,
GeoNumberValue r, GeoPoint S) {
Transform t = new TransformDilate(cons, r, S);
return t.transform(geoDil, label);
}
/**
* Distance named label between points P and Q
*/
final public GeoNumeric Distance(String label, GeoPointND P, GeoPointND Q) {
AlgoDistancePoints algo = new AlgoDistancePoints(cons, label, P, Q);
GeoNumeric num = algo.getDistance();
return num;
}
/**
* Distance named label between point P and line g
*/
final public GeoNumeric Distance(String label, GeoPointND P, GeoElementND g) {
AlgoDistancePointObject algo = new AlgoDistancePointObject(cons, label,
P, g);
GeoNumeric num = algo.getDistance();
return num;
}
final public GeoImplicit ImplicitPoly(String label, GeoFunctionNVar func) {
AlgoImplicitPolyFunction algo = new AlgoImplicitPolyFunction(cons,
label, func);
GeoImplicit implicitPoly = algo.getImplicitPoly();
return implicitPoly;
}
final public GeoImplicitCurve ImplicitCurve(String label,
GeoFunctionNVar func) {
AlgoImplicitCurveFunction algo = new AlgoImplicitCurveFunction(cons,
label, func);
return algo.getImplicitCurve();
}
/********************
* ALGORITHMIC PART *
********************/
/** Point in region with cartesian coordinates (x,y) */
final public GeoPoint PointIn(String label, Region region, double x,
double y, boolean addToConstruction, boolean complex,
boolean coords2D) {
boolean oldMacroMode = false;
if (!addToConstruction) {
oldMacroMode = cons.isSuppressLabelsActive();
cons.setSuppressLabelCreation(true);
}
AlgoPointInRegion algo = new AlgoPointInRegion(cons, label, region, x,
y);
// Application.debug("PointIn - \n x="+x+"\n y="+y);
GeoPoint p = algo.getP();
if (complex) {
p.setMode(Kernel.COORD_COMPLEX);
} else if (!coords2D) {
p.setCartesian3D();
p.update();
}
if (!addToConstruction) {
cons.setSuppressLabelCreation(oldMacroMode);
}
return p;
}
public GeoPointND PointIn(String label, Region region, Coords coords,
boolean addToConstruction, boolean complex, boolean coords2D) {
return PointIn(label, region, coords.getX(), coords.getY(),
addToConstruction, complex, coords2D);
}
/**
* Midpoint M = (P + Q)/2
*/
final public GeoPoint Midpoint(String label, GeoPoint P, GeoPoint Q) {
AlgoMidpoint algo = new AlgoMidpoint(cons, label, P, Q);
GeoPoint M = algo.getPoint();
return M;
}
/**
* Midpoint of segment
*/
final public GeoPoint Midpoint(GeoSegment s) {
AlgoMidpointSegment algo = new AlgoMidpointSegment(cons, s);
GeoPoint M = algo.getPoint();
return M;
}
/**
* Length[list]
*/
final public GeoNumeric Length(String label, GeoList list) {
AlgoListLength algo = new AlgoListLength(cons, label, list);
return algo.getLength();
}
/**
* Length[locus]
*/
final public GeoNumeric Length(String label, GeoLocusable locus) {
AlgoLengthLocus algo = new AlgoLengthLocus(cons, label, locus);
return algo.getLength();
}
/**
* polygon P[0], ..., P[n-1] The labels name the polygon itself and its
* segments
*/
public GeoElement[] Polygon(String[] labels, GeoPointND[] P) {
AlgoPolygon algo = new AlgoPolygon(cons, labels, P);
return algo.getOutput();
}
// G.Sturr 2010-3-14
/**
* Polygon with vertices from geolist Only the polygon is labeled, segments
* are not labeled
*/
public GeoElement[] Polygon(String[] labels, GeoList pointList) {
AlgoPolygon algo = new AlgoPolygon(cons, labels, pointList);
return algo.getOutput();
}
// END G.Sturr
/**
* polygon P[0], ..., P[n-1] The labels name the polygon itself and its
* segments
*/
final public GeoElement[] PolyLine(String label, GeoPointND[] P,
boolean penStroke) {
AlgoElement algo = penStroke ? getStrokeAlgo(P)
: new AlgoPolyLine(cons, P, null);
algo.getOutput(0).setLabel(label);
return algo.getOutput();
}
public AlgoElement getStrokeAlgo(GeoPointND[] p) {
return cons.getApplication().has(Feature.PEN_IS_LOCUS)
? new AlgoLocusStroke(cons, p) : new AlgoPenStroke(cons, p);
}
/**
* Intersect[polygon,polygon] G. Sturr
*
* modified by thilina
*/
final public GeoElement[] IntersectPolygons(String[] labels,
GeoPolygon poly0, GeoPolygon poly1, boolean asRegion) {
if (asRegion) {
AlgoPolygonIntersection algo = new AlgoPolygonIntersection(cons,
labels, poly0, poly1);
GeoElement[] polygon = algo.getOutput();
return polygon;
} else {
AlgoIntersectPolyLines algo = new AlgoIntersectPolyLines(cons,
labels, poly0, poly1, true, true);
return algo.getOutput();
}
}
/**
* Intersect[polygon, polygon] as region. This is used when loading saved
* files.
*
* @author thilina
*/
final public GeoElement[] IntersectPolygons(String[] labels,
GeoPolygon poly0, GeoPolygon poly1, int[] outputSizes) {
AlgoPolygonIntersection algo = new AlgoPolygonIntersection(cons, labels,
poly0, poly1, outputSizes);
GeoElement[] polygon = algo.getOutput();
return polygon;
}
/**
* Union[polygon,polygon] G. Sturr
*/
final public GeoElement[] Union(String[] labels, GeoPolygon poly0,
GeoPolygon poly1) {
AlgoPolygonUnion algo = new AlgoPolygonUnion(cons, labels, poly0,
poly1);
GeoElement[] polygon = algo.getOutput();
return polygon;
}
/**
* Union[polygon, polygon] as region. This is used when loading saved files
*
* @author thilina
*/
final public GeoElement[] Union(String[] labels, GeoPolygon poly0,
GeoPolygon poly1, int[] outputSizes) {
AlgoPolygonUnion algo = new AlgoPolygonUnion(cons, labels, poly0, poly1,
outputSizes);
GeoElement[] polygon = algo.getOutput();
return polygon;
}
/**
* Difference[polygon,polygon]
*
* @author thilina
*/
final public GeoElement[] Difference(String[] labels, GeoPolygon poly0,
GeoPolygon poly1) {
AlgoPolygonDifference algo = new AlgoPolygonDifference(cons, labels,
poly0, poly1, null);
GeoElement[] polygon = algo.getOutput();
return polygon;
}
/**
* Difference[polygon, polygon] as region. This is used when loading saved
* files
*
* @author thilina
*/
final public GeoElement[] Difference(String[] labels, GeoPolygon poly0,
GeoPolygon poly1, int[] outputSizes) {
AlgoPolygonDifference algo = new AlgoPolygonDifference(cons, labels,
poly0, poly1, null, outputSizes);
GeoElement[] polygon = algo.getOutput();
return polygon;
}
/**
* Difference[polygon,polygon, boolean exclusive]
*
* @author thilina
*/
final public GeoElement[] Difference(String[] labels, GeoPolygon poly0,
GeoPolygon poly1, GeoBoolean exclusive) {
AlgoPolygonDifference algo = new AlgoPolygonDifference(cons, labels,
poly0, poly1, exclusive);
GeoElement[] polygon = algo.getOutput();
return polygon;
}
/**
* locus line for Q dependent on P. Note: P must be a point on a path.
*/
final public GeoElement Locus(String label, GeoPointND Q, GeoPointND P) {
if (!LocusCheck(P, Q)) {
return null;
}
if (P.getPath() instanceof GeoList) {
if (((GeoList) P.getPath()).shouldUseAlgoLocusList(true)) {
return (new AlgoLocusList(cons, label, (GeoPoint) Q,
(GeoPoint) P)).getLocus();
}
}
return (new AlgoLocus(cons, label, Q, P)).getLocus();
}
final public boolean LocusCheck(GeoPointND P, GeoPointND Q) {
if (P.getPath() == null || Q.getPath() != null
|| !((GeoElement) P).isParentOf(Q)) {
return false;
}
return true;
}
/**
* locus line for Q dependent on P. Note: P must be a visible slider
*/
final public GeoElement Locus(String label, GeoPointND Q, GeoNumeric P) {
if (!LocusCheck(Q, P)) {
return null;
}
return LocusNoCheck(label, Q, P);
}
public static boolean LocusCheck(GeoPointND Q, GeoNumeric P) {
return P.isSlider() && P.isDefined() && P.isAnimatable()
&& Q.getPath() == null && P.isParentOf(Q);
}
protected GeoElement LocusNoCheck(String label, GeoPointND Q,
GeoNumeric P) {
AlgoLocusSlider algo = new AlgoLocusSlider(cons, label, (GeoPoint) Q,
P);
return algo.getLocus();
}
/**
* Distance named label between line g and line h
*/
public GeoNumeric Distance(String label, GeoLineND g, GeoLineND h) {
AlgoDistanceLineLine algo = new AlgoDistanceLineLine(cons, label,
(GeoLine) g, (GeoLine) h);
GeoNumeric num = algo.getDistance();
return num;
}
/**
* IntersectLines yields intersection point named label of lines g, h
*/
public GeoPointND IntersectLines(String label, GeoLineND g, GeoLineND h) {
AlgoIntersectLines algo = new AlgoIntersectLines(cons, label,
(GeoLine) g, (GeoLine) h);
GeoPoint S = algo.getPoint();
return S;
}
/**
* Solves a system of ODEs
*/
final public GeoLocus[] NSolveODE(String[] labels, GeoList fun,
GeoNumeric startX, GeoList startY, GeoNumeric endX) {
AlgoNSolveODE algo = new AlgoNSolveODE(cons, labels, fun, startX,
startY, endX);
return algo.getResult();
}
/**
* yields intersection points named label of line g and polyLine p
*/
final public GeoElement[] IntersectLinePolyLine(String[] labels, GeoLine g,
GeoPolyLine p) {
AlgoIntersectLinePolyLine algo = new AlgoIntersectLinePolyLine(cons,
labels, g, p);
return algo.getOutput();
}
/**
* yields intersection points named label of line g and polyLine p
*/
final public GeoElement[] IntersectLineCurve(String[] labels, GeoLine g,
GeoCurveCartesian p) {
AlgoIntersectLineCurve algo = new AlgoIntersectLineCurve(cons, labels,
g, p);
return algo.getOutput();
}
/**
* yields intersection points named label of polyLine g and polyLine p
*
* @author thilina
*/
final public GeoElement[] IntersectPolyLines(String[] labels, GeoPolyLine g,
GeoPolyLine p) {
AlgoIntersectPolyLines algo = new AlgoIntersectPolyLines(cons, labels,
g, p, false, false);
return algo.getOutput();
}
/**
* yields intersection points named label of curve g and curve p
*/
final public GeoElement[] IntersectCurveCurve(String[] labels,
GeoCurveCartesian g, GeoCurveCartesian p) {
AlgoIntersectCurveCurve algo = new AlgoIntersectCurveCurve(cons, labels,
g, p);
return algo.getOutput();
}
/**
* yields intersection points named label of curve c1 and curve c1 (x,y)
* determines the parameters for the iteration
*/
final public GeoElement[] IntersectCurveCurveSingle(String[] labels,
GeoCurveCartesian c1, GeoCurveCartesian c2, double x, double y) {
GeoPoint p = new GeoPoint(cons, x, y, 1.0);
double t1 = c1.getClosestParameter(p,
(c1.getMinParameter() + c1.getMaxParameter()) / 2);
double t2 = c2.getClosestParameter(p,
(c2.getMinParameter() + c2.getMaxParameter()) / 2);
AlgoIntersectCurveCurve algo = new AlgoIntersectCurveCurve(cons, labels,
c1, c2, new GeoNumeric(cons, t1), new GeoNumeric(cons, t2));
return algo.getOutput();
}
/**
* yields intersection points named label of line g and polygon p (as
* boundary)
*/
final public GeoElement[] IntersectLinePolygon(String[] labels, GeoLine g,
GeoPolygon p) {
AlgoIntersectLinePolyLine algo = new AlgoIntersectLinePolyLine(cons,
labels, g, p);
return algo.getOutput();
}
/**
* yields intersection points named label of PolyLine g and polygon p (as
* boundary)
*
* @author thilina
*/
final public GeoElement[] IntersectPolyLinePolygon(String[] labels,
GeoPolyLine g, GeoPolygon p) {
AlgoIntersectPolyLines algo = new AlgoIntersectPolyLines(cons, labels,
g, p, false, true);
return algo.getOutput();
}
/**
* Intersects f and g using starting point A (with Newton's root finding)
*/
final public GeoPoint IntersectFunctions(String label, GeoFunction f,
GeoFunction g, GeoPoint A) {
AlgoIntersectFunctionsNewton algo = new AlgoIntersectFunctionsNewton(
cons, label, f, g, A);
GeoPoint S = algo.getIntersectionPoint();
return S;
}
/**
* Intersects f and l using starting point A (with Newton's root finding)
*/
final public GeoPoint IntersectFunctionLine(String label, GeoFunction f,
GeoLine l, GeoPoint A) {
AlgoIntersectFunctionLineNewton algo = new AlgoIntersectFunctionLineNewton(
cons, label, f, l, A);
GeoPoint S = algo.getIntersectionPoint();
return S;
}
/**
* IntersectLineConic yields intersection points named label1, label2 of
* line g and conic c
*/
public GeoPointND[] IntersectLineConic(String[] labels, GeoLineND g,
GeoConicND c) {
AlgoIntersectLineConic algo = getIntersectionAlgorithm((GeoLine) g,
(GeoConic) c);
algo.setPrintedInXML(true);
GeoPoint[] points = algo.getIntersectionPoints();
GeoElement.setLabels(labels, points);
return points;
}
/**
* IntersectPolyLineConic yields intersection points of polyLine g and conic
* c
*/
public GeoElement[] IntersectPolyLineConic(String[] labels, GeoPolyLine g,
GeoConic c) {
AlgoIntersectPolyLineConic algo = getIntersectionAlgorithm(
g, c);
algo.setPrintedInXML(true);
GeoElement[] points = algo.getOutput();
GeoElement.setLabels(labels, points);
return points;
}
/**
* IntersectPolygonConic yields intersection points of polygon g and conic c
*/
public GeoElement[] IntersectPolygonConic(String[] labels, GeoPolygon g,
GeoConic c, boolean asRegion) {
if (asRegion) {
// TODO
return null;
} else {
AlgoIntersectPolyLineConic algo = getIntersectionAlgorithm(
g, c);
algo.setPrintedInXML(true);
GeoElement[] points = algo.getOutput();
GeoElement.setLabels(labels, points);
return points;
}
}
/**
* IntersectConics yields intersection points named label1, label2, label3,
* label4 of conics c1, c2
*/
public GeoPointND[] IntersectConics(String[] labels, GeoConicND a,
GeoConicND b) {
AlgoIntersectConics algo = getIntersectionAlgorithm((GeoConic) a,
(GeoConic) b);
algo.setPrintedInXML(true);
GeoPoint[] points = algo.getIntersectionPoints();
GeoElement.setLabels(labels, points);
return points;
}
/**
* IntersectPolynomials yields all intersection points of polynomials a, b
*/
final public GeoPoint[] IntersectPolynomials(String[] labels, GeoFunction a,
GeoFunction b) {
if (isConditionalPolynomial(a) && b.isPolynomialFunction(false)) {
AlgoRootsPolynomialInterval algo = new AlgoRootsPolynomialInterval(
cons, labels, a, b);
GeoPoint[] g = algo.getRootPoints();
return g;
}
if (isConditionalPolynomial(b) && a.isPolynomialFunction(false)) {
AlgoRootsPolynomialInterval algo = new AlgoRootsPolynomialInterval(
cons, labels, b, a);
GeoPoint[] g = algo.getRootPoints();
return g;
}
// TODO decide polynomial when CAS not loaded
if (!a.isPolynomialFunction(false) || !b.isPolynomialFunction(false)) {
// dummy point
GeoPoint A = new GeoPoint(cons);
A.setZero();
// we must check that getLabels() didn't return null
String label = labels == null ? null : labels[0];
AlgoIntersectFunctionsNewton algo = new AlgoIntersectFunctionsNewton(
cons, label, a, b, A);
GeoPoint[] ret = { algo.getIntersectionPoint() };
return ret;
}
AlgoIntersectPolynomials algo = getIntersectionAlgorithm(a, b);
algo.setPrintedInXML(true);
algo.setLabels(labels);
GeoPoint[] points = algo.getIntersectionPoints();
return points;
}
/**
* get only one intersection point of two polynomials a, b that is near to
* the given location (xRW, yRW)
*/
final public GeoPoint IntersectPolynomialsSingle(String label,
GeoFunction a, GeoFunction b, double xRW, double yRW) {
if (!a.isPolynomialFunction(false) || !b.isPolynomialFunction(false)) {
return null;
}
AlgoIntersectPolynomials algo = getIntersectionAlgorithm(a, b);
int index = algo.getClosestPointIndex(xRW, yRW);
AlgoIntersectSingle salgo = new AlgoIntersectSingle(label, algo, index);
GeoPoint point = salgo.getPoint();
return point;
}
private boolean isConditionalPolynomial(GeoFunction f) {
if (f.getFunctionExpression() != null && Operation.IF
.equals(f.getFunctionExpression().getOperation())) {
Function test = new Function(
f.getFunctionExpression().deepCopy(cons.getKernel())
.getRightTree());
test.initFunction();
return test.isPolynomialFunction(false, true);
}
return false;
}
/**
* IntersectPolyomialLine yields all intersection points of polynomial f and
* line l
*/
final public GeoPoint[] IntersectPolynomialLine(String[] labels,
GeoFunction f, GeoLine l, GeoPoint pref) {
// TODO decide polynomial when CAS not loaded ?
if (isConditionalPolynomial(f)) {
AlgoRootsPolynomialInterval algo = new AlgoRootsPolynomialInterval(
cons, labels, f, l);
GeoPoint[] g = algo.getRootPoints();
return g;
}
if (!f.isPolynomialFunction(false)) {
// dummy point
GeoPoint A = pref;
if (A == null) {
A = new GeoPoint(cons);
A.setZero();
}
// we must check that getLabels() didn't return null
String label = labels == null ? null : labels[0];
AlgoIntersectFunctionLineNewton algo = new AlgoIntersectFunctionLineNewton(
cons, label, f, l, A);
GeoPoint[] ret = { algo.getIntersectionPoint() };
return ret;
}
AlgoIntersectPolynomialLine algo = getIntersectionAlgorithm(f, l);
algo.setPrintedInXML(true);
algo.setLabels(labels);
GeoPoint[] points = algo.getIntersectionPoints();
return points;
}
/**
* Intersect function/polynomial-polyLine yields all intersection points of
* GeoFunction f and polyLine l
*
* @author thilina
*/
final public GeoElement[] IntersectPolynomialPolyLine(String[] labels,
GeoFunction f, GeoPolyLine pl) {
AlgoIntersectPolynomialPolyLine algo = new AlgoIntersectPolynomialPolyLine(
cons, labels, f, pl, false);
return algo.getOutput();
}
/**
* Intersect function/Polynomial-polygon yields all intersection points of
* GeoFunction f and polygon pl
*
* @author thilina
*/
final public GeoElement[] IntersectPolynomialPolygon(String[] labels,
GeoFunction f, GeoPolygon pl) {
AlgoIntersectPolynomialPolyLine algo = new AlgoIntersectPolynomialPolyLine(
cons, labels, f, pl, true);
return algo.getOutput();
}
/**
* Intersect function-polyline yields all intersection points of GeoFunction
* f and polyline pl
*
* @author thilina
*/
final public GeoElement[] IntersectNPFunctionPolyLine(String[] labels,
GeoFunction f, GeoPolyLine pl, GeoPoint initPoint) {
AlgoIntersectNpFunctionPolyLine algo = new AlgoIntersectNpFunctionPolyLine(
cons, labels, initPoint, f, pl, false);
return algo.getOutput();
}
/**
* Intersect function-polygon yields all intersection points of GeoFunction
* f and polygon pl
*
* @author thilina
*/
final public GeoElement[] IntersectNPFunctionPolygon(String[] labels,
GeoFunction f, GeoPolygon pl, GeoPoint initPoint) {
AlgoIntersectNpFunctionPolyLine algo = new AlgoIntersectNpFunctionPolyLine(
cons, labels, initPoint, f, pl, true);
return algo.getOutput();
}
/**
* get only one intersection point of two conics that is near to the given
* location (xRW, yRW)
*/
final public GeoPoint IntersectConicsSingle(String label, GeoConic a,
GeoConic b, double xRW, double yRW) {
AlgoIntersectConics algo = getIntersectionAlgorithm(a, b);
int index = algo.getClosestPointIndex(xRW, yRW);
AlgoIntersectSingle salgo = new AlgoIntersectSingle(label, algo, index);
GeoPoint point = salgo.getPoint();
return point;
}
/**
* get intersection points of a polynomial and a conic
*/
final public GeoPoint[] IntersectPolynomialConic(String[] labels,
GeoFunction f, GeoConic c) {
AlgoIntersectPolynomialConic algo = getIntersectionAlgorithm(f, c);
algo.setPrintedInXML(true);
GeoPoint[] points = algo.getIntersectionPoints();
// GeoElement.setLabels(labels, points);
algo.setLabels(labels);
return points;
}
/**
* get intersection points of a implicitPoly and a line
*/
final public GeoPoint[] IntersectImplicitpolyLine(String[] labels,
GeoImplicit p, GeoLine l) {
AlgoIntersectImplicitpolyParametric algo = getIntersectionAlgorithm(p,
l);
algo.setPrintedInXML(true);
GeoPoint[] points = algo.getIntersectionPoints();
algo.setLabels(labels);
return points;
}
/**
* get intersection points of a implicitPoly and a polyline
*/
final public GeoPoint[] IntersectImplicitpolyPolyLine(String[] labels,
GeoImplicit p, GeoPolyLine l) {
AlgoIntersectImplicitpolyPolyLine algo = getIntersectionAlgorithm(p, l);
algo.setPrintedInXML(true);
GeoPoint[] points = algo.getIntersectionPoints();
algo.setLabels(labels);
return points;
}
/**
* get intersection points of a implicitPoly and a polygon
*/
final public GeoPoint[] IntersectImplicitpolyPolygon(String[] labels,
GeoImplicit p, GeoPolygon l) {
AlgoIntersectImplicitpolyPolyLine algo = getIntersectionAlgorithm(p, l);
algo.setPrintedInXML(true);
GeoPoint[] points = algo.getIntersectionPoints();
algo.setLabels(labels);
return points;
}
/**
* get intersection points of a implicitPoly and a polynomial
*/
final public GeoPoint[] IntersectImplicitpolyPolynomial(String[] labels,
GeoImplicit p, GeoFunction f) {
// if (!f.isPolynomialFunction(false))
// return null;
AlgoIntersectImplicitpolyParametric algo = getIntersectionAlgorithm(p,
f);
algo.setPrintedInXML(true);
GeoPoint[] points = algo.getIntersectionPoints();
algo.setLabels(labels);
return points;
}
/**
* get intersection points of two implicitPolys
*/
final public GeoPoint[] IntersectImplicitpolys(String[] labels,
GeoImplicit p1, GeoImplicit p2) {
AlgoIntersectImplicitpolys algo = getIntersectionAlgorithm(p1, p2);
algo.setPrintedInXML(true);
GeoPoint[] points = algo.getIntersectionPoints();
algo.setLabels(labels);
return points;
}
/**
* get intersection points of implicitPoly and conic
*/
final public GeoPoint[] IntersectImplicitpolyConic(String[] labels,
GeoImplicit p1, GeoConic c1) {
AlgoIntersectImplicitpolys algo = getIntersectionAlgorithm(p1, c1);
algo.setPrintedInXML(true);
GeoPoint[] points = algo.getIntersectionPoints();
algo.setLabels(labels);
return points;
}
final public GeoPoint[] IntersectImplicitCurveLine(String[] labels,
GeoImplicitCurve curve, GeoLine line) {
AlgoIntersectImplicitpolyParametric algo = new AlgoIntersectImplicitpolyParametric(
cons, curve, line);
GeoPoint[] points = algo.getIntersectionPoints();
algo.setLabels(labels);
return points;
}
final public GeoPoint[] IntersectImplicitCurveConic(String[] labels,
GeoImplicitCurve curve, GeoConic conic) {
AlgoIntersectImplicitpolys algo = new AlgoIntersectImplicitpolys(cons,
curve, conic);
GeoPoint[] points = algo.getIntersectionPoints();
algo.setLabels(labels);
return points;
}
final public GeoPoint[] IntersectImplicitCurveFunction(String[] labels,
GeoImplicitCurve curve, GeoFunction func) {
AlgoIntersectImplicitpolyParametric algo = new AlgoIntersectImplicitpolyParametric(
cons, curve, func);
GeoPoint[] points = algo.getIntersectionPoints();
algo.setLabels(labels);
return points;
}
final public GeoPoint[] IntersectImplicitCurveImpCurve(String[] labels,
GeoImplicit curve, GeoImplicit impCurve) {
AlgoIntersectImplicitpolys algo = new AlgoIntersectImplicitpolys(cons,
curve, impCurve);
GeoPoint[] points = algo.getIntersectionPoints();
algo.setLabels(labels);
return points;
}
public GeoElement[] IntersectImplicitSurfaceLine(String[] labels,
GeoImplicitSurfaceND surf, GeoLineND line) {
return new GeoPoint[0];
}
// intersect path with point
public GeoElement[] IntersectPathPoint(String label, Path path,
GeoPointND point) {
AlgoIntersectPathPoint algo = new AlgoIntersectPathPoint(cons, label,
path, point);
GeoElement[] p = new GeoElement[1];
p[0] = algo.getP().toGeoElement();
return p;
}
// intersect polynomial and conic
public AlgoIntersectPolynomialConic getIntersectionAlgorithm(GeoFunction f,
GeoConic c) {
AlgoElement existingAlgo = findExistingIntersectionAlgorithm(f, c);
if (existingAlgo != null) {
return (AlgoIntersectPolynomialConic) existingAlgo;
}
// we didn't find a matching algorithm, so create a new one
AlgoIntersectPolynomialConic algo = new AlgoIntersectPolynomialConic(
cons, f, c);
algo.setPrintedInXML(false);
addIntersectionAlgorithm(algo); // remember this algorithm
return algo;
}
// intersect line and conic
public AlgoIntersectLineConic getIntersectionAlgorithm(GeoLine g,
GeoConic c) {
AlgoElement existingAlgo = findExistingIntersectionAlgorithm(g, c);
if (existingAlgo != null) {
return (AlgoIntersectLineConic) existingAlgo;
}
// we didn't find a matching algorithm, so create a new one
AlgoIntersectLineConic algo = new AlgoIntersectLineConic(cons, g, c);
algo.setPrintedInXML(false);
addIntersectionAlgorithm(algo); // remember this algorithm
return algo;
}
// intersect polyLine and Conic
public AlgoIntersectPolyLineConic getIntersectionAlgorithm(GeoPolyLine g,
GeoConic c) {
AlgoElement existingAlgo = findExistingIntersectionAlgorithm(g, c);
if (existingAlgo != null) {
return (AlgoIntersectPolyLineConic) existingAlgo;
}
// we didn't find a matching algorithm, so create a new one
AlgoIntersectPolyLineConic algo = new AlgoIntersectPolyLineConic(cons,
c, g, false);
algo.setPrintedInXML(false);
addIntersectionAlgorithm(algo); // remember this algorithm
return algo;
}
// intersect polygon(as boundary) and Conic
public AlgoIntersectPolyLineConic getIntersectionAlgorithm(GeoPolygon g,
GeoConic c) {
AlgoElement existingAlgo = findExistingIntersectionAlgorithm(g, c);
if (existingAlgo != null) {
return (AlgoIntersectPolyLineConic) existingAlgo;
}
// we didn't find a matching algorithm, so create a new one
AlgoIntersectPolyLineConic algo = new AlgoIntersectPolyLineConic(cons,
c, g, true);
algo.setPrintedInXML(false);
addIntersectionAlgorithm(algo); // remember this algorithm
return algo;
}
// intersect conics
public AlgoIntersectConics getIntersectionAlgorithm(GeoConic a,
GeoConic b) {
AlgoElement existingAlgo = findExistingIntersectionAlgorithm(a, b);
if (existingAlgo != null) {
return (AlgoIntersectConics) existingAlgo;
}
// we didn't find a matching algorithm, so create a new one
AlgoIntersectConics algo = new AlgoIntersectConics(cons, a, b);
algo.setPrintedInXML(false);
addIntersectionAlgorithm(algo); // remember this algorithm
return algo;
}
// intersection of polynomials
public AlgoIntersectPolynomials getIntersectionAlgorithm(GeoFunction a,
GeoFunction b) {
AlgoElement existingAlgo = findExistingIntersectionAlgorithm(a, b);
if (existingAlgo != null) {
return (AlgoIntersectPolynomials) existingAlgo;
}
// we didn't find a matching algorithm, so create a new one
AlgoIntersectPolynomials algo = new AlgoIntersectPolynomials(cons, a,
b);
algo.setPrintedInXML(false);
addIntersectionAlgorithm(algo); // remember this algorithm
return algo;
}
// intersection of polynomials
public AlgoIntersectPolynomialLine getIntersectionAlgorithm(GeoFunction a,
GeoLine l) {
AlgoElement existingAlgo = findExistingIntersectionAlgorithm(a, l);
if (existingAlgo != null) {
return (AlgoIntersectPolynomialLine) existingAlgo;
}
// we didn't find a matching algorithm, so create a new one
AlgoIntersectPolynomialLine algo = new AlgoIntersectPolynomialLine(cons,
a, l);
algo.setPrintedInXML(false);
addIntersectionAlgorithm(algo); // remember this algorithm
return algo;
}
// intersection of GeoImplicitPoly, GeoLine
public AlgoIntersectImplicitpolyParametric getIntersectionAlgorithm(
GeoImplicit p, GeoLine l) {
AlgoElement existingAlgo = findExistingIntersectionAlgorithm(p, l);
if (existingAlgo != null) {
return (AlgoIntersectImplicitpolyParametric) existingAlgo;
}
// we didn't find a matching algorithm, so create a new one
AlgoIntersectImplicitpolyParametric algo = new AlgoIntersectImplicitpolyParametric(
cons, p, l);
algo.setPrintedInXML(false);
addIntersectionAlgorithm(algo); // remember this algorithm
return algo;
}
// intersection of GeoImplicitPoly, GeoPolyLine
public AlgoIntersectImplicitpolyPolyLine getIntersectionAlgorithm(
GeoImplicit p, GeoPolyLine l) {
AlgoElement existingAlgo = findExistingIntersectionAlgorithm(p, l);
if (existingAlgo != null) {
return (AlgoIntersectImplicitpolyPolyLine) existingAlgo;
}
// we didn't find a matching algorithm, so create a new one
AlgoIntersectImplicitpolyPolyLine algo = new AlgoIntersectImplicitpolyPolyLine(
cons, p, l, false);
algo.setPrintedInXML(false);
addIntersectionAlgorithm(algo); // remember this algorithm
return algo;
}
// intersection of GeoImplicitPoly, GeoPolygon
public AlgoIntersectImplicitpolyPolyLine getIntersectionAlgorithm(
GeoImplicit p, GeoPolygon l) {
AlgoElement existingAlgo = findExistingIntersectionAlgorithm(p, l);
if (existingAlgo != null) {
return (AlgoIntersectImplicitpolyPolyLine) existingAlgo;
}
// we didn't find a matching algorithm, so create a new one
AlgoIntersectImplicitpolyPolyLine algo = new AlgoIntersectImplicitpolyPolyLine(
cons, p, l, true);
algo.setPrintedInXML(false);
addIntersectionAlgorithm(algo); // remember this algorithm
return algo;
}
// intersection of GeoImplicitPoly, polynomial
public AlgoIntersectImplicitpolyParametric getIntersectionAlgorithm(
GeoImplicit p, GeoFunction f) {
AlgoElement existingAlgo = findExistingIntersectionAlgorithm(p, f);
if (existingAlgo != null) {
return (AlgoIntersectImplicitpolyParametric) existingAlgo;
}
// we didn't find a matching algorithm, so create a new one
AlgoIntersectImplicitpolyParametric algo = new AlgoIntersectImplicitpolyParametric(
cons, p, f);
algo.setPrintedInXML(false);
addIntersectionAlgorithm(algo); // remember this algorithm
return algo;
}
// intersection of two GeoImplicitPoly
public AlgoIntersectImplicitpolys getIntersectionAlgorithm(GeoImplicit p1,
GeoImplicit p2) {
AlgoElement existingAlgo = findExistingIntersectionAlgorithm(p1, p2);
if (existingAlgo != null) {
return (AlgoIntersectImplicitpolys) existingAlgo;
}
// we didn't find a matching algorithm, so create a new one
AlgoIntersectImplicitpolys algo = new AlgoIntersectImplicitpolys(cons,
p1, p2);
algo.setPrintedInXML(false);
addIntersectionAlgorithm(algo); // remember this algorithm
return algo;
}
public AlgoIntersectImplicitpolys getIntersectionAlgorithm(GeoImplicit p1,
GeoConic c1) {
AlgoElement existingAlgo = findExistingIntersectionAlgorithm(p1, c1);
if (existingAlgo != null) {
return (AlgoIntersectImplicitpolys) existingAlgo;
}
// we didn't find a matching algorithm, so create a new one
AlgoIntersectImplicitpolys algo = new AlgoIntersectImplicitpolys(cons,
p1, c1);
algo.setPrintedInXML(false);
addIntersectionAlgorithm(algo); // remember this algorithm
return algo;
}
public AlgoElement findExistingIntersectionAlgorithm(GeoElementND a,
GeoElementND b) {
int size = intersectionAlgos.size();
AlgoElement algo;
for (int i = 0; i < size; i++) {
algo = intersectionAlgos.get(i);
GeoElement[] input = algo.getInput();
if (a == input[0] && b == input[1]
|| a == input[1] && b == input[0]) {
// we found an existing intersection algorithm
return algo;
}
}
return null;
}
/**
* tangents to c through P
*/
final public GeoElement[] Tangent(String[] labels, GeoPointND P,
GeoConicND c) {
AlgoTangentPoint algo = new AlgoTangentPoint(cons, labels, P, c);
return algo.getOutput();
}
/**
* common tangents to c1 and c2 dsun48 [6/26/2011]
*/
final public GeoElement[] CommonTangents(String[] labels, GeoConicND c1,
GeoConicND c2) {
AlgoCommonTangents algo = new AlgoCommonTangents(cons, labels, c1, c2);
return algo.getOutput();
}
/**
* tangents to c parallel to g
*/
final public GeoElement[] Tangent(String[] labels, GeoLineND g,
GeoConicND c) {
AlgoTangentLine algo = new AlgoTangentLine(cons, labels, g, c);
return algo.getOutput();
}
/**
* tangent to f in x = x(P)
*/
final public GeoLine Tangent(String label, GeoPointND P, GeoFunction f) {
return KernelCAS.tangent(cons, label, P, f);
}
/**
* tangents to p through P
*/
final public GeoLine[] Tangent(String[] labels, GeoPointND R,
GeoImplicit p) {
AlgoTangentImplicitpoly algo = new AlgoTangentImplicitpoly(cons, labels,
p, R);
algo.setLabels(labels);
GeoLine[] tangents = algo.getTangents();
return tangents;
}
/**
* tangents to p parallel to g
**/
final public GeoLine[] Tangent(String[] labels, GeoLineND g, GeoImplicit p) {
AlgoTangentImplicitpoly algo = new AlgoTangentImplicitpoly(cons,
labels, p, g);
algo.setLabels(labels);
GeoLine[] tangents = algo.getTangents();
return tangents;
}
/********************************************************************
* TRANSFORMATIONS
********************************************************************/
/**
* translate geoTrans by vector v
*/
final public GeoElement[] Translate(String label, GeoElementND geoTrans,
GeoVec3D v) {
Transform t = new TransformTranslate(cons, v);
return t.transform(geoTrans, label);
}
public GeoElement[] TranslateND(String label, GeoElementND geoTrans,
GeoVectorND v) {
return Translate(label, geoTrans, (GeoVec3D) v);
}
/**
* mirror geoMir at point Q
*/
final public GeoElement[] Mirror(String label, GeoElement geoMir,
GeoPoint Q) {
Transform t = new TransformMirror(cons, Q);
return t.transform(geoMir, label);
}
/**
* mirror (invert) element Q in circle Michael Borcherds 2008-02-10
*/
final public GeoElement[] Mirror(String label, GeoElement Q,
GeoConic conic) {
Transform t = new TransformMirror(cons, conic);
return t.transform(Q, label);
}
/**
* mirror geoMir at line g
*/
final public GeoElement[] Mirror(String label, GeoElement geoMir,
GeoLine g) {
Transform t = new TransformMirror(cons, g);
return t.transform(geoMir, label);
}
public GeoPointND attach(GeoPointND point, Path path,
EuclidianViewInterfaceCommon view, Coords locRW) {
try {
boolean oldLabelCreationFlag = cons.isSuppressLabelsActive();
cons.setSuppressLabelCreation(true);
// checkZooming();
boolean setDefaultColor = false;
if (((GeoElement) point).getColorFunction() == null) {
setDefaultColor = ((GeoElement) point).getObjectColor()
.equals(cons.getConstructionDefaults()
.getDefaultGeo(
ConstructionDefaults.DEFAULT_POINT_FREE)
.getObjectColor());
}
GeoPointND newPoint = Point(null, path, locRW, false, false,
point.getMode() != Kernel.COORD_CARTESIAN_3D);
cons.setSuppressLabelCreation(oldLabelCreationFlag);
cons.replace((GeoElement) point, (GeoElement) newPoint);
// clearSelections();
if (setDefaultColor) {
newPoint.setObjColor(cons.getConstructionDefaults()
.getDefaultGeo(
ConstructionDefaults.DEFAULT_POINT_ON_PATH)
.getObjectColor());
}
return newPoint;
} catch (Exception e1) {
Log.error(e1.getMessage());
return null;
} catch (Error e2) {
// eg try to attach dependent point of regular polygon
Log.error(e2.getMessage());
return null;
}
}
public GeoPointND attach(GeoPointND point, Region region,
EuclidianViewInterfaceCommon view, Coords locRW) {
try {
boolean oldLabelCreationFlag = cons.isSuppressLabelsActive();
cons.setSuppressLabelCreation(true);
// checkZooming();
boolean setDefaultColor = false;
if (((GeoElement) point).getColorFunction() == null) {
setDefaultColor = ((GeoElement) point).getObjectColor()
.equals(cons.getConstructionDefaults()
.getDefaultGeo(
ConstructionDefaults.DEFAULT_POINT_FREE)
.getObjectColor());
}
GeoPointND newPoint = PointIn(null, region, locRW, false, false,
true);
cons.setSuppressLabelCreation(oldLabelCreationFlag);
cons.replace((GeoElement) point, (GeoElement) newPoint);
if (setDefaultColor) {
newPoint.setObjColor(cons.getConstructionDefaults()
.getDefaultGeo(
ConstructionDefaults.DEFAULT_POINT_IN_REGION)
.getObjectColor());
}
// clearSelections();
return newPoint;
} catch (Exception e1) {
e1.printStackTrace();
return null;
}
}
public GeoPointND detach(GeoPointND p, EuclidianViewInterfaceCommon view) {
try {
boolean oldLabelCreationFlag = cons.isSuppressLabelsActive();
cons.setSuppressLabelCreation(true);
boolean setDefaultColor = false;
if (((GeoElement) p).getColorFunction() == null) {
if (p.isPointOnPath()) {
setDefaultColor = ((GeoElement) p).getObjectColor()
.equals(cons.getConstructionDefaults()
.getDefaultGeo(
ConstructionDefaults.DEFAULT_POINT_ON_PATH)
.getObjectColor());
} else if (p.hasRegion()) {
setDefaultColor = ((GeoElement) p).getObjectColor()
.equals(cons.getConstructionDefaults()
.getDefaultGeo(
ConstructionDefaults.DEFAULT_POINT_IN_REGION)
.getObjectColor());
}
}
GeoPointND newPoint = copyFreePoint(p, view);
cons.setSuppressLabelCreation(oldLabelCreationFlag);
cons.replace((GeoElement) p, (GeoElement) newPoint);
if (setDefaultColor) {
newPoint.setObjColor(cons.getConstructionDefaults()
.getDefaultGeo(ConstructionDefaults.DEFAULT_POINT_FREE)
.getObjectColor());
}
return newPoint;
} catch (Exception e1) {
e1.printStackTrace();
return null;
}
}
protected final static int DETACH_OFFSET = 20;
protected GeoPointND copyFreePoint(GeoPointND point,
EuclidianViewInterfaceCommon view) {
double xOffset = 0, yOffset = 0;
if (!view.isEuclidianView3D()) {
xOffset = DETACH_OFFSET * view.getInvXscale();
yOffset = DETACH_OFFSET * view.getInvYscale();
}
return new GeoPoint(cons, null, point.getInhomX() + xOffset,
point.getInhomY() + yOffset, 1.0);
}
/**
* detaches a GeoPoint and sets its real world coordinates to (rwX, rwY)
*
* @param point
* the GeoPoint to be detached
* @param rwX
* new real world x-coordinate
* @param rwY
* new real world y-coordinate
* @return success
*/
public boolean detach(GeoPointND point, double d, double e,
boolean wasOnPath, boolean wasOnRegion) {
try {
boolean oldLabelCreationFlag = cons.isSuppressLabelsActive();
cons.setSuppressLabelCreation(true);
boolean setDefaultColor = false;
if (((GeoElement) point).getColorFunction() == null) {
if (wasOnPath) {
setDefaultColor = ((GeoElement) point).getObjectColor()
.equals(cons.getConstructionDefaults()
.getDefaultGeo(
ConstructionDefaults.DEFAULT_POINT_ON_PATH)
.getObjectColor());
} else if (wasOnRegion) {
setDefaultColor = ((GeoElement) point).getObjectColor()
.equals(cons.getConstructionDefaults()
.getDefaultGeo(
ConstructionDefaults.DEFAULT_POINT_IN_REGION)
.getObjectColor());
}
}
GeoPoint newPoint = new GeoPoint(cons, null, d, e, 1.0);
cons.setSuppressLabelCreation(oldLabelCreationFlag);
cons.replace((GeoElement) point, newPoint);
if (setDefaultColor) {
newPoint.setObjColor(cons.getConstructionDefaults()
.getDefaultGeo(ConstructionDefaults.DEFAULT_POINT_FREE)
.getObjectColor());
}
} catch (Exception e1) {
e1.printStackTrace();
return false;
}
return true;
}
/**
* one intersection point of polynomial f and line l near to (xRW, yRW)
*/
public final GeoPoint IntersectPolynomialLineSingle(String label,
GeoFunction f, GeoLine l, double xRW, double yRW) {
if (!f.getConstruction().isFileLoading()
&& !f.isPolynomialFunction(false)) {
return null;
}
AlgoIntersectPolynomialLine algo = getIntersectionAlgorithm(f, l);
int index = algo.getClosestPointIndex(xRW, yRW);
AlgoIntersectSingle salgo = new AlgoIntersectSingle(label, algo, index);
GeoPoint point = salgo.getPoint();
return point;
}
public final GeoPoint IntersectPolynomialConicSingle(String label,
GeoFunction f, GeoConic c, double x, double y) {
AlgoIntersect algo = getIntersectionAlgorithm(f, c);
int idx = algo.getClosestPointIndex(x, y);
AlgoIntersectSingle salgo = new AlgoIntersectSingle(label, algo, idx);
GeoPoint point = salgo.getPoint();
return point;
}
/**
* get only one intersection point of two conics that is near to the given
* location (xRW, yRW)
*/
public final GeoPoint IntersectLineConicSingle(String label, GeoLine g,
GeoConic c, double xRW, double yRW) {
AlgoIntersectLineConic algo = getIntersectionAlgorithm(g, c);
int index = algo.getClosestPointIndex(xRW, yRW);
AlgoIntersectSingle salgo = new AlgoIntersectSingle(label, algo, index);
GeoPoint point = salgo.getPoint();
return point;
}
/**
* get single intersection points of a implicitPoly and a line
*/
final public GeoPoint IntersectImplicitpolyLineSingle(String label,
GeoImplicit p, GeoLine l, double x, double y) {
AlgoIntersect algo = getIntersectionAlgorithm(p, l);
int idx = algo.getClosestPointIndex(x, y);
AlgoIntersectSingle salgo = new AlgoIntersectSingle(label, algo, idx);
GeoPoint point = salgo.getPoint();
return point;
}
/**
* get single intersection points of a implicitPoly and a line
*/
final public GeoPoint IntersectImplicitpolyPolynomialSingle(String label,
GeoImplicit p, GeoFunction f, double x, double y) {
if (!f.getConstruction().isFileLoading()
&& !f.isPolynomialFunction(false)) {
return null;
}
AlgoIntersect algo = getIntersectionAlgorithm(p, f);
int idx = algo.getClosestPointIndex(x, y);
AlgoIntersectSingle salgo = new AlgoIntersectSingle(label, algo, idx);
GeoPoint point = salgo.getPoint();
return point;
}
/**
* get single intersection points of implicitPolys and conic near given
* Point (x,y)
*
* @param x
* @param y
*/
final public GeoPoint IntersectImplicitpolyConicSingle(String label,
GeoImplicit p1, GeoConic c1, double x, double y) {
AlgoIntersectImplicitpolys algo = getIntersectionAlgorithm(p1, c1);
int idx = algo.getClosestPointIndex(x, y);
AlgoIntersectSingle salgo = new AlgoIntersectSingle(label, algo, idx);
GeoPoint point = salgo.getPoint();
return point;
}
/**
* get single intersection points of two implicitPolys near given Point
* (x,y)
*
* @param x
* @param y
*/
final public GeoPoint IntersectImplicitpolysSingle(String label,
GeoImplicit p1, GeoImplicit p2, double x, double y) {
AlgoIntersectImplicitpolys algo = getIntersectionAlgorithm(p1, p2);
int idx = algo.getClosestPointIndex(x, y);
AlgoIntersectSingle salgo = new AlgoIntersectSingle(label, algo, idx);
GeoPoint point = salgo.getPoint();
return point;
}
/**
*
* @param cons2
* @param path
* @param point
* @return new algo closest point for path and point
*/
public AlgoClosestPoint getNewAlgoClosestPoint(Construction cons2,
Path path, GeoPointND point) {
return new AlgoClosestPoint(cons2, path, point);
}
public GeoAngle createLineAngle(GeoLine line1, GeoLine line2) {
GeoAngle angle = null;
// did we get two segments?
if ((line1 instanceof GeoSegment) && (line2 instanceof GeoSegment)) {
// check if the segments have one point in common
GeoSegment a = (GeoSegment) line1;
GeoSegment b = (GeoSegment) line2;
// get endpoints
GeoPoint a1 = a.getStartPoint();
GeoPoint a2 = a.getEndPoint();
GeoPoint b1 = b.getStartPoint();
GeoPoint b2 = b.getEndPoint();
if (a1 == b1) {
angle = Angle(null, a2, a1, b2);
} else if (a1 == b2) {
angle = Angle(null, a2, a1, b1);
} else if (a2 == b1) {
angle = Angle(null, a1, a2, b2);
} else if (a2 == b2) {
angle = Angle(null, a1, a2, b1);
}
}
if (angle == null) {
angle = Angle(null, line1, line2);
}
return angle;
}
/**
*
* @param cons
* @param labels
* @param p
* @return new AlgoVertexPolygon
*/
public AlgoVertexPolygon newAlgoVertexPolygon(Construction cons,
String[] labels, GeoPoly p) {
return new AlgoVertexPolygon(cons, labels, p);
}
}