/* 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.geogebra3D.kernel3D.algos; import org.geogebra.common.euclidian.EuclidianConstants; import org.geogebra.common.geogebra3D.kernel3D.geos.GeoConic3D; import org.geogebra.common.geogebra3D.kernel3D.geos.GeoConicPart3D; import org.geogebra.common.kernel.Construction; import org.geogebra.common.kernel.PathParameter; import org.geogebra.common.kernel.StringTemplate; import org.geogebra.common.kernel.Matrix.Coords; import org.geogebra.common.kernel.algos.AlgoElement; import org.geogebra.common.kernel.algos.AlgoMidpoint; 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.AlgoMidpointND; import org.geogebra.common.kernel.kernelND.GeoConicNDConstants; import org.geogebra.common.kernel.kernelND.GeoDirectionND; import org.geogebra.common.kernel.kernelND.GeoPointND; /** * Semicircle defined by two points A and B (start and end point) with * orientation */ public class AlgoSemicircle3D extends AlgoElement { private GeoPointND A, B; // input private GeoDirectionND orientation; // input private GeoConicPart3D conicPart; // output private PathParameter param; private GeoPointND M; // midpoint of AB private GeoConic3D conic; /** * Creates new semicircle algoritm * * @param cons * construction * @param label * label for the semicircle * @param A * first endpoint * @param B * second endpoint */ public AlgoSemicircle3D(Construction cons, String label, GeoPointND A, GeoPointND B, GeoDirectionND orientation) { this(cons, A, B, orientation); conicPart.setLabel(label); } /** * Creates new unlabeled semicircle algoritm * * @param cons * construction * @param A * first endpoint * @param B * second endpoint */ public AlgoSemicircle3D(Construction cons, GeoPointND A, GeoPointND B, GeoDirectionND orientation) { super(cons); p2d = new Coords(4); this.A = A; this.B = B; this.orientation = orientation; // helper algo to get midpoint AlgoMidpointND algom; if (A.isGeoElement3D() || B.isGeoElement3D()) { algom = new AlgoMidpoint3D(cons, A, B); } else { algom = new AlgoMidpoint(cons, (GeoPoint) A, (GeoPoint) B); } cons.removeFromConstructionList(algom); M = algom.getPoint(); // helper algo to get circle AlgoCircle3DPointPointDirection algo = new AlgoCircle3DPointPointDirection( cons, M, B, orientation); cons.removeFromConstructionList(algo); conic = algo.getCircle(); conicPart = new GeoConicPart3D(cons, GeoConicNDConstants.CONIC_PART_ARC); conicPart.addPointOnConic(A); conicPart.addPointOnConic(B); param = new PathParameter(); setInputOutput(); // for AlgoElement compute(); } @Override public Commands getClassName() { return Commands.Semicircle; } @Override public int getRelatedModeID() { return EuclidianConstants.MODE_SEMICIRCLE; } // for AlgoElement @Override protected void setInputOutput() { input = new GeoElement[3]; input[0] = (GeoElement) A; input[1] = (GeoElement) B; input[2] = (GeoElement) orientation; setOutputLength(1); setOutput(0, conicPart); setDependencies(); } /** * Returns the semicercle * * @return the semicircle */ public GeoConicPart3D getSemicircle() { return conicPart; } private Coords p2d; @Override public void compute() { if (!conic.isDefined()) { conicPart.setUndefined(); return; } B.getInhomCoordsInD3().projectPlaneInPlaneCoords( conic.getCoordSys().getMatrixOrthonormal(), p2d); p2d.setZ(1); conic.pointChanged(p2d, param); conicPart.set(conic); conicPart.setParameters(param.t, param.t + Math.PI, true); } @Override final public String toString(StringTemplate tpl) { // Michael Borcherds 2008-03-30 // simplified to allow better Chinese translation return getLoc().getPlain("SemicircleThroughAandBOrientedbyC", ((GeoElement) A).getLabel(tpl), ((GeoElement) B).getLabel(tpl), ((GeoElement) orientation).getLabel(tpl)); } }