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 cube with its center 014 at the origin, having edge length 2, and with its 015 corners at {@code (±1, ±1, ±1)}. 016<p> 017 This version of the cube model has the top and bottom 018 faces of the cube cut up by a triangle fan and the 019 front, back, right, and left faces cut up by a grid 020 of perpendicular lines. 021<p> 022 Here is a picture showing how the cube's eight 023 corners are labeled. 024<pre>{@code 025 v4=(-1,1,-1) 026 +---------------------+ v5=(1,1,-1) 027 /| /| 028 / | / | 029 / | / | 030 / | / | 031 / | / | 032 v7 +---------------------+ v6 | 033 | | | | 034 | | | | 035 | | v0=(-1,-1,-1) | | 036 | +---------------|-----+ v1=(1,-1,-1) 037 | / | / 038 | / | / 039 | / | / 040 | / | / 041 |/ |/ 042 +---------------------+ 043 v3=(-1,-1,1) v2=(1,-1,1) 044}</pre> 045 046 @see Cube 047 @see Cube2 048 @see Cube3 049*/ 050public class Cube4 extends Model 051{ 052 /** 053 Create a cube with its center at the origin, having edge 054 length 2, with its corners at {@code (±1, ±1, ±1)}. with 055 a triangle fan of eight triangles in top and bottom faces, 056 and two perpendicular lines cutting each of the front, 057 back, right, and left faces. 058 */ 059 public Cube4( ) 060 { 061 this(2, 1, 2); 062 } 063 064 065 /** 066 Create a cube with its center at the origin, having edge 067 length 2, with its corners at {@code (±1, ±1, ±1)}, and 068 with the top and bottom faces containing a triangle fan 069 with the given number of triangles along each of the x, 070 and z directions. 071 <p> 072 There must be at least one triangle along the x and z directions. 073 074 @param xCount number of triangles along the x-direction 075 @param yGrid number of grid lines perpendicular to the y-axis 076 @param zCount number of triangles along the z-direction 077 @throws IllegalArgumentException if {@code xCount} is less than 1 078 @throws IllegalArgumentException if {@code yGrid} is less than 0 079 @throws IllegalArgumentException if {@code zCount} is less than 1 080 */ 081 public Cube4(final int xCount, final int yGrid, final int zCount) 082 { 083 super(String.format("Cube4(%d,%d,%d)", xCount, yGrid, zCount)); 084 085 if (xCount < 1) 086 throw new IllegalArgumentException("xCount must be greater than or equal to 1"); 087 if (yGrid < 0) 088 throw new IllegalArgumentException("yGrid must be greater than or equal to 0"); 089 if (zCount < 1) 090 throw new IllegalArgumentException("zCount must be greater than or equal to 1"); 091 092 final double xStep = 2.0 / xCount, 093 yStep = 2.0 / (1 + yGrid), 094 zStep = 2.0 / zCount; 095 096 // An array of vertices to be used to create primitives. 097 final Vertex[][] v = new Vertex[2 + yGrid][2*xCount + 2*zCount]; 098 099 // Create all the vertices. 100 for (int i = 0; i < 2 + yGrid; ++i) // choose a height of latitude 101 { 102 for(int j = 0; j < xCount; ++j) 103 { 104 v[i][j] = new Vertex(-1 + j*xStep, // move right 105 -1 + i*yStep, 106 -1); 107 } 108 for(int j = 0; j < zCount; ++j) 109 { 110 v[i][xCount + j] = new Vertex( 1, 111 -1 + i*yStep, 112 -1 + j*zStep); // move forward 113 } 114 for(int j = 0; j < xCount; ++j) 115 { 116 v[i][xCount+zCount + j] = new Vertex( 1 - j*xStep, // move left 117 -1 + i*yStep, 118 1); 119 } 120 for(int j = 0; j < zCount; ++j) 121 { 122 v[i][2*xCount+zCount + j] = new Vertex(-1, 123 -1 + i*yStep, 124 1 - j*zStep); // backwards 125 } 126 } 127 128 // Add all of the vertices to this model. 129 for (int i = 0; i < 2 + yGrid; ++i) 130 { 131 for (int j = 0; j < 2*xCount + 2*zCount; ++j) 132 { 133 addVertex( v[i][j] ); 134 } 135 } 136 addVertex(new Vertex(0, -1, 0), // center bottom 137 new Vertex(0, 1, 0)); // center top 138 final int cBottom = (2 + yGrid) * (2*xCount + 2*zCount); 139 final int cTop = cBottom + 1; 140 141 // Create the line fans in the cube's bottom and top sides. 142 for (int j = 0; j < 2*xCount + 2*zCount; ++j) 143 { 144 addPrimitive( 145 new LineSegment(cBottom, 146 j), // v[0][j] 147 new LineSegment(cTop, 148 (yGrid+1)*(2*xCount+2*zCount)+j)); // v[2+yGrid-1][j] 149 } 150 151 // Create all the loops around the cube's vertical sides. 152 for (int i = 0; i < 2 + yGrid; ++i) // choose a height of latitude 153 { 154 for (int j = 0; j < 2*xCount + 2*zCount - 1; ++j) 155 { 156 addPrimitive( 157 new LineSegment(i*(2*xCount+2*zCount)+j, // v[i][j] 158 i*(2*xCount+2*zCount)+j+1)); // v[i][j+1] 159 } 160 addPrimitive( 161 new LineSegment((1+i)*(2*xCount+2*zCount) - 1, // v[i][2*xCount + 2*zCount-1] 162 i *(2*xCount+2*zCount))); // v[i][0] 163 } 164 165 // Create all the vertical lines in the cube's vertical sides. 166 for (int j = 0; j < 2*xCount + 2*zCount; ++j) 167 { 168 for (int i = 0; i < 2 + yGrid - 1; ++i) // choose a height of latitude 169 { 170 addPrimitive( 171 new LineSegment( i *(2*xCount+2*zCount)+j, // v[i ][j] 172 (i+1)*(2*xCount+2*zCount)+j)); // v[i+1][j] 173 } 174 } 175 176 177 } 178}//Cube4