/* Java2DModel.java Representation of a 3D model as a wire frame of line segments tailored for use in a Java2D environment. History: 10 Jun 2008 Extracted and adapted from Model3D class in JTwoD.java. */ import java.io.*; /** The representation of a 3D model. Used by JTwoD. @see JTwoD */ class Java2DModel extends Model3D { /** Class for storing LineSegment data. */ static class LineSegment { public final int m_p1, m_p2; // end points (indices into m_points) public final int m_type; LineSegment(int p1, int p2, int type) { m_p1 = p1; m_p2 = p2; m_type = type; } } /** Average x value (in model coordinates) for the figure. */ float m_xmean; /** Average y value (in model coordinates) for the figure. */ float m_ymean; /** Average z value (in model coordinates) for the figure. */ float m_zmean; /** Radius (in model coordinates) of the figure's bounding sphere. */ float m_radius; /** Untransformed (model) coordinates for all points. */ private tuple3d m_verts[]; /** Size of used portion of vertex array. */ private int m_nverts; /** Minimum size of vertex and line arrays. */ static final int M_MIN_BUFFSIZE = 50; /** Lines in the model. */ private LineSegment m_lines[]; /** Indicates how many of the values in m_lines are valid. Incremented by addLine(). @see #m_lines @see #addLine */ private int m_nlines; Java2DModel() { } /** Zero vertex and line counts. */ public void reset() { m_nverts = 0; m_nlines = 0; } /** See how many vertices are in the current model -- can also be used to check if a model has been loaded. */ int nverts() { return m_nverts; } /** Get vertices for the current model. */ tuple3d[] verts() { return m_verts; } /** See how many lines are in the current model. */ int nlines() { return m_nlines; } /** Index of first end point for given line. */ int p1(int index) { return m_lines[index].m_p1; } /** Index of second end point for given line. */ int p2(int index) { return m_lines[index].m_p2; } /** Type value for given line. */ int type(int index) { return m_lines[index].m_type; } /** Add a point to this model. Implements abstract method. @param x x coordinate of point @param y y coordinate of point @param z z coordinate of point */ void addPoint(double x, double y, double z) { if (m_verts == null) m_verts = new tuple3d[M_MIN_BUFFSIZE]; else if (m_nverts >= m_verts.length) { tuple3d nv[] = new tuple3d[m_verts.length*2]; System.arraycopy(m_verts, 0, nv, 0, m_verts.length); m_verts = nv; } if (m_verts[m_nverts] == null) m_verts[m_nverts] = new tuple3d((float)x, (float)y, (float)z); else m_verts[m_nverts].set((float)x, (float)y, (float)z); m_nverts++; } /** Add a line segment from vertex p1 to vertex p2 to the model's geometry. Implements abstract method. @param p1 zero-based index of first endpoint @param p2 zero-based index of second endpoint @param type type value for this line segment */ void addLineSegment(int p1, int p2, int type) { if (p1 >= m_nverts || p2 >= m_nverts) return; if (m_lines == null) m_lines = new LineSegment[M_MIN_BUFFSIZE]; else if (m_nlines >= m_lines.length) { LineSegment lines[] = new LineSegment[m_lines.length*2]; System.arraycopy(m_lines, 0, lines, 0, m_lines.length); m_lines = lines; } m_lines[m_nlines] = new LineSegment(p1, p2, type); m_nlines++; } /** Compute the bounding sphere (in model coordinates) of this model. Implements abstract method. @see #m_xmean @see #m_ymean @see #m_zmean @see #m_radius */ void computeBoundingSphere() { if (m_nverts <= 0) return; // find center m_xmean = 0f; m_ymean = 0f; m_zmean = 0f; for (int i = 0; i < m_nverts; i++) { m_xmean += m_verts[i].x(); m_ymean += m_verts[i].y(); m_zmean += m_verts[i].z(); } m_xmean /= m_nverts; m_ymean /= m_nverts; m_zmean /= m_nverts; // find radius m_radius = 0; for (int i = 0; i < m_nverts; i++) { float dx = m_verts[i].x() - m_xmean; float dy = m_verts[i].y() - m_ymean; float dz = m_verts[i].z() - m_zmean; float radius = dx*dx + dy*dy + dz*dz; if (radius > m_radius) m_radius = radius; } m_radius = (float)Math.sqrt(m_radius); } }