/* 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.euclidian.EuclidianConstants; import org.geogebra.common.kernel.Construction; import org.geogebra.common.kernel.StringTemplate; import org.geogebra.common.kernel.commands.Commands; import org.geogebra.common.kernel.geos.GeoElement; 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.GeoDirectionND; import org.geogebra.common.kernel.kernelND.GeoPointND; /** * * @author Markus */ public abstract class AlgoEllipseHyperbolaFociPointND extends AlgoElement { protected GeoPointND A, B, C; // input protected GeoConicND conic; // output final protected int type; // ellipse or hyperbola public AlgoEllipseHyperbolaFociPointND(Construction cons, String label, GeoPointND A, GeoPointND B, GeoPointND C, GeoDirectionND orientation, final int type) { this(cons, A, B, C, orientation, type); conic.setLabel(label); } public AlgoEllipseHyperbolaFociPointND(Construction cons, GeoPointND A, GeoPointND B, GeoPointND C, GeoDirectionND orientation, final int type) { super(cons); this.type = type; this.A = A; this.B = B; this.C = C; setOrientation(orientation); conic = newGeoConic(cons); setInputOutput(); // for AlgoElement initCoords(); compute(); addIncidence(); } /** * init coords values */ protected void initCoords() { // none used here } /** * for 3D, set an orientation * * @param orientation * orientation */ protected void setOrientation(GeoDirectionND orientation) { // not needed in 2D } /** * * @param cons * construction * @return new conic */ abstract protected GeoConicND newGeoConic(Construction cons); /** * @author Tam * * for special cases of e.g. AlgoIntersectLineConic */ private void addIncidence() { if (C != null) { C.addIncidence(conic, false); } } @Override public Commands getClassName() { if (type == GeoConicNDConstants.CONIC_HYPERBOLA) { return Commands.Hyperbola; } return Commands.Ellipse; } @Override public int getRelatedModeID() { if (type == GeoConicNDConstants.CONIC_HYPERBOLA) { return EuclidianConstants.MODE_HYPERBOLA_THREE_POINTS; } return EuclidianConstants.MODE_ELLIPSE_THREE_POINTS; } /** * set the input */ protected void setInput() { input = new GeoElement[3]; input[0] = (GeoElement) A; input[1] = (GeoElement) B; input[2] = (GeoElement) C; } // for AlgoElement @Override protected void setInputOutput() { setInput(); super.setOutputLength(1); super.setOutput(0, conic); setDependencies(); // done by AlgoElement } public GeoConicND getConic() { return conic; } public GeoPointND getFocus1() { // Public for LocusEqu return A; } public GeoPointND getFocus2() { // Public for LocusEqu return B; } /** * Method for LocusEqu * * @return returns external point for ellipse. */ public GeoPointND getExternalPoint() { return C; } // compute ellipse with foci A, B passing through C @Override public void compute() { double xyA[] = new double[2]; double xyB[] = new double[2]; double xyC[] = new double[2]; getA2d().getInhomCoords(xyA); getB2d().getInhomCoords(xyB); getC2d().getInhomCoords(xyC); double length; double length1 = Math.sqrt((xyA[0] - xyC[0]) * (xyA[0] - xyC[0]) + (xyA[1] - xyC[1]) * (xyA[1] - xyC[1])); double length2 = Math.sqrt((xyB[0] - xyC[0]) * (xyB[0] - xyC[0]) + (xyB[1] - xyC[1]) * (xyB[1] - xyC[1])); if (type == GeoConicNDConstants.CONIC_HYPERBOLA) { length = Math.abs(length1 - length2); } else { length = length1 + length2; // ellipse } conic.setEllipseHyperbola(getA2d(), getB2d(), length / 2); } /** * * @return point A in 2D coords */ abstract protected GeoPoint getA2d(); /** * * @return point B in 2D coords */ abstract protected GeoPoint getB2d(); /** * * @return point C in 2D coords */ abstract protected GeoPoint getC2d(); @Override public String toString(StringTemplate tpl) { if (type == GeoConicNDConstants.CONIC_HYPERBOLA) { return getLoc().getPlain("HyperbolaWithFociABPassingThroughC", A.getLabel(tpl), B.getLabel(tpl), C.getLabel(tpl)); } return getLoc().getPlain("EllipseWithFociABPassingThroughC", A.getLabel(tpl), B.getLabel(tpl), C.getLabel(tpl)); } }