Posted: June 2nd, 2024
A few years ago, I came across an indie game called Miegakure.
From what I was able to gather from the few promotional videos, it was a relatively simple concept: you witness someone get their purse stolen and you must follow after the thief to retrieve it.
The premise isn't interesting; the technology is.
Miegakure is a puzzle/platformer game that takes place in four spacial dimensions.
You, the player, are able to move around in four dimensions.
Unfortunately, the game still hasn't been released at time of writing, so this series of posts will seek to answer the question:
What if there were four dimensions?
Most of us are familar with Einstein's concept of spacetime and that the universe is a four dimensional object of which time is the fourth dimension. We're not doing that here. For the sake of this series, we will assume the fourth dimension to be a spacial dimension (a being pointed in the correct direction could walk along it just like the three existing ones).
The existance of the fourth dimension is unintuitive, as we (three dimensional beings) are unable to properly visualize it. For that reason, we will attempt to reason about it from the perspective of a two dimensional researcher trying to figure out three dimensions. I do not take credit for this idea; Edwin Abbott's Flatland presented it way back in 1884.
In Geometry, all positions are described relative to a center point called origin. We then describe a set of rulers each perpendicular to each other (at 90° to all its peers). Because they are all perpendicular, a point's position along one of the rulers is entirely independant from the others. We can then describe a position in space by recording the distance along each of the rulers in an ordered sequence. If that doesn't make sense, that's ok. I'll give you a few examples:
When using graph paper in school, if a teacher asked you to plot the points (1, 2) and (3, 4) you would first define a central point (likely in the middle or bottom left of the page). That central point is the origin. You would then count one square to the right and two squares up to plot the first point. Then, you would go back to the origin and count three squares to the right and four squares up to plot the second point. In that case, you defined origin and used the horizontal line and vertical line as your rulers. You counted along your two 'rulers' to place the point.
Three dimensions is similar, except you have left/right, up/down, and in/out. If you (like me) played Minecraft
as a kid, you probably have a good understanding of this. You diamonds are under y = 15
and that
you can tell someone your position by relaying three numbers in the debug screen--the first number increases and
decreases when traveling one way, the last number increases and decreases when traveling perpendicular to that, and
the middle number increases when going up and decreases when going down. Those numbers are your distances along three
'rulers' placed at the center of the world (at 0,0,0), and they tell you the number of blocks along each ruler that
you are. There are diamonds starting at 15 ruler ticks from the bottom of the world (going downward).
Geometry can even be applied to one dimension. Zero is the 'origin' of the number line. There is a ruler pointed in one direction, and a number is the distance along that ruler. If you go in the opposite direction of the ruler, the 'position' is negative. 53 is 53 ruler ticks in the direction of the ruler. -5 is 5 ruler ticks in the opposite direction of the ruler.
Now, let's apply this to four dimensions. We'll say our first ruler is pointed to the right. Our second ruler is pointed upward (perpendicular to the first). Our third ruler is pointed away from us (perpendicular to the first two). Our fourth ruler gets placed by a friend who is able to place it in such a way that it is perpendicular to the first three rulers.
This probably doesn't make sense, but our three dimensional world also won't make sense to a square on a piece of paper. Just stick with me.
Let's say our dog is in our room, and we want to describe its position to someone. We can do that by measuring the distance along each ruler that we have precariously setup. Something on the floor may be 3 feet to the right, 0 feet up, and -2 feet away (2 feet toward us), and 5 feet along the ruler that only our friend can see.
Now we know where our dog is. But what if we want to know how far it is away from the cat?
You and your friend find the position of the cat using the method above. You then find the position of the dog again because there was apparently a strange noise outside. You write down their positions below.
Cat: 1 foot to the right, 2 feet up, 3 feet away, and 3 feet along your friend's ruler.
Dog: 5 feet to the right, 0 feet up, -6 feet away, and 2 feet along your friend's ruler.
First, let's formalize this.
Instead of writing out the lengths along each direction, we'll define something called a vector. There are several ways of notating a vector. I prefer the way below.
v = <x, y, z, w>
Where x, y, z, w are the lengths along the right, up, away, and your friend's rulers.
Knowing this, let's write out the cat and dog positions using vectors (c is the position of the cat; d is the position of the dog).
c = <1, 2, 3, 3>
d = <5, 0, -6, 2>
You can think of a vector either as a point (such as the location of your pet) or an arrow starting at origin and ending at the location. In the first case, the vector is a position. In the second case, it's more of a direction or displacement.
Side Note: With the introduction of vectors, there are also scalars. Scalars are just normal numbers like 5, 17, 42, etc. They're kinda like one dimensional vectors (and some operations like addition, subtraction, dot product, and magnitude look suspiciously like normal addition, subtraction, multiplication, and absolute value).
Now, for the forseeable future, we will need to be aware of the following operations:
I'll be quick.
Conceptually, you can think of vector addition as taking two arrows (the vectors) and placing the beginning of one at the end of the other.
So a vector pointing 3 feet up plus a vector pointing 2 feet to the right will result in a vector pointing 3 feet up and 2 feet to the right.
^ ^--> ^
| + = | = /
| --> | /
As you would expect, you get the resulting vector by adding each component together. So:
A = <a, b, c, d>
B = <e, f, g, h>
A + B = <a + e, b + f, c + g, d + h>
Vector subtraction is practically identical (but you subtract instead of add).
A = <a, b, c, d>
B = <e, f, g, h>
A - B = <a - e, b - f, c - g, d - h>
Why is that helpful?
Going back to the example with the cat and the dog, say we want to find the position of the cat relative to the dog (the cat's position if the dog was the origin). In that case, because position relative to origin is like adding that vector to origin, the cat's position relative to the dog would be the dog's position plus some vector. Here is a drawing (d is the dog; c is the cat):
d d
| | \ <---- [We want this vector]
| | \
| c ==> | c
| / | /
| / | /
0 0
Now let's do some math.
The dog's position can be expressed as 0 + d
(where 0 is the origin).
Likewise, the cat's position can be expressed as 0 + c
.
So, if we want to express the cat's position relative to the dog, it would be d + v
(where v is just some vector).
Because we want the position of the cat to stay the same relative to origin, it becomes d + v = c
.
Now, we can use some algebra to find that the relative position (v) is v = c - d
.
Using the numbers above, v = <1 - 5, 2 - 0, 3 - (-6), 3 - 2> = <-4, 2, 9, 1>
The cat is 4 feet to the left of, 2 feet above, 9 feet away, and 1 foot along our friend's ruler relative to the dog.
Vector scaling is somewhat self-explanitory.
Say you had a picture of your favorite pet (cat or dog, I won't ask which one).
You put it into an image editor.
You scale it by 2x.
It is now twice the size.
That's vector scaling.
A = <x, y, z, w>
A * s = As = <x*s, y*s, z*s, w*s>
Say you said to me: "Hey Trevor, I have a vector for the position of my dog, what if I wanted it to be twice as far away?"
I would say: "d*2
"
If you said: "Hey Trevor, I have a vector for my cat and I want it to be half the distance."
I would say: "d*0.5
or d*(1/2)
"
For the last two operations, I first tried to outline an intuitive understanding of the operation before telling you the math.
That doesn't really work here.
The math for dot product is pretty simple: Multiply each component together and add them all up:
A = <a, b, c, d>
B = <e, f, g, h>
A * B = (a * e) + (b * f) + (c * g) + (d * h)
It does have a different formula (foreshadowing), but we don't care about it right now (we'll deal with it in shading).
Magnitude is just a fancy name for length. If I ask you for the magnitude of a vector, I'm asking you for the length.
One fun part of vector notation: If I want the magnitude of A
, I write |A|
(aka the absolute value of v).
That makes sense, because absolute value is the distance from 0 (the origin) on the number line.
-42 is 42 numbers away from 0 (just like positive 42).
Question is: How do we find the magnitude of a vector? The answer: Pythagoras.
If you don't know about the Pythagorean theorem, some old (now dead) guy found that for the right triangle:
|\
a | \ c
| \
|______\
b
The side lengths (a, b, c) are related: a2 + b2 = c2
Now, I'm sure my man Pythagoras was fun to have at parties, but that's helpful because if
A = <x, y>
:
/|
/ |
|v| / | y
/ |
/ |
O------
x
x2 + y2 = |A|2 [and... taking the square root of both sides...]
|A| = sqrt(x2 + y2)
Now, extending to three dimensions is pretty simple; you project the vector on the xy plane
and find its magnitude. You then use that projected magnitude as the base of the triangle and
use the z component as the height. You then find the hypotenuse (|A|
). I'm not
even going to attempt a drawing, because I know my limits. If you don't follow, just trust me.
A = <a, b, c>
|A| = sqrt(sqrt(a2 + b2)2 + c2)
= sqrt(a2 + b2 + c2)
Likewise, the same thing can be done in four dimensions. I'm definitely not drawing this.
A = <a, b, c, d>
|A|
= sqrt(sqrt(sqrt(a2 + b2)2 + c2)2 + d2)
= sqrt(a2 + b2 + c2 + d2)
Let's jump back to the above example of our cat and dog laying in the room. If we didn't have our strange four dimensional friend to read the ruler, we would think the cat's and dog's positions would be:
c = <1, 2, 3>
d = <5, 0, -6>
Using our relative vector calculations and the magnitude of that relative vector:
v = c - d
|v| = |c - d| = |<-4, 2, 9>|
= sqrt((-4)2 + 22 + 92) = 10.0498756211
We can also perform this calculation knowing their four dimensional positions:
v = c - d
|v| = |c - d| = |<-4, 2, 9, 1>|
= sqrt((-4)2 + 22 + 92 + 12) = 10.0995049384
We find that the cat and dog are slightly further apart than they would be if they weren't in our four dimensional sci-fi living room. Ignoring the implications of living in a house slightly out of skew with the rest of reality, we at least know that our cat chose to be a bit over half an inch further away from our dog than we originally thought them to be.
Now, before you finish this section, I want to bring something to your attention. I'm going to do some weird math, and I want you to follow it (it's really important for the next post).
|A|
= sqrt(a2 + b2 + c2 + d2)
= sqrt(a*a + b*b + c*c + d*d) [now squint really hard]
= sqrt(A * A)
Because a vector dotted with itself is the same as squaring its components and adding them together (you're just multiplying each one with itself), we can construct an additional definition of vector magnitude which will be helpful for deriving ray-intersection with a hypersphere (I'm getting ahead of myself).
Side Note: You can also make a vector's length 1 by dividing by its magnitude (or scaling by its reciprocal).
Sorry for the long (slightly boring) post. I'm well aware that no-one wants to read an intro to linear algebra in the first weeks of summer, but you'll need the base to do anything more than look at the pretty pictures in the next post. The next one will be more interesting. I promise.
Until next time,
Cheers.
Trevor Martin
^2
with superscripts.