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