package org.geogebra.common.geogebra3D.kernel3D.algos; import org.geogebra.common.geogebra3D.kernel3D.geos.GeoConic3D; import org.geogebra.common.kernel.Construction; import org.geogebra.common.kernel.StringTemplate; import org.geogebra.common.kernel.Matrix.CoordSys; import org.geogebra.common.kernel.Matrix.Coords; import org.geogebra.common.kernel.algos.AlgoCircleThreePoints; import org.geogebra.common.kernel.geos.GeoElement; import org.geogebra.common.kernel.geos.GeoPoint; import org.geogebra.common.kernel.kernelND.GeoPointND; /** * @author ggb3D * * Algo that creates a 3D circle joining three 3D points * */ public class AlgoCircle3DThreePoints extends AlgoCircleThreePoints { /** coord sys defined by the three points where the 3D circle lies */ private CoordSys coordSys; /** 2D projection of the 3D points in the coord sys */ private GeoPoint[] points2D; /** 3D points */ private GeoPointND[] points; /** * Basic constructor * * @param cons * construction * @param label * name of the circle * @param A * first point * @param B * second point * @param C * third point */ public AlgoCircle3DThreePoints(Construction cons, String label, GeoPointND A, GeoPointND B, GeoPointND C) { super(cons, label, A, B, C); } /** * Basic constructor * * @param cons * construction * @param A * first point * @param B * second point * @param C * third point */ public AlgoCircle3DThreePoints(Construction cons, GeoPointND A, GeoPointND B, GeoPointND C) { super(cons, A, B, C); } @Override protected void setPoints(GeoPointND A, GeoPointND B, GeoPointND C) { points = new GeoPointND[3]; points[0] = A; points[1] = B; points[2] = C; coordSys = new CoordSys(2); points2D = new GeoPoint[3]; for (int i = 0; i < 3; i++) { points2D[i] = new GeoPoint(getConstruction()); } super.setPoints(points2D[0], points2D[1], points2D[2]); } /** * * @param i * index * @return i-th 2D point */ public GeoPoint getPoint2D(int i) { return points2D[i]; } @Override protected void createCircle() { circle = new GeoConic3D(cons, coordSys); } @Override protected void setInput() { input = new GeoElement[3]; for (int i = 0; i < 3; i++) { input[i] = (GeoElement) points[i]; } } @Override protected void setOutput() { setOnlyOutput(circle); } @Override public void compute() { coordSys.resetCoordSys(); for (int i = 0; i < 3; i++) { coordSys.addPoint(points[i].getInhomCoordsInD3()); } /* * if (!coordSys.makeOrthoMatrix(false,false)){ circle.setUndefined(); * return; } */ if (!coordSys.isMadeCoordSys()) { // force 2D coord sys (for line, or single point) coordSys.completeCoordSys2D(); } coordSys.makeOrthoMatrix(false, false); // Log.debug("coordSys=\n"+coordSys.getMatrixOrthonormal().toString()); for (int i = 0; i < 3; i++) { // project the point on the coord sys // Coords[] // project=points[i].getCoordsInD3().projectPlane(coordSys.getMatrixOrthonormal()); Coords[] project = coordSys .getNormalProjection(points[i].getInhomCoordsInD3()); // set the 2D points points2D[i].setCoords(project[1].getX(), project[1].getY(), project[1].getW()); } super.compute(); } @Override public String toString(StringTemplate tpl) { return getLoc().getPlain("CircleThroughABC", points[0].getLabel(tpl), points[1].getLabel(tpl), points[2].getLabel(tpl)); } }