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 v0, v1, v2, v3, v4, v5, v6, v7;
114
115      // three vertices around the top
116      v0 = new Vertex( r,    h,    0);
117      v1 = new Vertex(-r/2,  h,  r*0.5*sqrt3);
118      v2 = new Vertex(-r/2,  h, -r*0.5*sqrt3);
119
120      // three vertices around the bottom
121      v3 = new Vertex( r,   -h,    0);
122      v4 = new Vertex(-r/2, -h,  r*0.5*sqrt3);
123      v5 = new Vertex(-r/2, -h, -r*0.5*sqrt3);
124      if (! bothHalves)  // cut off the bottom half
125      {
126         v3 = new Vertex( r,    0,    0);
127         v4 = new Vertex(-r/2,  0,  r*0.5*sqrt3);
128         v5 = new Vertex(-r/2,  0, -r*0.5*sqrt3);
129      }
130
131      v6 = new Vertex(0,  h+h2, 0);  // vertex at the top
132      v7 = new Vertex(0, -h-h2, 0);  // vertex at the bottom
133      if (! bothHalves)  // cut off the bottom half
134      {
135         v7 = new Vertex(0, 0, 0);   // vertex at the bottom
136      }
137
138      // Create 15 line segments.
139      // 3 top faces
140      addLineSegment(v6, v0);
141      addLineSegment(v6, v1);
142      addLineSegment(v6, v2);
143      // the top edge
144      addLineSegment(v0, v1);
145      addLineSegment(v1, v2);
146      addLineSegment(v2, v0);
147      // three vertical edges
148      addLineSegment(v0, v3);
149      addLineSegment(v1, v4);
150      addLineSegment(v2, v5);
151      // the bottom edge
152      addLineSegment(v3, v4);
153      addLineSegment(v4, v5);
154      addLineSegment(v5, v3);
155      // 3 bottom faces
156      addLineSegment(v7, v3);
157      addLineSegment(v7, v4);
158      addLineSegment(v7, v5);
159
160      // Create n lines of latitude around the prism.
161      if (n > 0)
162      {
163         double delta_y = 2.0*h/(n+1);
164         if (! bothHalves)  // cut off the bottom half
165         {
166            delta_y = h/(n+1);
167         }
168
169         for (int j = 0; j < n; j++)
170         {
171            double y = -h + (j+1) * delta_y;
172            if (! bothHalves)  // cut off the bottom half
173            {
174               y = (j+1) * delta_y;
175            }
176            Vertex v_0 = new Vertex( r,    y,    0);
177            Vertex v_1 = new Vertex(-r/2,  y,  r*0.5*sqrt3);
178            Vertex v_2 = new Vertex(-r/2,  y, -r*0.5*sqrt3);
179
180            addLineSegment(v_0, v_1);
181            addLineSegment(v_1, v_2);
182            addLineSegment(v_2, v_0);
183         }
184      }
185   }
186}//TriangularPrism