/* Coyright 2018 Glen Whitney This file is contributed to C.a.R./CaRMetal software. C.a.R. is a 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, version 3 of the License. C.a.R. is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package rene.zirkel.objects; import rene.gui.Global; import rene.zirkel.construction.Construction; import rene.zirkel.construction.ConstructionException; import rene.zirkel.expression.Expression; /* A three dimensional circle determined by a 3D point (the "midpoint" of the super object), an expression giving its radius, and a TwoPointLineObject determined by two 3D points, giving its normal direction. (The line does not have to go through the center. */ public class Circle3DObject extends PrimitiveCircleObject { Expression E_R; // Expression for the radius TwoPointLineObject N; public Circle3DObject(final Construction c, final PointObject C, final String s, final TwoPointLineObject L) throws ConstructionException { super(c, C); if (!C.is3D()) { throw new ConstructionException("Cannot create Circle3D with " + "non-3D center " + C.getName()); } if (!L.getP1().is3D() || !L.getP2().is3D()) { throw new ConstructionException("Cannot create Circle3D with " + "non-3D normal " + L.getName()); } E_R = new Expression(s, c, this); N = L; validate(); updateText(); } @Override public String getTag() { return "Circle3D"; } @Override public void updateText() { setText(text3(Global.name("text.circle3D"), M.getName(), E_R.toString(), N.getName())); } @Override public void validate() { super.validate(); Valid = false; if (!M.valid() || !E_R.valid() || !N.valid()) { return; } try { R = E_R.getValue(); } catch (final Exception e) { R = 0; return; } if (R < 0) { return; } Valid = true; } @Override public void printArgs(final XmlWriter xml) { xml.printArg("radius", E_R.toString()); xml.printArg("normal", N.getName()); super.printArgs(xml); } @Override public String getStringLength() { return E_R.toString(); } @Override public double getValue() throws ConstructionException { if (!Valid) { throw new InvalidException("exception.invalid"); } else { return R; } } @Override public Enumeration depending() { super.depending(); final Enumeration e = E_R.getDepList().elements(); while (e.hasMoreElements()) { DL.add((ConstructionObject) e.nextElement()); } DL.add(N); return DL.elements(); } /* A (rudimentary version) of the class is almost done at this point, but it still needs a paint() method. This we want to share with the QuadricObject. The best way I could think of was to create a class that encapsulates the X[..] data in QuadricObject, with a method to set that up from 5 (x,y) pairs. In QuadricObject, I woul just use the 5 (x,y) values of the Point members. Here, in validate, I would use the center, radius, and normal data to compute 5 equally-spaced (x,y,z) coordinates around the circle. The sticking point is then projecting those to (x,y). There does not seem to be any good way to do it -- it seems like Expressions that do it are littered all around the code. Ugh. So I am giving up for now. */ }