Geometric Modeling Lab

In which you generate two models using algorithms.

This lab is an exploration of 2D parametric surfaces, which are 3D shapes that can be expressed as functions of two variables. Earth is a parametric surface. Any point on its surface can be described using two variables: a latitude-longitude pair.

You will create two surfaces in this lab: a grid and a sphere. Both shapes will build on the notion of latitude and longitude. Remind yourself of the answers to these questions:

When you've successfully remembered, you're ready to start modeling.

Grid

Consider this 8x4 grid, whose latitude and and longitude indices are labeled:

Follow the steps below to generate a grid of arbitrary dimensions.

In main.js of the grid application, write a function generateGrid that accepts two parameters: the number of lines of latitude and the number of lines of longitude. Have it implement this pseudocode:
for each longitude index
  for each latitude index
    assign indices to x and y
    add vertex position to list of positions

construct vertex attributes
Adapt your initialize function to call this function.

When your render your scene as points, the vertices should appear in a grid formation. However, most vertices are probably offscreen. You need to scale and translate their coordinates so they fit in \(\begin{bmatrix}-1&1\end{bmatrix}\). You don't need matrices to do that.

Add width and height parameters to your function.
Instead of assigning the longitude directly, turn the longitude index into a proportion of the number of lines of longitude. Treat the latitude index similarly.
Apply the proportions to the grid's width and height.
Subtract off half the dimensions to center the grid.
Experiment with different parameter values to change the density and size of the grid.

To fill in the pixels between these intersections, you need to render triangles instead of points. Given that a single vertex is shared by as many as six triangles, as you can see in the figure above, indexed geometry is very helpful here. You need a way to figure out each vertex's index.

Given the vertex generation algorithm above, what is the index of the vertex whose ilatitude is 0 and ilongitude is 0? That's vertex 0. How about the one whose ilatitude is 1 and ilongitude is 0? That's vertex 1. How about the one whose ilatitude is 0 and whose ilongitude is 1? That's vertex 4.

Here's the complete list of indices for the example grid:

You need a general formula for computing the index. A vertex's ilongitude value tells you how many lines of longitude precede it. Each of these lines has nlatitudes vertices in it. So, you can multiply these together to get the number of indices in the rectangular block left of the vertex. Then you need to count the vertices south of the current latitude. That leads to this formula for turning a 2D latitude/longitude pair into a 1D index:

index = ilongitude * nlatitudes + ilatitude

With this formula, you are ready to generate the index list.

Iterate through the latitudes and longitudes again.
Each time you visit a vertex, form the two triangles in its grid cell. One triangle connects the bottom-left, bottom-right, and top-left vertices. The other triangle connects the bottom-right, top-right, and top-left vertices. Watch out for out-of-bounds errors. You won't get an exception in JavaScript. Just disappointment.
Switch to indexed drawing.

The grid should now render solid. However, it's hard to tell it's a grid. You could have achieved the same effect with just four vertices.

Add colors to your vertices in some way.
Show your instructor your working renderer to receive credit.

Sphere

Your second challenge is to render a sphere. The sphere is actually a cousin to the grid. It is a grid that wraps around to form a ball. Follow these steps to generate your sphere:

On paper, draw a semi-circle that forms the right side of a circle, starting at the south pole and ending at the north. Label the south pole as -90 degrees. What is that in radians? Label the north pole as 90 degrees. What is that in radians?
Draw several points along the semi-circle. The points represent a set of seed points which you will rotate around the y-axis to create vertices all around the globe.
In main.js of the sphere application, write a function named generateSphere. Have it accept parameters for the numbers of lines of latitude, the number of lines of longitude, and the radius.
Implement the following pseudocode to generate the seed positions along the right semi-circle:
make empty seeds array
for each latitude index
  compute latitude proportion
  compute radians by applying proportion to radians range
  convert radians and radius to Cartesian coordinates
  push seed position as Vector4
Temporarily render the seed points. To convert them from an array of Vector4 to a flat array, use flatMap:
seeds.flatMap(seed => [seed.x, seed.y, seed.z])
The next task is to rotate the line of seed points all around the sphere to form the lines of longitude. Implement this pseudocode to produce the full positions array:
for each longitude index
  compute longitude proportion
  compute degrees by applying longitude proportion
  generate a rotation matrix around y-axis
  for each latitude index
    rotate seed position by matrix
    push rotated position into positions list
Stitch the vertices into triangles just like you did with the grid. All 2D parametric shapes have more or less the same topological structure. The winding order may need to be adjusted.
Draw the sphere as indexed geometry.
Show your instructor your working renderer to receive credit.