/* 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. */ /* * AlgoJoinPointsSegment * * Created on 21. August 2003 */ 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.Kernel; 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.commands.Commands; import org.geogebra.common.kernel.geos.GeoElement; import org.geogebra.common.kernel.kernelND.GeoQuadricND; import org.geogebra.common.kernel.kernelND.GeoQuadricNDConstants; /** * * @author ggb3D * */ public class AlgoIntersectQuadricsAsCircle extends AlgoElement3D { // inputs private GeoQuadricND quadric1, quadric2; // output /** intersection */ protected GeoConic3D circle; /** * Creates new AlgoIntersectLinePlane * * @param cons * the construction * @param labels * names * @param quadric1 * first quadric * @param quadric2 * second quadric */ AlgoIntersectQuadricsAsCircle(Construction cons, String[] labels, GeoQuadricND quadric1, GeoQuadricND quadric2) { this(cons, quadric1, quadric2); if (labels != null && labels.length > 0) { circle.setLabel(labels[0]); } else { circle.setLabel(null); } } /** * Creates new AlgoIntersectLinePlane * * @param cons * the construction * @param quadric1 * first quadric * @param quadric2 * second quadric */ AlgoIntersectQuadricsAsCircle(Construction cons, GeoQuadricND quadric1, GeoQuadricND quadric2) { super(cons); this.quadric1 = quadric1; this.quadric2 = quadric2; circle = new GeoConic3D(cons, true); circle.setCoordSys(new CoordSys(2)); setInputOutput(new GeoElement[] { quadric1, quadric2 }, new GeoElement[] { circle }); compute(); } /** * return the intersection * * @return the intersection */ public GeoConic3D getConic() { return circle; } // ///////////////////////////////////////////// // COMPUTE private Coords o = new Coords(3), v = new Coords(3), vn1 = new Coords(3), vn2 = new Coords(3); @Override public void compute() { if (!quadric1.isDefined() || !quadric2.isDefined()) { circle.setUndefined(); return; } circle.setDefined(); if (quadric1.getType() == GeoQuadricNDConstants.QUADRIC_SPHERE) { if (quadric2.getType() == GeoQuadricNDConstants.QUADRIC_SPHERE) { // intersect sphere / sphere Coords o1 = quadric1.getMidpoint3D(); double r1 = quadric1.getHalfAxis(0); Coords o2 = quadric2.getMidpoint3D(); double r2 = quadric2.getHalfAxis(0); // same center if (o1.equalsForKernel(o2)) { if (Kernel.isZero(r1) && Kernel.isZero(r2)) { // single point GeoConic3D.setSinglePoint(circle, o1); return; } if (Kernel.isEqual(r1, r2)) { // undefined circle.setUndefined(); return; } // empty conic circle.empty(); return; } // different centers v.setSub3(o2, o1); v.calcNorm(); double d = v.getNorm(); if (Kernel.isGreater(d, r1 + r2)) { // no intersection : empty circle.empty(); return; } v.mulInside3(1 / d); double x = (d + (r1 * r1 - r2 * r2) / d) / 2; o.setAdd3(o1, o.setMul(v, x)); v.completeOrthonormal3(vn1, vn2); CoordSys coordSys = circle.getCoordSys(); coordSys.resetCoordSys(); coordSys.addPoint(o); coordSys.addVector(vn1); coordSys.addVector(vn2); coordSys.makeOrthoMatrix(false, false); circle.setSphereND(new Coords(0, 0), Math.sqrt(r1 * r1 - x * x)); return; } } // other cases circle.setUndefined(); } @Override public Commands getClassName() { return Commands.IntersectConic; } @Override final public String toString(StringTemplate tpl) { StringBuilder sb = new StringBuilder(); sb.append(getLoc().getPlain("IntersectionCircleOfAB", quadric1.getLabel(tpl), quadric2.getLabel(tpl))); return sb.toString(); } }