001/*
002
003*/
004
005package renderer.models;
006import  renderer.scene.*;
007
008/**
009   Create a wireframe model of a partial right circular cone with its
010   base parallel to the xz-plane and its apex on the positive y-axis.
011<p>
012   By a partial cone we mean a cone over a circular sector of the
013   cone's base and also cutting off the top part of the cone (the
014   part between the apex and a circle of latitude) leaving a frustum
015   of the (partial) cone.
016
017   @see Cone
018   @see ConeFrustum
019*/
020public class ConeSector extends Model
021{
022   /**
023      Create half of a right circular cone with its base in the xz-plane,
024      a base radius of 1, height 1, and apex on the positive y-axis.
025   */
026   public ConeSector( )
027   {
028      this(1, 1, Math.PI/2, 3*Math.PI/2, 15, 8);
029   }
030
031
032   /**
033      Create a part of the cone with its base in the xz-plane,
034      a base radius of {@code r}, height {@code h}, and apex
035      on the y-axis.
036   <p>
037      If {@code theta1 > 0} or {@code theta2 < 2pi},then the partial
038      cone is a cone over the circular sector from angle {@code theta1}
039      to angle {@code theta2}. In other words, the (partial) circles of
040      latitude in the model extend from angle {@code theta1} to angle
041      {@code theta2}.
042   <p>
043      The last two parameters determine the number of lines of longitude
044      and the number of (partial) circles of latitude in the model.
045   <p>
046      Notice that if there are {@code n} circles of latitude in the model
047      (including the bottom edge), then each line of longitude will have
048      {@code n} line segments. If there are {@code k} lines of longitude,
049      then each (partial) circle of latitude will have {@code k-1} line
050      segments.
051   <p>
052      There must be at least four lines of longitude and at least
053      one circle of latitude.
054
055      @param r       radius of the base in the xz-plane
056      @param h       height of the apex on the y-axis
057      @param theta1  beginning longitude angle of the sector
058      @param theta2  ending longitude angle of the sector
059      @param n       number of circles of latitude around the cone
060      @param k       number lines of longitude
061   */
062   public ConeSector(double r,
063                     double h,
064                     double theta1, double theta2,
065                     int n, int k)
066   {
067      this(r, h, h, theta1, theta2, n+1, k);
068   }
069
070
071   /**
072      Create a part of the cone with its base in the xz-plane,
073      a base radius of {@code r}, height {@code  h}, and apex
074      on the y-axis.
075   <p>
076      If {@code 0 < t < h}, then the partial cone is a frustum
077      with its base in the xz-plane and the top of the frustum at
078      {@code y = t}.
079   <p>
080      If {@code theta1 > 0} or {@code theta2 < 2pi},then the partial
081      cone is a cone over the circular sector from angle {@code theta1}
082      to angle {@code theta2}. In other words, the (partial) circles of
083      latitude in the model extend from angle {@code theta1} to angle
084      {@code theta2}.
085   <p>
086      The last two parameters determine the number of lines of longitude
087      (not counting one edge of any removed sector) and the number of
088      (partial) circles of latitude (not counting the top edge of the
089      frustum) in the model.
090   <p>
091      Notice that if there are {@code n} circles of latitude in the model
092      (including the bottom edge but not the top edge of the frustum), then
093      each line of longitude will have {@code n+1} line segments. If there
094      are {@code k} lines of longitude (not counting one edge of any removed
095      sector), then each (partial) circle of latitude will have {@code k}
096      line segments.
097   <p>
098      There must be at least four lines of longitude and at least
099      two circles of latitude.
100
101      @param r       radius of the base in the xz-plane
102      @param h       height of the apex on the y-axis
103      @param t       top of the frustum of the come
104      @param theta1  beginning longitude angle of the sector
105      @param theta2  ending longitude angle of the sector
106      @param n       number of circles of latitude around the cone
107      @param k       number lines of longitude
108   */
109   public ConeSector(double r,
110                     double h,
111                     double t,
112                     double theta1, double theta2,
113                     int n, int k)
114   {
115      this(r, 0, h, t, theta1, theta2, n, k);
116   }
117
118
119   /**
120      Create a part of the cone with its base in the plane {@code y = h1},
121      a base radius of {@code r}, and apex on the y-axis at {@code h = h2}.
122   <p>
123      If {@code h1 < t < h2}, then the partial cone is a frustum with its
124      base in the plane {@code y = h1} and the top of the frustum at
125      {@code y = t}.
126   <p>
127      If {@code theta1 > 0} or {@code theta2 < 2pi},then the partial cone
128      is a cone over the circular sector from angle {@code theta1} to angle
129      {@code theta2}. In other words, the (partial) circles of latitude
130      in the model extend from angle {@code theta1} to angle {@code theta2}.
131   <p>
132      The last two parameters determine the number of lines of longitude
133      and the number of (partial) circles of latitude in the model.
134   <p>
135      Notice that if there are {@code n} circles of latitude in the model
136      (including the bottom edge but not the top edge of the frustum), then
137      each line of longitude will have {@code n+1} line segments. If there
138      are {@code k} lines of longitude (not counting one edge of any removed
139      sector), then each (partial) circle of latitude will have {@code k}
140      line segments.
141   <p>
142      There must be at least four lines of longitude and at least
143      two circles of latitude.
144
145      @param r       radius of the base of the cone
146      @param h1      height (on the y-axis) of the base of the cone
147      @param h2      height (on the y-axis) of the apex of the cone
148      @param t       height (on the y-axis) of the top of the frustum of the cone
149      @param theta1  beginning longitude angle of the sector
150      @param theta2  ending longitude angle of the sector
151      @param n       number of circles of latitude around the cone
152      @param k       number lines of longitude
153   */
154   public ConeSector(double r,
155                     double h1, double h2,
156                     double t,
157                     double theta1, double theta2,
158                     int n, int k)
159   {
160      super();
161
162      if (n < 2) n = 2;
163      if (k < 4) k = 4;
164      if (t > h2) t = h2;
165      if (t < h1) t = h1;
166
167      // Create the cone's geometry.
168
169      double deltaH = (t - h1) / (n - 1);
170      double deltaTheta = (theta2 - theta1) / (k - 1);
171
172      // An array of vertices to be used to create line segments.
173      Vertex[][] v = new Vertex[n][k];
174
175      // Create all the vertices.
176      for (int j = 0; j < k; j++) // choose an angle of longitude
177      {
178         double c = Math.cos(theta1 + j * deltaTheta);
179         double s = Math.sin(theta1 + j * deltaTheta);
180         for (int i = 0; i < n; i++) // choose a circle of latitude
181         {
182            double slantRadius = r * (1 - i * deltaH / (h2 - h1));
183            v[i][j] = new Vertex( slantRadius * c,
184                                  h1 + i * deltaH,
185                                  slantRadius * s );
186         }
187      }
188      Vertex apex = new Vertex(0, h2, 0);
189      Vertex bottomCenter = new Vertex(0, h1, 0);
190
191      // Create the horizontal (partial) circles of latitude around the cone.
192      for (int i = 0; i < n; i++)
193      {
194         for (int j = 0; j < k - 1; j++)
195         {
196            addLineSegment(new LineSegment(new Vertex(v[i][j]),
197                                           new Vertex(v[i][j+1])));
198         }
199      }
200
201      // Create the slanted lines of longitude from the base to the
202      // top circle of latitude, and the triangle fan in the base.
203      for (int j = 0; j < k; j++)
204      {
205         addLineSegment(new LineSegment(new Vertex(bottomCenter),
206                                        new Vertex(v[0][j])));
207
208         for (int i = 0; i < n - 1; i++)
209         {
210            addLineSegment(new LineSegment(new Vertex(v[i][j]),
211                                           new Vertex(v[i+1][j])));
212         }
213      }
214   }
215}//ConeSector