001/* 002 003*/ 004 005package renderer.models; 006import renderer.scene.*; 007 008/** 009 Create a wireframe model of a frustum of a right circular cone 010 with its base in the xz-plane. 011<p> 012 See <a href="https://en.wikipedia.org/wiki/Frustum" target="_top"> 013 https://en.wikipedia.org/wiki/Frustum</a> 014 015 @see Cone 016 @see ConeSector 017*/ 018public class ConeFrustum extends Model 019{ 020 /** 021 Create a frustum of a right circular cone with its base in the 022 xz-plane, a base radius of 1, top radius of 1/2, and height 1/2. 023 */ 024 public ConeFrustum( ) 025 { 026 this(1.0, 0.5, 0.5, 7, 16); 027 } 028 029 030 /** 031 Create a frustum of a right circular cone with its base in the 032 xz-plane, a base radius of {@code r1}, top radius of {@code r2}, 033 and height {@code h}. 034 <p> 035 Notice that this model works with either {@code r1 > r2} or 036 {@code r1 < r2}. In other words, the frustum can have its "apex" 037 either above or below the xz-plane. 038 <p> 039 There must be at least three lines of longitude and at least 040 two circles of latitude. 041 042 @param r1 radius of the base of the frustum 043 @param r2 radius of the top of the frustum 044 @param h height of the frustum 045 @param n number of circles of latitude 046 @param k number of lines of longitude 047 */ 048 public ConeFrustum(double r1, double r2, double h, int n, int k) 049 { 050 super(); 051 052 if (n < 2) n = 2; 053 if (k < 3) k = 3; 054 055 // Create the frustum's geometry. 056 057 double deltaTheta = (2 * Math.PI) / k; 058 059 // An array of vertices to be used to create line segments. 060 Vertex[][] v = new Vertex[n][k]; 061 062 // Create all the vertices. 063 for (int j = 0; j < k; j++) // choose an angle of longitude 064 { 065 double c = Math.cos(j * deltaTheta); 066 double s = Math.sin(j * deltaTheta); 067 for (int i = 0; i < n; i++) // choose a circle of latitude 068 { 069 double slantRadius = (i/(double)(n-1)) * r1 + ((n-1-i)/(double)(n-1)) * r2; 070 v[i][j] = new Vertex( slantRadius * c, 071 h - (i*h)/(n-1), 072 slantRadius * s ); 073 } 074 } 075 Vertex topCenter = new Vertex(0, h, 0); 076 Vertex bottomCenter = new Vertex(0, 0, 0); 077 078 // Create all the horizontal circles of latitude around the frustum wall. 079 for (int i = 0; i < n; i++) 080 { 081 for (int j = 0; j < k-1; j++) 082 { 083 addLineSegment(new LineSegment(new Vertex(v[i][j]), 084 new Vertex(v[i][j+1]))); 085 } 086 // close the circle 087 addLineSegment(new LineSegment(new Vertex(v[i][k-1]), 088 new Vertex(v[i][0]))); 089 } 090 091 // Create the vertical half-trapazoids of longitude from north to south pole. 092 for (int j = 0; j < k; j++) 093 { 094 // Create the triangle fan at the top. 095 addLineSegment(new LineSegment(new Vertex(topCenter), 096 new Vertex(v[0][j]))); 097 // Create the slant lines from the top to the base. 098 addLineSegment(new LineSegment(new Vertex(v[0][j]), 099 new Vertex(v[n-1][j]))); 100 // Create the triangle fan at the base. 101 addLineSegment(new LineSegment(new Vertex(v[n-1][j]), 102 new Vertex(bottomCenter))); 103 } 104 } 105}//ConeFrustum