001/*
002
003*/
004
005package renderer.models;
006import  renderer.scene.*;
007
008/**
009   Create a wireframe model of a right equilateral triangular prism
010   with the y-axis as its central axis.
011<p>
012   See <a href="https://en.wikipedia.org/wiki/Triangular_prism" target="_top">
013                https://en.wikipedia.org/wiki/Triangular_prism</a>
014<p>
015   See <a href="https://en.wikipedia.org/wiki/Prism_(geometry)" target="_top">
016                https://en.wikipedia.org/wiki/Prism_(geometry)</a>
017<p>
018   Attach to each triangular end of the prism a tetrahedron.
019*/
020public class TriangularPrism extends Model
021{
022   /**
023      Create a right equilateral triangular prism with a
024      regular tetrahedrons attached to each end so that
025      the total length runs from -1 to 1 along the y-axis.
026   */
027   public TriangularPrism( )
028   {
029      this(0.5, 0.6);
030   }
031
032
033   /**
034      Create an equilateral triangular prism that runs
035      from {@code -h} to {@code h} along the y-axis, has
036      triangle side length {@code s}, and has a regular
037      tetrahedron attached to each end.
038
039      @param s  the length of the triangle's sides
040      @param h  the body of the prism runs from -h to h along the y-axis
041   */
042   public TriangularPrism(double s, double h)
043   {
044      this(s, h, 0);
045   }
046
047
048   /**
049      Create an equilateral triangular prism that runs
050      from {@code -h} to {@code h} along the y-axis, has
051      triangle side length {@code s}, has a regular
052      tetrahedron attached to each end, and has {@code n}
053      lines of latitude around the body of the prism.
054
055      @param s  the length of the triangle's sides
056      @param h  the body of the prism runs from -h to h along the y-axis
057      @param n  number of lines of latitude around the body of the prism
058   */
059   public TriangularPrism(double s, double h, int n)
060   {
061      this(s/Math.sqrt(3), h, Math.atan(Math.sqrt(2)), n);
062   }
063
064
065   /**
066      Create an equilateral triangular prism that runs
067      from {@code -h} to {@code h} along the y-axis, with
068      the triangle inscribed in a circle of radius {@code r},
069      has a tetrahedron attached to each end where the
070      face-edge-face angle of each tetrahedron is {@code theta}
071      (with theta in radians!), and has {@code n} lines of
072      latitude around the body of the prism.
073   <p>
074      If {@code theta = 0}, then there are no tetrahedrons at the ends of the prism.
075   <p>
076      If {@code theta = arctan(sqrt(2)) = 54.736°}, then the tetrahedrons are regular.
077
078      @param r      radius of circle in xz-plane that the equilateral triangle is inscribed in
079      @param h      the body of the prism runs from -h to h along the y-axis
080      @param theta  slant angle of each tetrahedron at the ends of the prism
081      @param n      number of lines of latitude around the body of the prism
082   */
083   public TriangularPrism(double r, double h, double theta, int n)
084   {
085      this(r, h, r*Math.tan(theta), n, true);
086   }
087
088
089   /**
090      Create an equilateral triangular prism that runs
091      from {@code -h} to {@code h} along the y-axis, with
092      the triangle inscribed in a circle of radius {@code r},
093      has a tetrahedron attached to each end where the height
094      of each tetrahedron is {@code h2}, and has {@code n} lines
095      of latitude around the body of the prism.
096   <p>
097      So the total height is {@code 2*(h + h2)}.
098
099      @param r   radius of circle in xz-plane that the equilateral triangle is inscribed in
100      @param h   the body of the prism runs from h to -h in the y-direction
101      @param h2  height of each tetrahedron at the ends of the prism
102      @param n   number of lines of latitude around the body of the prism
103      @param bothHalves  determines if both halves or only the top half gets created
104   */
105   public TriangularPrism(double r, double h, double h2, int n, boolean bothHalves)
106   {
107      super();
108
109      if (n < 0) n = 0;
110
111      // Create the prism's geometry.
112      double sqrt3 = Math.sqrt(3.0);
113      Vertex[] v = new Vertex[8];
114
115      // three vertices around the top
116      v[0] = new Vertex( r,    h,    0);
117      v[1] = new Vertex(-r/2,  h,  r*0.5*sqrt3);
118      v[2] = new Vertex(-r/2,  h, -r*0.5*sqrt3);
119
120      // three vertices around the bottom
121      v[3] = new Vertex( r,   -h,    0);
122      v[4] = new Vertex(-r/2, -h,  r*0.5*sqrt3);
123      v[5] = new Vertex(-r/2, -h, -r*0.5*sqrt3);
124      if (! bothHalves)  // cut off the bottom half
125      {
126         v[3] = new Vertex( r,    0,    0);
127         v[4] = new Vertex(-r/2,  0,  r*0.5*sqrt3);
128         v[5] = new Vertex(-r/2,  0, -r*0.5*sqrt3);
129      }
130
131      v[6] = new Vertex(0,  h+h2, 0);  // vertex at the top
132      v[7] = new Vertex(0, -h-h2, 0);  // vertex at the bottom
133      if (! bothHalves)  // cut off the bottom half
134      {
135         v[7] = new Vertex(0, 0, 0);   // vertex at the bottom
136      }
137
138      // Create 15 line segments.
139      // 3 top faces
140      addLineSegment(new LineSegment(new Vertex(v[6]), new Vertex(v[0])));
141      addLineSegment(new LineSegment(new Vertex(v[6]), new Vertex(v[1])));
142      addLineSegment(new LineSegment(new Vertex(v[6]), new Vertex(v[2])));
143      // the top edge
144      addLineSegment(new LineSegment(new Vertex(v[0]), new Vertex(v[1])));
145      addLineSegment(new LineSegment(new Vertex(v[1]), new Vertex(v[2])));
146      addLineSegment(new LineSegment(new Vertex(v[2]), new Vertex(v[0])));
147      // three vertical edges
148      addLineSegment(new LineSegment(new Vertex(v[0]), new Vertex(v[3])));
149      addLineSegment(new LineSegment(new Vertex(v[1]), new Vertex(v[4])));
150      addLineSegment(new LineSegment(new Vertex(v[2]), new Vertex(v[5])));
151      // the bottom edge
152      addLineSegment(new LineSegment(new Vertex(v[3]), new Vertex(v[4])));
153      addLineSegment(new LineSegment(new Vertex(v[4]), new Vertex(v[5])));
154      addLineSegment(new LineSegment(new Vertex(v[5]), new Vertex(v[3])));
155      // 3 bottom faces
156      addLineSegment(new LineSegment(new Vertex(v[7]), new Vertex(v[3])));
157      addLineSegment(new LineSegment(new Vertex(v[7]), new Vertex(v[4])));
158      addLineSegment(new LineSegment(new Vertex(v[7]), new Vertex(v[5])));
159
160      // Create n lines of latitude around the prism.
161      if (n > 0)
162      {
163         Vertex[][] v2 = new Vertex[n][3];
164
165         double delta_y = 2.0*h/(n+1);
166         if (! bothHalves)  // cut off the bottom half
167         {
168            delta_y = h/(n+1);
169         }
170
171         for (int j = 0; j < n; j++)
172         {
173            double y = -h + (j+1) * delta_y;
174            if (! bothHalves)  // cut off the bottom half
175            {
176               y = (j+1) * delta_y;
177            }
178            v2[j][0] = new Vertex( r,    y,    0);
179            v2[j][1] = new Vertex(-r/2,  y,  r*0.5*sqrt3);
180            v2[j][2] = new Vertex(-r/2,  y, -r*0.5*sqrt3);
181
182            addLineSegment(new LineSegment(new Vertex(v2[j][0]), new Vertex(v2[j][1])));
183            addLineSegment(new LineSegment(new Vertex(v2[j][1]), new Vertex(v2[j][2])));
184            addLineSegment(new LineSegment(new Vertex(v2[j][2]), new Vertex(v2[j][0])));
185         }
186      }
187   }
188}//TriangularPrism