001/*
002 *   Entity100_CircularArc  -- Entity that defines a circle or circular arc.
003 *
004 *   Copyright (C) 2010-2016, Joseph A. Huwaldt.
005 *   All rights reserved.
006 *   
007 *   This library is free software; you can redistribute it and/or
008 *   modify it under the terms of the GNU Lesser General Public
009 *   License as published by the Free Software Foundation; either
010 *   version 2.1 of the License, or (at your option) any later version.
011 *   
012 *   This library is distributed in the hope that it will be useful,
013 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
014 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015 *   Lesser General Public License for more details.
016 *
017 *   You should have received a copy of the GNU Lesser General Public License
018 *   along with this program; if not, write to the Free Software
019 *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
020 *   Or visit:  http://www.gnu.org/licenses/lgpl.html
021 *
022 *   Based on, but heavily modified from, IGESView ( http://ts.nist.gov/Standards/IGES/igesTools.cfm )
023 */
024package geomss.geom.reader.iges;
025
026import geomss.geom.*;
027import geomss.geom.nurbs.CurveFactory;
028import jahuwaldt.js.param.Parameter;
029import java.io.IOException;
030import java.io.RandomAccessFile;
031import javax.measure.quantity.Angle;
032import javax.measure.quantity.Dimensionless;
033import javax.measure.quantity.Length;
034import javax.measure.unit.SI;
035import static javolution.lang.MathLib.*;
036
037/**
038 * <b><i>CIRCULAR ARC ENTITY</i></b> - This entity defines a circle or a portion of a
039 * circle which may be isolated or used as a component of a Composite Curve Entity or a
040 * subfigure. The definition space coordinate system is always chosen so that the circular
041 * arc remains in a plane either coincident with or parallel to the XT, YT plane.
042 *
043 * <p>
044 * This entity, when read from an IGES file, is converted to a NURBS curve of degree 2
045 * (IGES type 126, Form 2, Degree 2). This entity type can not be written out to an IGES
046 * file. All circular arc parameters are stored in the user data with the prefix
047 * "IGES_100_" followed by the parameter name.
048 * </p>
049 *
050 * <p> Modified by: Joseph A. Huwaldt </p>
051 * 
052 * @author JDN, Version 1.0
053 * @version September 13, 2016
054 */
055public class Entity100_CircularArc extends GeomSSEntity {
056
057    private double zt; // Parallel ZT displacement of arc from XT, YT plane
058    private double x1; // Arc center abcissa
059    private double y1; // Arc center ordinate
060    private double x2; // Start point abcissa
061    private double y2; // Start point ordinate
062    private double x3; // Terminate point abcissa
063    private double y3; // Terminate point ordinate
064
065    private double r;       // Radius
066    private double angle1;  // Start angle
067    private double angle2;  // Terminate angle
068    private boolean circle; // Full circle?
069
070    private Curve curve;    //  The GeomSS curve represented by this element.
071
072    /**
073     * Default constructor.
074     *
075     * @param p  part to which this entity is contained
076     * @param de Directory Entry for this entity
077     */
078    public Entity100_CircularArc(Part p, DirEntry de) {
079        super(p, de);
080
081        if (Constants.DEBUG) {
082            System.out.println("Entity100 constructor called");
083        }
084    }
085
086    /**
087     * Checks to see if the entity is correct. The following restrictions are imposed:
088     *
089     * - The length must be greater than 0.0
090     */
091    @Override
092    public void check() {
093        DirEntry DE = getDirectoryEntry();
094
095        // Radius must be greater than 0.0
096        double rad1 = Constants.dist(x1, y1, x2, y2);
097        double rad2 = Constants.dist(x1, y1, x3, y3);
098        if ((abs(rad1) < Constants.Grain) || (abs(rad2) < Constants.Grain)) {
099            String msg = RESOURCES.getString("zeroRadiusArc");
100            addErrorMessage(getWarningString(msg));
101        }
102
103        // Length must be greater than 0.0
104        if (abs(angle2 - angle1) < Constants.Grain) {
105            String msg = RESOURCES.getString("zeroLengthArc");
106            addErrorMessage(getWarningString(msg));
107        }
108    }
109
110    /**
111     * Read the Parameter Data from the String read in by the superclass.
112     *
113     * @param in input file
114     * @throws java.io.IOException
115     */
116    @Override
117    public void read(RandomAccessFile in) throws IOException {
118        if (Constants.DEBUG) {
119            System.out.println("Entity100.read() called");
120        }
121
122        super.read(in);
123        String s = getPDString();
124
125        if (Constants.DEBUG) {
126            System.out.println("PD String = \"" + s + "\"");
127        }
128
129        zt = getReal(s);
130        if (abs(zt) < Constants.Grain)
131            zt = 0;
132        x1 = getReal(s);
133        if (abs(x1) < Constants.Grain)
134            x1 = 0;
135        y1 = getReal(s);
136        if (abs(y1) < Constants.Grain)
137            y1 = 0;
138        x2 = getReal(s);
139        if (abs(x2) < Constants.Grain)
140            x2 = 0;
141        y2 = getReal(s);
142        if (abs(y2) < Constants.Grain)
143            y2 = 0;
144        x3 = getReal(s);
145        if (abs(x3) < Constants.Grain)
146            x3 = 0;
147        y3 = getReal(s);
148        if (abs(y3) < Constants.Grain)
149            y3 = 0;
150
151        super.read_additional();
152
153        double dx = x2 - x1;
154        double dy = y2 - y1;
155        r = sqrt(dx * dx + dy * dy);
156
157        angle1 = atan2(dy, dx);
158        angle2 = atan2(y3 - y1, x3 - x1);
159
160        circle = (abs(angle2 - angle1) < Constants.Grain);
161
162        while (angle1 < 0.0) {
163            angle1 += TWO_PI;
164        }
165
166        while (angle2 <= angle1) {
167            angle2 += TWO_PI;
168        }
169
170    }
171
172    /**
173     * The GeomSS geometry element is created from the IGES parameters when this method is
174     * called.
175     */
176    @Override
177    void createGeometry() throws IOException {
178
179        //  Define some inputs required.
180        Point center = Point.valueOf(x1, y1, zt, Constants.unit);
181        Parameter<Length> radius = Parameter.valueOf(r, Constants.unit);
182        Vector<Dimensionless> normal = Vector.valueOf(0, 0, 1).toUnitVector();
183
184        if (circle) {
185            //  We have a full circle.
186            curve = CurveFactory.createCircle(center, radius, normal);
187
188        } else {
189            //  We have an arc.
190            Parameter<Angle> thetaS = Parameter.valueOf(angle1, SI.RADIAN);
191            Parameter<Angle> thetaE = Parameter.valueOf(angle2, SI.RADIAN);
192            curve = CurveFactory.createCircularArc(center, radius, normal, thetaS, thetaE);
193        }
194
195    }
196
197    /**
198     * Method used to apply IGES meta-data to GeomSS elements. This implementation stores
199     * in the user data, in addition to the header info, all the parameter information for
200     * this entity type prefixed by "IGES_100_".
201     */
202    @Override
203    protected void applyMetaData(GeomElement element) {
204        super.applyMetaData(element);
205        element.putUserData("IGES_100_ZT", zt);
206        element.putUserData("IGES_100_X1", x1);
207        element.putUserData("IGES_100_Y1", y1);
208        element.putUserData("IGES_100_X2", x2);
209        element.putUserData("IGES_100_Y2", y2);
210        element.putUserData("IGES_100_X3", x3);
211        element.putUserData("IGES_100_Y3", y3);
212    }
213
214    /**
215     * Return a reference to the Transformable GeomElement contained in this IGES Entity.
216     *
217     * @return A reference to the Transformable GeomElement contained in this IGES Entity.
218     */
219    @Override
220    protected Transformable getGeomElement() {
221        return curve;
222    }
223
224    /**
225     * Returns a short String describing this Entity object's type.
226     *
227     * @return A short String describing this Entity object's type.
228     */
229    @Override
230    public String getTypeString() {
231        return "Entity100 - Circular Arc";
232    }
233
234    /**
235     * Dump to String.
236     *
237     * @return String containing the resulting text.
238     */
239    @Override
240    public String toString() {
241        StringBuilder outStr = new StringBuilder(super.toString());
242        outStr.append("\n");
243
244                outStr.append("zt = "); outStr.append(zt);      outStr.append("\n");
245                outStr.append("x1 = "); outStr.append(x1);      outStr.append("\n");
246                outStr.append("y1 = "); outStr.append(y1);      outStr.append("\n");
247                outStr.append("x2 = "); outStr.append(x2);      outStr.append("\n");
248                outStr.append("y2 = "); outStr.append(y2);      outStr.append("\n");
249                outStr.append("x3 = "); outStr.append(x3);      outStr.append("\n");
250                outStr.append("y3 = "); outStr.append(y3);
251
252        return outStr.toString();
253    }
254
255}