Table of contents

Projects


Disclaimer

This is a work in progress and contains errors that needs to be ironed out. Much of the information should still be useful though.


What do I need to know before reading this book?

Python

Some basic programming in Python.

Optional: Blenders Python API

How to use this book

I intended for the reader to learn by playing with the source code examples to get the intuition or "feel" for how the math works and what it can be used for.

Math Tools

Math Tools is a math library for Python made for learning and teaching mathematics through useful practical end applications as early on in the learning process as possible. This text assumes the reader only has basic knowledge of Python programming and arithmetic.

Math Tools on Github

Installation

Requirements

Download zip or clone the repo on the Github page.

$ git clone https://github.com/martin-petersson/MathTools.git

Instructions and command reference


Numbers

Natural numbers or integers.

$$ \mathbb{N} $$

Real numbers.

$$ \mathbb{R} $$

Vectors

Vectors are one of the most fundamental mathematical concepts throughout physics and engineering, a vector is an example of a mathematical object. They can be thought of as a points in space, or as having direction and magnitude(length). They are defined by a list of real valued numbers, making up coordinates in usually a cartesian coordinate system.

The easiest way to understand vectors first is to think of them as as points in space before confusing someone with magnitude and direction.

A vector can have any number of dimensions (called components). In the figure below we define a vector with three dimensions but they can be only two or any number of dimensions.

$$ \begin{equation} \vec{v} = (x, y, z) \end{equation} $$

Let's put a point somewhere in space by defining the following vector.

$$ \vec{v} = (3.0, 4.0, 1.0) $$

Represented visually our vector \( \vec{v} \) in a three dimensional Cartesian coordinate system looks like this including lines representating the distance along each axis in the coordinate system:

A cartesian coordinate system showcasing the vector \( \vec{v} \).


Using Math Tools we define a vector using the following syntax:

import mathtools as mt

v = mt.vector([3.0, 4.0, 1.0])

In a cartesian coordinate system the cardinal axes are perpendicular to each other. There are many other coordinate systems like spherical, cylindrical etc. which will be covered later in this book.

Using the right hand rule we define our cardinal directions this way, Positive Z is often used as the up direction but it's a matter of convention, sometimes Y is used as up instead. I like to use positive Z as up because that's what Blender uses.

$$ \mathbb{R}^3 $$

$$ \vec{p} = (0.0, 0.0, 0.0) $$

The vector \( \vec{p} \) located at the origin of our coordinate system.

$$ \vec{p} = (-4.0, -1.0, 5.0) $$

A vector located in the negative direction from the origin but on the positive Z axis.

The position of a vector is relative to the origin.

$$ \vec{v} = (6.0, 4.0) $$

$$ \vec{b} = (-4.0, 3.0) $$

Now, not only can a vector be thought of as a point in space, but also as having magnitude (or length) and direction from an origin. In physics quantities such as displacement and velocity are vector quantities.

Frame of reference. A vector can sit on top of another and be displaced by another previous vector quantity, the point where it ultimately ends up. Which we'll look at in the next section.


Adding vectors

If you think of vectors as points and you add each of those points with a vector that has a small magnitude, pointing in a direction from the origin of the Cartesian coordinate system. And then add the same vector to the set of vectors we think of as points in space. Then for every iteration they will be moving in the direction of the vector they're added with, if you then change the direction of the vector and keep adding it over and over to the set of points it will move in the new direction. This is called a translation.

Vectors are used to represent vertices in polygonal 3d graphics. Three vertices can then together form a visible surface called a polygon. A set of polygons together makes up this object in object space, which can be moved around in world space through translation.


Let's add two vectors.

$$ \vec{v} = (6.0, 4.0) $$

$$ \vec{b} = (-4.0, 3.0) $$

Since addition is commutative the order we add the vectors in won't matter as shown in the above figure.

$$\vec{p} = \vec{v} + \vec{b}$$

The result of adding \( \vec{v} \) and \( \vec{b} \) together is the new vector \( \vec{p} \).

$$ \vec{p} = (2.0, 7.0) $$


Syntax for vector addition using Math Tools is as follows:

v = mt.Vector([6, 4])
b = mt.Vector([-4, 3])

p = v + b


Subtracting vectors

Unlike with addition, vector subtraction is non-commutative so order matters to where the resulting vector ends up.

$$\vec{p} = \vec{v} - \vec{b}$$

And the Math Tools syntax:

v = mt.Vector([6, 4])
b = mt.Vector([-4, 3])

p = v - b

Result of subtracting the previously defined vectors:

$$ \vec{p} = (10.0, 1.0) $$

$$ \vec{v} = \vec{b} + \vec{p} $$

p = v - b
v = b + p 

And if we change the order.

$$\vec{p} = \vec{b} - \vec{v}$$

We get the following result.

$$ \vec{p} = (-10.0, -1.0) $$

If we add \( \vec{v} \) with our new vector \( \vec{p} \) we end up at \( \vec{b} \).

$$ \vec{b} = \vec{v} + \vec{p} $$


p = b - v
b = v + p 


Scaling vectors

A scalar is a real valued number

$$ -3.02, 0.0, 2.5 \ \dots n $$

We call real numbered values scalars in the context of vector algebra because they're used to "scale" the length of a vector by multiplying the two so its length or magnitude changes. The fact that things are called different things depending on the context was something that confused me a lot when I learned all this myself. But as I've stated in the preface just relax because you will get used to it as long as you keep trying to learn.

$$ s = 2 $$

$$ \vec{b} = \vec{v}s $$

Scaling \( \vec{v} \) by \( s \) we get the resulting vector \( \vec{b} \) that is twice the length.

$$ \vec{p} = \vec{v}s $$
s = 2
b = v * s

You can invert a vector by multiplying by -1 unless it's not immediately obvious.


Dividing vectors

$$ \vec{p} = \frac{\vec{v}}{d} $$
d = 0.8
print(v / d) # print result of vector division


Summation

Used for a sequence of sums

Index \( i \) denoted using subscript. \( n \) denotes the number of times to repeat the summation to the right of the sum operator (Greek letter sigma).

$$ 8 = 2 + 2 + 2 + 2 $$

$$ 8 = \sum_{i=1}^{n} 2 $$

Summation is similar to a for loop.

n = 4
a = 0

for i in range(n):
    a = sum(2)


Center of mass for a set of points

$$ \vec{c} = \frac{1}{n}\sum_{i=1}^{n} \vec{p}_i $$

Let \( \vec{p}_i \) be the set of point vectors that make up a polygon mesh. the indices \( i \) being every individual point vector in the set not the components of a vector. Sum the set of \( n \) vectors. Then divide the vector sum by \( n \) and the result you get is a point vector \( \vec{c} \) in the geometric center of your set of vectors.

import mathtools as mt

pointvecs = # put your vectors here.
pointmass = 0

for i in range(n):
    pointmass += pointvecs[i] # make the code work with sum()

c = pointmass / n


Interpolate between two points in space

$$\vec{p} = \vec{b} - \vec{a} $$

$$ \vec{p} = (\vec{b} - \vec{a}) + \vec{a} $$

$$ \vec{p} = (\vec{b} - \vec{a}) t + \vec{a} $$

$$ \{ t \in \mathbb{R} \; \vert \; 0 \leq t \leq 1 \} $$

\( \text{t} \) is the set of real numbers in the interval between 0 to 1.

a = mt.Vector([-10, 10])
b = mt.Vector([15, 0])

a.lerp(b, 0.5) # interpolate half way between a and b


Bezier curves

By creating additional linear interpolations between interpolation vectors(the purple point vector in the previous example) we can trace out a smooth curve motion.

A second degree curve.

A third degree curve.


Bezier surfaces

Bezier curves can be extended to surfaces.

$$ \vec{P}(u, v) = \sum_{i=0}^{n} \sum_{j=0}^{m} \vec{B}_{m,i}(u) \vec{B}_{n,j}(v)\vec{P}_{ij} $$


Vector length

Or magnitude.

$$ \| \vec{p} \| = \sqrt{p_x^2 + p_y^2} $$

vec = mt.Vector([1,0,1])
magnitude = vec.len

print('length of vec:', magnitude)

A more general way of writing it would be to use the summation symbol \( \Sigma \) (Greek letter Sigma) for vectors that has an arbitrary number or dimensions or components.

$$ \| \vec{p} \| = \sqrt{\sum_{i=1}^{n} \vec{p}_i^2} $$

Something you might've not been told in school is that the pythagorean theorem can be defined as a vector (adjacent, opposite = vec(x, y)) and it works in any number of dimensions not only in two! Like the vector in \( \mathbb{R}^3 \) shown here:

$$ \| \vec{p} \| = \sqrt{p_x^2 + p_y^2 + p_z^2} $$

$$ c^2 = a^2 + b^2 $$

If a right triangle where the adjacent and the opposite is \( 1 \) then the hypotenuse is equal to \( \sqrt{2} \).


Euclidean distance

$$ \| \vec{d} \| = \sqrt{\sum_{i=1}^{n} (\vec{p}_i - \vec{v}_i)^2} $$

Why are magnitude of a vector and absolute value using the same notation in MathJax? Or is it?

There's multiple ways to do this, here's one:

vec1 = mt.Vector([1,0,1])
vec1_magnitude = vec1.len

vec2 = mt.Vector([1,-2,0])
vec2_magnitude = vec2.len 

distance = math.abs(vec1 - vec2)
print('distance between vectors: ', distance)

The better and cleaner ways?


Vector normalization (also called unitization)

Unit vector for short.

Returns a vector 1 unit in length. We get it by dividing a vector by it's magnitude.

$$ \hat{u} = \frac{\vec{u}}{\| \vec{u} \|} $$
vec = mt.vector([0,0,2])
print(vec.unit)


Dot products

$$ d = \vec{p} \cdot \vec{v} $$

To calculate the dot product of two vectors we first unitize the vectors. Then we multiply the components of the two vectors together and add, or sum the components into a scalar.

$$ \vec{p} \cdot \vec{v} = \vec{p}_x \vec{v}_x + \vec{p}_y \vec{v}_y + \vec{p}_z \vec{v}_z $$

Using summation the procedure of taking the dot product can be written more generally where \( i \) denotes the indices for the vector components like so:

$$ \vec{p} \cdot \vec{v} = \sum_{n=1}^{n} \vec{p}_i \vec{v}_i $$

If the unit vectors are perpendicular to each other the dot product will be equal to 0 and if the unit vectors are pointing in the same direction they will be equal to 1. The dot product is a projection of a vector onto another.

p = mt.vector([0,0,2])
v = mt.vector([1,1,0])
p.unit
v.unit

dot = p.dot(v)

A property of the dot product is that it's equal to the cosine angle between the two unit vectors.

$$ \vec{p} \cdot \vec{v} = \cos{\theta} $$


Cross products

Also called vector products. Only works in \( \mathbb{R}^3 \)(3d) and \( \mathbb{R}^7 \). They are anticommutative.

$$ \vec{C}_x = \vec{a}_y \vec{b}_z - \vec{a}_z \vec{b}_y $$

$$ \vec{C}_y = \vec{a}_z \vec{b}_x - \vec{a}_x \vec{b}_z $$

$$ \vec{C}_z = \vec{a}_x \vec{b}_y - \vec{a}_y \vec{b}_x $$

Denoted with a cross.

$$ \vec{C} = \vec{a} \times \vec{b} $$
vec1 = mt.vector([1,0,0])
vec2 = mt.vector([0,1,0])

vec1.cross(vec2)

Some applications of the cross product in physics is torque, which is the cross product of lever length and force, while angular momentum is the cross product of distance and linear momentum.

In computer graphics cross products are used to calculate surface normals of polygon surfaces. The order of vertices matter (vertices are 3d points in space defining the corners of polygons).


Trigonometric functions

In school we learn that a full revolution around the circumference of a circle is 360 degrees. This isn't an inherent mathematical property of the circle but is based on the fact that old calendars had 360 days. Instead when measuring angles we use radial angles, or radians for short. The radian angle of a circle is the length of the radius of the circle laid around it's circumference or perimeter. A full revolution around a unit circle(radius 1) is then \( 2 \pi r \).

Matrices

Basis

Basis vectors

$$ \hat{i}, \hat{j}, \hat{k} $$

Linear independence / linear dependence

Cardinality

"In mathematics, the dimension of a vector space V is the cardinality (i.e., the number of vectors) of a basis of V over its base field.[1][2] It is sometimes called Hamel dimension (after Georg Hamel) or algebraic dimension to distinguish it from other types of dimension."

Standard basis.

Orthogonal and Orthonormal basis

Basis is orthogonal if the vectors that form it are perpendicular. Basis is orthonormal if the vectors that form it are perpendicular and they have length 1.

Identity matrix

$$ M = \begin{bmatrix}1 & 0 & 0 & 0\\ 0 & 1 & 0 & 0\\0 & 0 & 1 & 0\\0 & 0 & 0 & 1\end{bmatrix} $$

Can also be written using parentheses depending on what notation the author likes since as stated math notation hasn't been standardized:

$$ M = \begin{pmatrix}1 & 0 & 0 & 0\\ 0 & 1 & 0 & 0\\0 & 0 & 1 & 0\\0 & 0 & 0 & 1\end{pmatrix} $$

Defined as follows with Math Tools:

identity = mt.Matrix([1, 0, 0, 0],
                     [0, 1, 0, 0],
                     [0, 0, 1, 0],
                     [0, 0, 0, 1])


Translation matrix

Using a 3x3 matrix.

$$ \begin{bmatrix}m \\ n \\ p \end{bmatrix} = \begin{bmatrix}a & b & c \\ d & e & f \\ g & h & i\end{bmatrix} + \begin{bmatrix}x \\ y \\ z \end{bmatrix} $$

Translation
\( m = a+x+b+y+c+z \)
\( n = d+x+e+y+f+z \)
\( p = g+x+h+y+i+z \)


Using a 4x4 matrix(homogenous coordinates).

$$ \begin{bmatrix}m \\ n \\ p \\ o \end{bmatrix} = \begin{bmatrix}1 & 0 & 0 & x \\ 0 & 1 & 0 & y \\ 0 & 0 & 1 & z \\ 0 & 0 & 0 & 1\end{bmatrix} \cdot \begin{bmatrix}x \\ y \\ z \\ w \end{bmatrix} $$
v = mt.Vector([1, 1, 1, 1])

x = 3
y = 0
z = 1

M = mt.Matrix([1, 0, 0,  x],
              [0, 1, 0,  y],
              [0, 0, 1,  z],
              [0, 0, -1, 1])

v = M * v


Scaling matrix

Multiplying a vector by a matrix

$$ \begin{bmatrix}m \\ n \\ p \end{bmatrix} = \begin{bmatrix}a & b & c \\ d & e & f \\ g & h & i\end{bmatrix} \cdot \begin{bmatrix}x \\ y \\ z \end{bmatrix} $$

Sometimes dots are used to denote multiplication, but usually it's omitted. Instead a dot is used to denote a dot product. Matrix multiplication can be written without the dot (I think).

Multiplication
\( m=ax+by+cz \)
\( n=dx+ey+fz \)
\( p=gx+hy+iz \)

Rotation matrix

Used in computer graphics to rotate 3d geometry.

$$ \vec{R}_x (\theta) = \begin{bmatrix}1 & 0 & 0 \\ 0 & \cos{\theta} & -\sin{\theta} \\ 0 & \sin{\theta} & \cos{\theta}\end{bmatrix} $$

$$ \vec{R}_y (\theta) = \begin{bmatrix} \cos{\theta} & 0 & \sin{\theta} \\ 0 & 1 & 0 \\ -\sin{\theta} & 0 & \cos{\theta}\end{bmatrix} $$

$$ \vec{R}_z (\theta) = \begin{bmatrix}\cos{\theta} & -\sin{\theta} & 0 \\ \sin{\theta} & \cos{\theta} & 0 \\ 0 & 0 & 1\end{bmatrix} $$


Matrix multiplication

Non-commutative, so order matters. I think the right way is to multiply the matrix by a vector like this

$$ \vec{a} = \text{M} \vec{v} $$
a = M * v


Affine transformations

Shearing. Reflection.

Determinants

If determinant equals zero it means a transformation has squished all vectors to a lower dimension or point (correct?)

Matrix transpose

$$ \begin{bmatrix}a & b & c \\ d & e & f \\ g & h & i\end{bmatrix}^T $$

Row-major order

Column-major order

Triple products

Scalar triple product.

$$ \vec{a} \cdot (\vec{b} \times \vec{c}) $$

Vector triple product.


Hadamard product

https://en.wikipedia.org/wiki/Hadamard_product_(matrices)


Oblique perspective projection

$$ M = \begin{bmatrix}1 & 0 & 0 & 0\\ 0 & 1 & 0 & 0\\0 & 0 & 1 & 0\\0 & 0 & -1 & 1\end{bmatrix} $$
 mt.Matrix([1, 0, 0,  0],
           [0, 1, 0,  0],
           [0, 0, 1,  0],
           [0, 0, -1, 1])


Next page: Path tracer