Basic math for graphics programming

·

8 min read

Recently I've been interested in graphics, GPU computing, and everything that falls between or exists adjacent to these fields. I decided to check out the Introduction to Computer Graphics course by Cem Yuksel at the university of Utah.

--> You can watch the lecture here

Overview

The wave of nostalgia immediately hit me, and I was reminded of exciting bygone days of high school. In general the topics covered are quite basic, but I have to admit, it's been a hot minute since I graduated high school and my math is rusty to say the least. Turns out that most web development jobs do not require linear algebra. The lecture briefly covers Vectors and matrices, and naturally, that gives us our topics for this post.

Vectors

Let's start off with the basics. "What is a vector?" A natural question indeed! It can be thought of as a construct that has both a direction, and a size. A vector is visually represented by an arrow in some coordinate space.

These "arrows in coordinate spaces" does not only exist in two dimensions. We can for example have 1D vectors: [x], 2D vectors [x, y], and 3D vectors [x, y, z]. There is no limit, as vectors can be everything from 1D to nD.

In graphics, we will mostly be exposed to 1D, 2D, 3D and 4D vectors. Anything above that will generally only occur in special cases.

Typically we will want to use column-vectors instead of row-vectors. If we want to save vertical space we can use the transpose of the column vector:

$$\begin{align} \begin{bmatrix} x \\ y \\ z \end{bmatrix} =\begin{bmatrix} x, y, z \end{bmatrix}^{T} \end{align}$$

You can read a vector in two ways: As a position, and as a direction. However, it is very important to remember that a vector in and of itself is meaningless. You can only understand a vector given its' surrounding context. That is, the coordinate system (also called coordinate frame). You generally need to know the origin to understand how many units the vector moves across each axis.

If you have two vectors that exist in separate coordinate frames, one of them has to be translated to the others' coordinate frame!

Notation

In math, vectors are generally denoted as:

$$\begin{align} \overrightarrow{a} &= \begin{bmatrix} x \\ y \\ z \end{bmatrix} \end{align}$$

But in graphics vectors are usually denoted by bold letters such as:

$$\begin{align} \boldsymbol{a} &= \begin{bmatrix} x \\ y \\ z \end{bmatrix} \end{align}$$

Also, the value for each axis is usually denoted as a subscript of the vector like this:

$$\begin{align} \boldsymbol{a} &= \begin{bmatrix} a_x \\ a_y \\ a_z \end{bmatrix} \end{align}$$

The length of a 3D vector is defined as:

$$\begin{align} \boldsymbol{a} &= \sqrt{a_{x}^2+a_y^2+a_z^2} \end{align}$$

This can be done for vectors of any dimension. In general the length of the vector is the square root of the sum of each individual part squared. Whew! That's a mouthful. But its really not that bad, you just square the x-coordinate, the y-coordinate etc. Then you add them all together and take the square root! Easy peasy :)

The least important notion (but not notation per se) is that of the unit vector. This is simply a vector that moves one single unit along its' direction. It looks a little like this:

$$\begin{align} |\boldsymbol{a}| &= 1 =\begin{bmatrix} 1 \\ 1 \\ 1 \end{bmatrix} \end{align}$$

Operations

In the context of super basic graphics math, we are mostly concerned with the Dot product and the cross product. But there are some other operations that we will look at before we get into it.

First, what is a negative vector? Why it is a vector that goes in the exact opposite direction! The length is the same, but the direction is different. Simple right? Not so fast! A common error is to keep the vector in the same spot, just drawing the arrow head in the opposite direction like so:

When in fact, a direction change actually means "direction from the vectors' origin". So a negative version of the above vector would be like this instead:

Additions and subtractions

Addition and subtraction is really easy, you just pair the x-coordinates of the vectors you're operating on with each other, then the same for the y-coordinates and the z-coordinates etc. It's more obvious with math:

$$\begin{align} \boldsymbol{a}+\boldsymbol{b} &= \begin{bmatrix} a_x+b_x \\ a_y+b_y \\ a_z+b_z \end{bmatrix} & \boldsymbol{a}-\boldsymbol{b} &= \begin{bmatrix} a_x-b_x \\ a_y-b_y \\ a_z-b_z \end{bmatrix} \end{align}$$

Dot Product

The dot product is an operation between vectors that outputs a scalar value. That is, a number. It is defined as follows:

$$\boldsymbol{a} \cdot \boldsymbol{b} = a_xb_x+a_yb_y+\dotso+a_nb_n \rightarrow \text{Scalar value}$$

Taking the dot product of a vector with itself is equal to squaring its' length.

You could think of the dot product as getting some scalar value that symbolizes how closely the directions of two vectors align. Let's formulate it a little bit more complicated. By taking the dot product of a and b we are calculating the projection of a on b*.*

What this essentially means is that we want to know "how much does vector a point in the same direction as b?", or formulated differently: "if we draw a on top of b, how far along b does a reach?".

Borrowing an image from the lecture video, what we are looking at is "what is the size of d?". If vector b is a unit vector, we get the following equation

$$|\boldsymbol{b}|=1 \implies d=a \cdot b$$

If vector b is not a unit vector, we simply need to correct it by dividing the dot product with the length of vector b

$$|\boldsymbol{b}|\neq1 \implies d=(\boldsymbol{a} \cdot \boldsymbol{b})\: / \:| \boldsymbol{b}|$$

Projecting b onto a is the same thing just reverted.

Another interesting property to keep in mind is the relationship with the dot product and the angle between the two vectors. It is defined as:

$$\boldsymbol{a} \cdot \boldsymbol{b}=|\boldsymbol{a}||\boldsymbol{b}|\: cos\:\theta$$

Note that with unit vectors we get an equality between the dot product and the angle theta. If the dot product is zero, this implies that the vectors are perpendicular (or orthogonal) to each other. It is worth noting that there is an edge case here involving zero-vectors. But in the general case you can assume a dot product of zero means orthogonal vectors.

Some final notes on dot product is that it is both commutative and associative.

Cross Product

$$\boldsymbol{a} \times \boldsymbol{b} = |a||b|\sin\theta n$$

The cross product produces a third vector that is orthogonal on BOTH the vectors. Now consider the implication of this in a 2D environment. If there is a third vector that has to be orthogonal on two unique vectors that exist in a two-dimensional space. Where does the third vector go? That's right, it is in the third dimension. But that should be kind of impossible in a two dimensional environment, so the gist of it is that in 2D you can think of the scalar product as the area formed by the two vectors. If the two vectors are pointing in the same direction this means that the area will be 0.

Some useful equations:

$$\boldsymbol{a} \times \boldsymbol{b} = -(\boldsymbol{a} \times \boldsymbol{b}) $$

$$(k \boldsymbol{a}) \times \boldsymbol{b} = k(\boldsymbol{a} \times \boldsymbol{b}) $$

$$\boldsymbol{a} \times (\boldsymbol{b+c}) = \boldsymbol{a} \times \boldsymbol{b}+ \boldsymbol{a} \times \boldsymbol{c}$$

Matrices

They are denoted with a capital bold letter, for example A, and look a little something like this:

$$\boldsymbol{A}=\begin{bmatrix} a_{00} & a_{01} \\ a_{10} & a_{11} \end{bmatrix}$$

They can be of dimensions n X m, but in general we will mostly see 2D, 3D, and 4D matrices in graphics. The 4D matrices are commonly used for transformations.

A very common operation is multiplying a matrix with a vector. That looks a little something like this:

$$\boldsymbol{Ab}=\begin{bmatrix} a_{00} & a_{01} \\ a_{10} & a_{11} \end{bmatrix}\begin{bmatrix} b_x \\ by \end{bmatrix}=\begin{bmatrix} a_{00}b_x & a_{01}b_y \\ a_{10}b_x & a_{11}b_y \end{bmatrix}$$

Finally, it is worth noting that with matrix multiplication the order does matter and the results will differ depending on whether you write AB versus BA

Concluding

Refreshing the good old math-knowledge is always a fun way to exercise the brain. From what I understand, these are basically just the bare-minimum knowledge required to learn graphics programming. So we still have a long way to go. Nevertheless, I think do enjoy it and will probably write another post whenever I get around to learning more.

FAQ by GPT

What are vectors and matrices, and why are they important in computer graphics?Vectors are mathematical entities that represent both direction and magnitude in a space, crucial for defining positions, directions, and transformations in computer graphics. Matrices, on the other hand, are arrays of numbers used for various transformations such as scaling, rotation, and translation of objects in graphics environments. Both vectors and matrices serve as fundamental building blocks in creating visual representations and manipulating objects in computer-generated imagery.

How do vectors and matrices relate to each other, and what are some common operations involving them in computer graphics?
Vectors and matrices often go hand in hand in computer graphics. Matrices can be used to transform vectors, allowing for complex manipulations of positions, orientations, and scales of objects in a scene. Common operations involving vectors and matrices include addition, subtraction, dot product, cross product, and matrix multiplication. These operations enable tasks like calculating distances, finding angles between vectors, determining reflections, and performing various transformations necessary for rendering realistic images and animations in graphics applications.