# Triangles Lab

In which you will apply vertex attributes, shader programs, and a VAO in order to fill your framebuffers with the dotted outlines of two shapes that can be described algorithmically.

## Frankenshape

Your first challenge is to construct a random polygon shape from physical construction tools and then digitize it. Complete the following steps to render a frankenshape:

Create and clone your group's lab directory. In the frankenshape project, run npm install.
Start up a web server and verify that you see two dots.
Stitch together at least 5 triangles out of Zometool to form a planar polygon.
Assign coordinates in [-1, 1] to each vertex. The coordinates should reasonably approximate the physical shape.
Render the shape using indexed geometry. Give each vertex a unique color that is interpolated across the frankenshape.
Make the shape scale in and out over time using a uniform whose value changes smoothly and repetitively. Do you know any mathematical functions that are smooth and repetitive? Animate the application state using a helper function that is scheduled by requestAnimationFrame, like this:
function animateFrame() {
// TODO:
// - use performance.now() to get milliseconds elapsed
// - calculate a smooth, periodic scale factor using the time
// - redraw the scene using the new scale factor
requestAnimationFrame(animateFrame);
}

## Rotating Tetrahedron

Your second challenge is to render a tetrahedron that rotates with the mouse. Complete these steps:

In the tetrahedon project, run npm install.
Start up a web server and verify that you see two dots.
Use the blue Zometool struts to form a cube.
Pick two nodes on the same face. Run a green strut between them.
Run a green strut running a 90-degree turn through the face on the opposite side of the cube.
Connect the endpoints of the two struts to each other using four more green struts.
The green struts form a tetrahedron, which is the shape with the fewest faces in 3D.
Render the tetrahedron using separated triangles, not indexed geometry. Give each face its own color.
Animate the tetrahedron so that it rotates about the y-axis as the mouse moves horizontally across the canvas. Rotating about the y-axis is a lot like rotating about the z-axis. The difference is that you use the x- and z-coordinates instead of the x- and y-coordinates.
Likely you'll encounter some strange layering of the faces as the tetrahedron spins. That's because triangles drawn later will overwrite triangles drawn earlier. The fix is to enable depth testing. Put this line in your initialize function:
gl.enable(gl.DEPTH_TEST);