001/*
002
003*/
004
005package renderer.models;
006import  renderer.scene.*;
007
008/**
009   Create a wireframe model of a partial sphere centered at the origin
010<p>
011   See <a href="https://en.wikipedia.org/wiki/Sphere" target="_top">
012                https://en.wikipedia.org/wiki/Sphere</a>
013<p>
014   By a partial sphere we mean cutting a hole in the sphere around
015   either the north or the south pole (that is, removing a spherical
016   cap from either the top or bottom of the sphere) and also cutting
017   from the sphere a spherical wedge between two lines of longitude.
018<p>
019   Notice that we can use this model to both model a spherical wedge
020   and to model a sphere with a spherical wedge removed from it.
021<p>
022   Similarly, we can use this model to both model a spherical cap
023   and to model a sphere with a spherical cap removed from it.
024<p>
025   See <a href="https://en.wikipedia.org/wiki/Spherical_cap" target="_top">
026                https://en.wikipedia.org/wiki/Spherical_cap</a>
027<p>
028   See <a href="https://en.wikipedia.org/wiki/Spherical_segment" target="_top">
029                https://en.wikipedia.org/wiki/Spherical_segment</a>
030<p>
031   See <a href="https://en.wikipedia.org/wiki/Spherical_wedge" target="_top">
032                https://en.wikipedia.org/wiki/Spherical_wedge</a>
033<p>
034   The whole sphere of radius {@code r} is the surface of revolution generated
035   by revolving the right half-circle in the xy-plane with radius {@code r} and
036   center {@code (0,0,0)} all the way around the y-axis.
037<p>
038   Here are parametric equations for the right half-circle in the xy-plane with
039   radius {@code r} and center {@code (0,0,0)}, parameterized from the top down.
040   <pre>{@code
041      x(phi) = r * sin(phi)  \
042      y(phi) = r * cos(phi)   |-  0 <= phi <= PI
043      z(phi) = 0             /
044   }</pre>
045   Here is the 3D rotation matrix that rotates around the y-axis
046   by {@code theta} radians, {@code 0 <= theta <= 2*PI}
047   <pre>{@code
048      [ cos(theta)   0   sin(theta)]
049      [     0        1       0     ]
050      [-sin(theta)   0   cos(theta)]
051   }</pre>
052   If we multiply the rotation matrix with the half-circle
053   parameterization, we get a parameterization of the sphere.
054   <pre>{@code
055      [ cos(theta)   0   sin(theta)]   [r * sin(phi)]
056      [     0        1       0     ] * [r * cos(phi)]
057      [-sin(theta)   0   cos(theta)]   [     0      ]
058
059      = ( r * sin(phi) * cos(theta).    \
060          r * cos(phi),                  |- 0<=theta<=2*PI,  0<=phi<=PI
061         -r * sin(phi) * sin(theta) )   /
062   }</pre>
063   See
064     <a href="https://en.wikipedia.org/wiki/Sphere#Equations_in_three-dimensional_space" target="_top">
065              https://en.wikipedia.org/wiki/Sphere#Equations_in_three-dimensional_space</a>
066
067   @see Sphere
068*/
069public class SphereSector extends Model
070{
071   /**
072      Create half of a sphere of radius 1 centered at the origin.
073   */
074   public SphereSector()
075   {
076      this(1, Math.PI/2, 3*Math.PI/2, 15, 8);
077   }
078
079
080   /**
081      Create a part of the sphere of radius r centered at the origin.
082   <p>
083      If {@code theta1 > 0} or {@code theta2 < 2*PI}, then a spherical
084      wedge is removed from the model. In other words, the (partial)
085      circles of latitude in the model extend from angle {@code theta1}
086      to angle {@code theta2}.
087   <p>
088      The last two parameters determine the number of half circles of
089      longitude and the number of (partial) circles of latitude in the model.
090   <p>
091      Notice that if there are {@code k} half circles of longitude, then
092      each (partial) circle of latitude will have {@code k-1} line segments.
093      If there are {@code n} circles of latitude, then each half circle of
094      longitude will have {@code n+1} line segments.
095   <p>
096      There must be at least four half circles of longitude and
097      at least one circle of latitude.
098
099      @param r       radius of the sphere
100      @param theta1  beginning longitude angle of the spherical wedge
101      @param theta2  ending longitude angle of the spherical wedge
102      @param n       number of circles of latitude
103      @param k       number of lines of longitude, not counting the edges of a spherical wedge
104   */
105   public SphereSector(double r, double theta1, double theta2,
106                                 int n, int k)
107   {
108      this(r, theta1, theta2, 0, Math.PI, n+2, k);
109   }
110
111
112   /**
113      Create a part of the sphere of radius r centered at the origin.
114   <p>
115      If {@code phi1 > 0}, then there is hole in the sphere around its
116      north pole. Similarly, if {@code phi2 < PI}, then there is a hole
117      in the sphere around its south pole. In other words, in spherical
118      coordinates, lines of longitude in the model extend from angle
119      {@code phi1} to angle {@code phi2}.
120   <p>
121      If {@code theta1 > 0} or {@code theta2 < 2*PI}, then a spherical
122      wedge is removed from the model. In other words, the (partial)
123      circles of latitude in the model extend from angle {@code theta1}
124      to angle {@code theta2}.
125   <p>
126      The last two parameters determine the number of lines of longitude
127      and the number of (partial) circles of latitude in the model.
128   <p>
129      Notice that if there are {@code k} lines of longitude, then each
130      (partial) circle of latitude will have {@code k-1} line segments.
131      If there are {@code n} circles of latitude (including the edges of
132      the removed spherical caps), then each line of longitude will have
133      {@code n-1} line segments.
134   <p>
135      There must be at least four lines of longitude and at least
136      three circles of latitude.
137
138      @param r       radius of the sphere
139      @param theta1  beginning longitude angle of the spherical wedge
140      @param theta2  ending longitude angle of the spherical wedge
141      @param phi1    beginning latitude angle of the spherical segment
142      @param phi2    ending latitude angle of the spherical segment
143      @param n       number of circles of latitude, not counting the edges of a spherical segment
144      @param k       number of lines of longitude, not counting one edge of a spherical wedge
145   */
146   public SphereSector(double r,
147                       double theta1, double theta2,
148                       double phi1,   double phi2,
149                       int n, int k)
150   {
151      super();
152
153      if (n < 3) n = 3;
154      if (k < 4) k = 4;
155
156      // Create the sphere section's geometry.
157
158      double deltaPhi = (phi2 - phi1) / (n - 1);
159      double deltaTheta = (theta2 - theta1) / (k - 1);
160
161      // An array of vertices to be used to create line segments.
162      Vertex[][] v = new Vertex[n][k];
163
164      // Create all the vertices.
165      for (int j = 0; j < k; j++) // choose an angle of longitude
166      {
167         double c1 = Math.cos(theta1 + j * deltaTheta);
168         double s1 = Math.sin(theta1 + j * deltaTheta);
169         for (int i = 0; i < n; i++) // choose an angle of latitude
170         {
171            double c2 = Math.cos(phi1 + i * deltaPhi);
172            double s2 = Math.sin(phi1 + i * deltaPhi);
173            v[i][j] = new Vertex( r * s2 * c1,
174                                  r * c2,
175                                 -r * s2 * s1 );
176         }
177      }
178
179      // Create the horizontal (partial) circles of latitude around the sphere.
180      for (int i = 0; i < n; i++)
181      {
182         for (int j = 0; j < k - 1; j++)
183         {
184            addLineSegment(v[i][j], v[i][j+1]);
185         }
186      }
187
188      // Create the vertical lines of longitude from the top edge to the bottom edge.
189      for (int j = 0; j < k; j++)
190      {
191         for (int i = 0; i < n - 1; i++)
192         {
193            addLineSegment(v[i][j], v[i+1][j]);
194         }
195      }
196   }
197}//SphereSector