/* 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. */ /* * AlgoEllipseFociPoint.java * * Ellipse with Foci A and B passing through point C * * Michael Borcherds * 2008-04-06 * adapted from EllipseFociLength */ package org.geogebra.common.kernel.algos; import org.geogebra.common.kernel.Construction; import org.geogebra.common.kernel.geos.GeoConic; import org.geogebra.common.kernel.geos.GeoPoint; import org.geogebra.common.kernel.kernelND.GeoConicND; import org.geogebra.common.kernel.kernelND.GeoConicNDConstants; import org.geogebra.common.kernel.kernelND.GeoElementND; import org.geogebra.common.kernel.kernelND.GeoPointND; import org.geogebra.common.kernel.prover.NoSymbolicParametersException; import org.geogebra.common.kernel.prover.polynomial.PPolynomial; import org.geogebra.common.kernel.prover.polynomial.PVariable; /** * * @author Markus */ public class AlgoEllipseHyperbolaFociPoint extends AlgoEllipseHyperbolaFociPointND implements SymbolicParametersBotanaAlgo { private PPolynomial[] botanaPolynomials; private PVariable[] botanaVars; public AlgoEllipseHyperbolaFociPoint(Construction cons, String label, GeoPointND A, GeoPointND B, GeoPointND C, final int type) { super(cons, label, A, B, C, null, type); } public AlgoEllipseHyperbolaFociPoint(Construction cons, GeoPointND A, GeoPointND B, GeoPointND C, final int type) { super(cons, A, B, C, null, type); } @Override protected GeoConicND newGeoConic(Construction cons) { return new GeoConic(cons); } @Override protected GeoPoint getA2d() { return (GeoPoint) A; } @Override protected GeoPoint getB2d() { return (GeoPoint) B; } @Override protected GeoPoint getC2d() { return (GeoPoint) C; } // /////////////////////////////// // TRICKS FOR XOY PLANE // /////////////////////////////// @Override protected int getInputLengthForXML() { return getInputLengthForXMLMayNeedXOYPlane(); } @Override protected int getInputLengthForCommandDescription() { return getInputLengthForCommandDescriptionMayNeedXOYPlane(); } @Override public GeoElementND getInput(int i) { return getInputMaybeXOYPlane(i); } @Override public PVariable[] getBotanaVars(GeoElementND geo) { return botanaVars; } @Override public PPolynomial[] getBotanaPolynomials(GeoElementND geo) throws NoSymbolicParametersException { if (botanaPolynomials != null) { return botanaPolynomials; } if (type == GeoConicNDConstants.CONIC_ELLIPSE) { GeoPoint F1 = getA2d(); GeoPoint F2 = getB2d(); GeoPoint Q = getC2d(); if (F1 != null && F2 != null && Q != null) { PVariable[] vA = F1.getBotanaVars(F1); PVariable[] vB = F2.getBotanaVars(F2); PVariable[] vC = Q.getBotanaVars(Q); // if the 2 focus points are equal // handle the ellipse as a circle if (vA[0] == vB[0] && vA[1] == vB[1]) { if (botanaVars == null) { botanaVars = new PVariable[4]; // A - center botanaVars[0] = vA[0]; botanaVars[1] = vA[1]; // C - point on the circle botanaVars[2] = vC[0]; botanaVars[3] = vC[1]; } return botanaPolynomials; } if (botanaVars == null) { botanaVars = new PVariable[12]; // P - point of ellipse botanaVars[0] = new PVariable(kernel); botanaVars[1] = new PVariable(kernel); // auxiliary variables for distances botanaVars[2] = new PVariable(kernel); botanaVars[3] = new PVariable(kernel); botanaVars[4] = new PVariable(kernel); botanaVars[5] = new PVariable(kernel); // A - focus point botanaVars[6] = vA[0]; botanaVars[7] = vA[1]; // B - focus point botanaVars[8] = vB[0]; botanaVars[9] = vB[1]; // C - point on ellipse botanaVars[10] = vC[0]; botanaVars[11] = vC[1]; } botanaPolynomials = new PPolynomial[5]; PPolynomial d1 = new PPolynomial(botanaVars[2]); PPolynomial d2 = new PPolynomial(botanaVars[3]); PPolynomial e1 = new PPolynomial(botanaVars[4]); PPolynomial e2 = new PPolynomial(botanaVars[5]); // d1+d2 = e1+e2 botanaPolynomials[0] = d1.add(d2).subtract(e1).subtract(e2); // d1^2=Polynomial.sqrDistance(a1,a2,c1,c2) botanaPolynomials[1] = PPolynomial .sqrDistance(vA[0], vA[1], vC[0], vC[1]) .subtract(d1.multiply(d1)); // d2^2=Polynomial.sqrDistance(b1,b2,c1,c2) botanaPolynomials[2] = PPolynomial .sqrDistance(vB[0], vB[1], vC[0], vC[1]) .subtract(d2.multiply(d2)); // e1^2=Polynomial.sqrDistance(a1,a2,p1,p2) botanaPolynomials[3] = PPolynomial .sqrDistance(vA[0], vA[1], botanaVars[0], botanaVars[1]) .subtract(e1.multiply(e1)); // e2^2=Polynomial.sqrDistance(b1,b2,p1,p2) botanaPolynomials[4] = PPolynomial .sqrDistance(vB[0], vB[1], botanaVars[0], botanaVars[1]) .subtract(e2.multiply(e2)); return botanaPolynomials; } throw new NoSymbolicParametersException(); } else if (type == GeoConicNDConstants.CONIC_HYPERBOLA) { GeoPoint F1 = getA2d(); GeoPoint F2 = getB2d(); GeoPoint Q = getC2d(); if (F1 != null && F2 != null && Q != null) { PVariable[] vA = F1.getBotanaVars(F1); PVariable[] vB = F2.getBotanaVars(F2); PVariable[] vC = Q.getBotanaVars(Q); if (botanaVars == null) { botanaVars = new PVariable[12]; // P - point of hyperbola botanaVars[0] = new PVariable(kernel); botanaVars[1] = new PVariable(kernel); // auxiliary variables botanaVars[2] = new PVariable(kernel); botanaVars[3] = new PVariable(kernel); botanaVars[4] = new PVariable(kernel); botanaVars[5] = new PVariable(kernel); // A botanaVars[6] = vA[0]; botanaVars[7] = vA[1]; // B botanaVars[8] = vB[0]; botanaVars[9] = vB[1]; // C botanaVars[10] = vC[0]; botanaVars[11] = vC[1]; } botanaPolynomials = new PPolynomial[5]; PPolynomial d1 = new PPolynomial(botanaVars[2]); PPolynomial d2 = new PPolynomial(botanaVars[3]); PPolynomial e1 = new PPolynomial(botanaVars[4]); PPolynomial e2 = new PPolynomial(botanaVars[5]); // d1-d2 = e1-e2 botanaPolynomials[0] = d1.subtract(d2).subtract(e1).add(e2); // d1^2=Polynomial.sqrDistance(a1,a2,c1,c2) botanaPolynomials[1] = PPolynomial .sqrDistance(vA[0], vA[1], vC[0], vC[1]) .subtract(d1.multiply(d1)); // d2^2=Polynomial.sqrDistance(b1,b2,c1,c2) botanaPolynomials[2] = PPolynomial .sqrDistance(vB[0], vB[1], vC[0], vC[1]) .subtract(d2.multiply(d2)); // e1^2=Polynomial.sqrDistance(a1,a2,p1,p2) botanaPolynomials[3] = PPolynomial .sqrDistance(vA[0], vA[1], botanaVars[0], botanaVars[1]) .subtract(e1.multiply(e1)); // e2^2=Polynomial.sqrDistance(b1,b2,p1,p2) botanaPolynomials[4] = PPolynomial .sqrDistance(vB[0], vB[1], botanaVars[0], botanaVars[1]) .subtract(e2.multiply(e2)); return botanaPolynomials; } throw new NoSymbolicParametersException(); } else { throw new NoSymbolicParametersException(); } } }