001/*
002
003*/
004
005package renderer.models;
006import  renderer.scene.*;
007
008/**
009   Create a wireframe model of a frustum of a right square pyramid
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 Pyramid
016*/
017public class PyramidFrustum extends Model
018{
019   /**
020      Create a frustum of a right square pyramid with its base in the
021      xz-plane, a base side length of 2, top side length of 1, and height 1/2.
022   */
023   public PyramidFrustum( )
024   {
025      this(2.0, 1.0, 0.5, 7, 4);
026   }
027
028
029   /**
030      Create a frustum of a right square pyramid with its base in the
031      xz-plane, a base side length of {@code s1}, top side length of
032      {@code s2}, and height {@code h}.
033   <p>
034      Notice that this model works with either {@code s1 > s2} or
035      {@code s1 < s2}. In other words, the frustum can have its "apex"
036      either above or below the xz-plane.
037
038      @param s1  side length of the base of the frustum
039      @param s2  side length of the top of the frustum
040      @param h   height of the frustum
041      @param n   number of lines of latitude
042      @param k   number of lines of longitude
043   */
044   public PyramidFrustum(double s1, double s2, double h, int n, int k)
045   {
046      super();
047
048      if (n < 0) n = 0;
049      if (k < 1) k = 1;
050
051      // Create the frustum's geometry.
052
053      // Create all the lines of longitude from the top, down to the base,
054      // across the base, then back up to the top, and across the top.
055      s1 = s1/2;
056      s2 = s2/2;
057      double delta1 = (2 * s1) / k;
058      double delta2 = (2 * s2) / k;
059      // lines of "longitude" perpendicular to the x-axis
060      for (int j = 0; j <= k; j++)
061      {
062         double d1 = j * delta1;
063         double d2 = j * delta2;
064         addLineSegment(new Vertex(-s2+d2, h, -s2), new Vertex(-s1+d1, 0, -s1));
065         addLineSegment(new Vertex(-s1+d1, 0, -s1), new Vertex(-s1+d1, 0,  s1));
066         addLineSegment(new Vertex(-s1+d1, 0,  s1), new Vertex(-s2+d2, h,  s2));
067         addLineSegment(new Vertex(-s2+d2, h,  s2), new Vertex(-s2+d2, h, -s2));
068      }
069      // lines of "longitude" perpendicular to the z-axis
070      for (int j = 0; j <= k; j++)
071      {
072         double d1 = j * delta1;
073         double d2 = j * delta2;
074         addLineSegment(new Vertex( s2, h, -s2+d2), new Vertex( s1, 0, -s1+d1));
075         addLineSegment(new Vertex( s1, 0, -s1+d1), new Vertex(-s1, 0, -s1+d1));
076         addLineSegment(new Vertex(-s1, 0, -s1+d1), new Vertex(-s2, h, -s2+d2));
077         addLineSegment(new Vertex(-s2, h, -s2+d2), new Vertex( s2, h, -s2+d2));
078      }
079      // Create all the lines of "latitude" around the pyramid, starting
080      // from the base and working up to the top.
081      double deltaH = h / (n + 1);
082      double deltaS = (s1 - s2) / (n + 1);
083      double s = s1;
084      for (int i = 0; i <= n; i++)
085      {
086         h = i * deltaH;
087         addLineSegment(new Vertex( s, h,  s), new Vertex( s, h, -s));
088         addLineSegment(new Vertex( s, h, -s), new Vertex(-s, h, -s));
089         addLineSegment(new Vertex(-s, h, -s), new Vertex(-s, h,  s));
090         addLineSegment(new Vertex(-s, h,  s), new Vertex( s, h,  s));
091         s -= deltaS;
092      }
093   }
094}//PyramidFrustum