3D Graphics


Date: Febuary 26, 2024

In the early years of computing, graphics had been stuck in 2 dimensions. In 1960, Ivan Sutherland came out with the first graphic design interface with 3D graphics.

An early use of Bezier curves to draw a car body
Ivan Sutherland using sketchpad with the light pen, 1962.

To understand how we can go from a list of points to 3D shapes, it is useful to simplify the problem to understand it. Two key concepts to understand are representation of 3D points and how trigonomic functions affect points. Sounds complicated, but don't worry; we'll go through it step by step. One of the first key concepts of trigonometry is that cos(a) is the x component of a circle, sin(a) is the y component, and a is the angle (usually in radians).

These are useful for rotating a point that starts at (1,0), but any other point won't work. Before things get kinda complicated, let's define x and y. We can define x and y as:

$$x = r * cos(a)$$ $$y = r * sin(a)$$
r is the arbitrary length of the vector and a is the arbitrary angle of the vector. These are the trig identities we mentioned above, just with a length. These values are arbitrary because we will substitute them out for the actual points we want to use. We will create two new points that represent our new, transformed points. These will be:

$$x' = r * cos(a+b)$$ $$y' = r * sin(a+b)$$
Note that the new point is still the same distance away from origin. We can then use these easily look-up-able formulas to finish the process:

$$cos(a+b) = cos(a) * cos(b) - sin(a) * sin(b)$$ $$sin(a+b) = sin(a) * cos(b) + cos(a) * sin(b)$$
We then substitute this formula into the new equations we created for the new point:

$$x' = r * (cos(a) * cos(b) - sin(a) * sin(b))$$ $$y' = r * (sin(a) * cos(b) + cos(a) * sin(b))$$
We then distribute the r to all of the terms in the equation:

$$x' = r * cos(a) * cos(b) - r * sin(a) * sin(b)$$ $$y' = r * sin(a) * cos(b) + r * cos(a) * sin(b)$$
You may recognize some of these terms as what we defined as the original x and y terms:

$$x' = r * cos(a) * cos(b) - r * sin(a) * sin(b)$$ $$y' = r * sin(a) * cos(b) + r * cos(a) * sin(b)$$ $$\Downarrow$$ $$x' = x * cos(b) - y * sin(b)$$ $$y' = y * cos(b) + x * sin(b)$$
You may notice that these new equations now only take a x or y value and an angle in which to rotate them by, which is exactly what we want. The last thing we can do is rearrange the last equation using the commutative property of addition:

(commutative property of addition: a + b = b + a)

$$x' = x * cos(b) - y * sin(b)$$ $$y' = x * sin(b) + y * cos(b)$$
This little change may seem trivial, but it allows us to compact this into matrix form, which looks like:

$$\begin{bmatrix} x' \\ y' \end{bmatrix} = \begin{bmatrix} cos(b) & -sin(b) \\ sin(b) & cos(b) \end{bmatrix} \begin{bmatrix} x \\ y \end{bmatrix}$$

Whew, that was a lot of math! Now, we have the simpler stuff: representing points in 3d. Most people are familiar with the x y z coordinate system used for 3d systems. If you're not, don't worry, it's simple: x is how far side to side (width), y is how much up or down (height), and z is depth or how far forward or back. We decide a point to be the origin of the coordinate system and define it as (0,0,0). Left is negative, down is negative, and towards the viewer is negative (don't worry, the z part will make more sense later). More importantly, for the math, we represent points as matrices with only one term in each row. After multiplying the point by the matrix, each row corresponds to either the x, y, or z component in that order. This is why, in the simple matrix above, the equation for X' was the sum of the first term multiplied by x and the second term multiplied by y. Go back to the matrix above and make sure you understand how we get the actual equations we derived, or none of this other part will make sense.

Strap on your math boots cause things are going to get a little conceptual. As we can see in the image below, rotating along an axis actually involves not moving the point along that axis at all:

x, y, and z axes
x, y, and z axes

We can also use this test matrix to look at how values are moved around when multiplied:

$$\begin{bmatrix} a & b & c\\ d & e & f\\ g & h & i\\ \end{bmatrix} \begin{bmatrix} x\\ y\\ z\\ \end{bmatrix}$$ $$\Downarrow$$ $$\begin{bmatrix} ax+by+cz\\ dx+ey+fz\\ gx+hy+iz\\ \end{bmatrix}$$ This shows us that each variable gets multiplied in a column, so reason would stand that we don't want the column with the axis variable or the output column to have anything in it. This is because the position along the axis shouldn't matter, so we don't want that variable in the calculation, and we don't want the position to change, so the output row should not change

x, y, and z axes
Matrix describing where transformations take place.

For the x axis, we treat the y value as the x, and the z as the y. Once we make these connections, it is easy to see how the 2d rotation matrix fits in; it simply slots in as the second row is the x (actually the y) and the third row is the y (actually the z). We also want to slot a 1 in where the empty row and column meet so the matrix will pass the x value on unchanged. All together, it looks like this:

$$R_{x}(\theta)= \begin{bmatrix} 1 & 0 & 0\\ 0 & cos(\theta) & -sin(\theta)\\ 0 & sin(\theta) & cos(\theta)\\ \end{bmatrix}$$ A similar process can be done for the y axis, but we have to do some rearranging. The second row and column will be empty for this axis, so the four corners of the matrix will be the "Math Zone". It is also most common for the z value to be x and the x value to be y. This means we have to put the equation for x in the third row to output to z, and we also need to flip the terms horizontally so the z value is treated like x:

$$\begin{bmatrix} x'\\ y'\\ z'\\ \end{bmatrix} = \begin{bmatrix} x & x & x\\ y & y & y\\ z & z & z\\ \end{bmatrix}$$ $$\Downarrow$$ $$\begin{bmatrix} y'\\ 0\\ x'\\ \end{bmatrix} = \begin{bmatrix} y & 0 & x\\ 0 & 1 & 0\\ y & 0 & x\\ \end{bmatrix}$$ Now, we just line up the terms we already know and we have the rotation matrix for the y axis. The z axis is the easiest of them all because it is simply the original 2d rotation matrix. We simply disregard the z axis. All together, the three rotation matrices are:

$$R_{x}(\theta)= \begin{bmatrix} 1 & 0 & 0\\ 0 & cos(\theta) & -sin(\theta)\\ 0 & sin(\theta) & cos(\theta)\\ \end{bmatrix}$$ $$R_{y}(\theta)= \begin{bmatrix} cos(\theta) & 0 & sin(\theta)\\ 0 & 1 & 0\\ -sin(\theta) & 0 & cos(\theta)\\ \end{bmatrix}$$ $$R_{z}(\theta)= \begin{bmatrix} cos(\theta) & -sin(\theta) & 0\\ sin(\theta) & cos(\theta) & 0\\ 0 & 0 & 1\\ \end{bmatrix}$$ Wow, that was a lot of math! Don't worry, that was as hard as it gets, so if you survived, we can now go all the way to the end and apply these concepts. Stay tuned for the next part where we finish this concept.