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.*;
011import renderer.scene.util.MeshMaker;
012
013/**
014   Create a wireframe model of a square in the xy-plane centered at the origin.
015*/
016public class SquareGrid extends Model implements MeshMaker
017{
018   public final double r;
019   public final int n;
020   public final int k;
021
022   /**
023      Create a square in the xy-plane with corners {@code (±1, ±1, 0)}.
024   */
025   public SquareGrid( )
026   {
027      this(1, 0, 0);
028   }
029
030
031   /**
032      Create a square in the xy-plane with corners {@code (±1, ±1, 0)} and
033      with {@code n} grid lines parallel to each of the x and y axes.
034
035      @param n  number of grid lines parallel to the axes
036      @throws IllegalArgumentException if {@code n} is less than 0
037   */
038   public SquareGrid(final int n)
039   {
040      this(1, n, n);
041   }
042
043
044   /**
045      Create a square in the xy-plane with corners {@code (±1, ±1, 0)} and
046      with {@code n} grid lines parallel to the x-axis and
047      with {@code k} grid lines parallel to the y-axis.
048   <p>
049      If there are {@code n} grid lines parallel to the x-axis, then each
050      grid line parallel to the y-axis will have {@code n+1} line segments.
051      If there are {@code k} grid lines parallel to the y-axis, then each
052      grid line parallel to the x-axis will have {@code k+1} line segments.
053
054      @param n  number of grid lines parallel to the x-axis
055      @param k  number of grid lines parallel to the y-axis
056      @throws IllegalArgumentException if {@code n} is less than 0
057      @throws IllegalArgumentException if {@code k} is less than 0
058   */
059   public SquareGrid(final int n, final int k)
060   {
061      this(1, n, k);
062   }
063
064
065   /**
066      Create a square in the xy-plane with corners {@code (±r, ±r, 0)}.
067
068      @param r  determines the corners of the square
069      @throws IllegalArgumentException if {@code r} is less than or equal to 0
070   */
071   public SquareGrid(final double r)
072   {
073      this(r, 0, 0);
074   }
075
076
077   /**
078      Create a square in the xy-plane with corners {@code (±r, ±r, 0)} and
079      with {@code n} grid lines parallel to each of the x and y axes.
080
081      @param r  determines the corners of the square
082      @param n  number of grid lines parallel to the axes
083      @throws IllegalArgumentException if {@code n} is less than 0
084      @throws IllegalArgumentException if {@code r} is less than or equal to 0
085   */
086   public SquareGrid(final double r, final int n)
087   {
088      this(r, n, n);
089   }
090
091
092   /**
093      Create a square in the xy-plane with corners {@code (±r, ±r, 0)} and
094      with {@code n} grid lines parallel to the x-axis and
095      with {@code k} grid lines parallel to the y-axis.
096   <p>
097      If there are {@code n} grid lines parallel to the x-axis, then each
098      grid line parallel to the y-axis will have {@code n+1} line segments.
099      If there are {@code k} grid lines parallel to the y-axis, then each
100      grid line parallel to the x-axis will have {@code k+1} line segments.
101
102      @param r  determines the corners of the square
103      @param n  number of grid lines parallel to the x-axis
104      @param k  number of grid lines parallel to the y-axis
105      @throws IllegalArgumentException if {@code n} is less than 0
106      @throws IllegalArgumentException if {@code k} is less than 0
107      @throws IllegalArgumentException if {@code r} is less than or equal to 0
108   */
109   public SquareGrid(final double r, final int n, final int k)
110   {
111      super(String.format("Square Grid(%.2f,%d,%d)", r, n, k));
112
113      if (n < 0)
114         throw new IllegalArgumentException("n must be greater than or equal to 0");
115      if (k < 0)
116         throw new IllegalArgumentException("k must be greater than or equal to 0");
117      if (r <= 0)
118         throw new IllegalArgumentException("r must be greater than 0");
119
120      this.r = r;
121      this.n = n;
122      this.k = k;
123
124      // Create the square's geometry.
125
126      final double xStep = (2 * r) / (1 + k),
127                   yStep = (2 * r) / (1 + n);
128
129      // An array of vertices to be used to create the line segments.
130      final Vertex[][] v = new Vertex[n+2][k+2];
131
132      // Create all the vertices.
133      for (int i = 0; i <= n + 1; ++i)
134      {
135         for (int j = 0; j <= k + 1; ++j)
136         {
137            // from top-to-bottom and left-to-right
138            v[i][j] = new Vertex(r - j * xStep, -r + i * yStep, 0);
139         }
140      }
141
142      // Add all of the vertices to this model.
143      for (int i = 0; i < n + 2; ++i)
144      {
145         for (int j = 0; j < k + 2; ++j)
146         {
147            addVertex( v[i][j] );
148         }
149      }
150
151      // Create the line segments parallel to the x-axis.
152      for (int i = 0; i < n + 2; ++i)
153      {
154         for (int j = 0; j < k + 1; ++j)
155         {
156            addPrimitive(new LineSegment( (i*(k+2)) + j,        // v[i][j  ]
157                                          (i*(k+2)) + (j+1) )); // v[i][j+1]
158         }
159      }
160
161      // Create the line segments parallel to the y-axis.
162      for (int j = 0; j < k + 2; ++j)
163      {
164         for (int i = 0; i < n + 1; ++i)
165         {
166            addPrimitive(new LineSegment( (i*(k+2)) + j,    // v[i  ][j]
167                                      ((i+1)*(k+2)) + j )); // v[i+1][j]
168         }
169      }
170
171   }
172
173
174
175   // Implement the MeshMaker interface (three methods).
176   @Override public int getHorzCount() {return n;}
177
178   @Override public int getVertCount() {return k;}
179
180   @Override
181   public SquareGrid remake(final int n, final int k)
182   {
183      return new SquareGrid(this.r, n, k);
184   }
185}//SquareGrid