How to prove r = n * 2(l·n) - l in specular reflection?

Vector Algebra Basics

I'm going to start with a quick review of the basics. I'm assuming some knowledge of trigonometry and familiarity with Pythagoras' Theorem. I'm not requiring prior knowledge of vector algebra. Everything on this answer is about euclidean spcaes.


Vectors

First, vectors have length, and direction. You can imagine the vector as an arrow:

The vector a

We can also understand a vector is a series of coordinates, that make up the position that the vector points to when placed at the origin.

How many coordinaste depends on how many dimension the space we are working on has. For example, in 2D, our vector $a$ would have $x_a$ and $y_a$ components; and in 3D, $a$ would have $x_a$, $y_a$ and $z_a$ components.

I need to mention that there is a zero vector. Which has zero length and no direction. So when placed at any position, the zero vector points at the same position. The zero vector has value $0$ on all its components.


Length

Second, if we have a vector $a$ the length of the vector $a$, I'll represent the length of the vector $a$ as $|a|$. Also known as the magnitud of the vector, or the norm of the vector.

If we wanted to compute the length of a vector, we would use Pythagoras' theorem extended to how many dimension we have.

For example, in 2D we would do this:

$|a| = \sqrt{(x_a)^2 + (y_a)^2}$

And in 3D we would do this:

$|a| = \sqrt{(x_a)^2 + (y_a)^2 + (z_a)^2}$

And it will extend in similar fashion to the number of dimensions we need.

I'm not including a proof of Pythagoras' theorem, nor its extension to more dimensions in this answer.


Vector addition

Third, we can add vectors together. I'll explain this with the Triangular Law of addition method. If we have a vector $a$:

The vector a

And a vector $b$:

The vector b

And we place them head to end (one after the other). Combined they span the result of adding the vectors, in this case $c$:

The vector c = the vector a plus the vector b

In other words, if have $a$ placed at the origin, and I place $b$ where $a$ points to; the position where $b$ points to, is the position where their sum points to when placed at the origin.

To compute the addition we add the components of the vectors.

For example, in 2D:

$x_c = x_a + x_b$

$y_c = y_a + y_b$

And in 3D:

$x_c = x_a + x_b$

$y_c = y_a + y_b$

$z_c = z_a + z_b$

And it will extend in similar fashion to the number of dimensions we need.

Notice that if we have a vector $a$ and we add to it the zero vector (which has $0$ in all its components) we get the same vector $a$.


Scalar product

Fourth, we can scale vectors. We do this multiplying the vector by a scalar (which is a a good, honest, regular number). When we do this, we get a vector in the same direction if the factor is positive, and a vector in the opposite direction if the factor is negative. The length is the result of multiplying the original length by the absolute value of scalar.

For example, if we did $d = a * 2$, then $d$ would be a vector in the same direction as $a$ but $|d| = |a| * 2$.

Notice that if we did $e = a + a$, then $e$ would also be a vector in the same direction as $a$ and $|e| = |a| * 2$.

To compute the scalar product, we multiply every component of the vector by the scalar.

For example, in 2D:

$g = a * f$

Means

$x_g = x_a * f$

$y_g = y_a * f$

And in 3D it means:

$x_g = x_a * f$

$y_g = y_a * f$

$z_g = z_a * f$

And it will extend in similar fashion to the number of dimensions we need.

Notice that if we have a vector $a$ and we scale it by 1, we get the same vector $a$.


Dot product

The dot product between two vectors is the total sum of the component-wise product. And by component-wise product I mean multiplying the components of one vector with the components of the other.

So, we do the dot product like this in 2D:

$a·b = x_a * x_b + y_a * y_b$

And in 3D:

$a·b = x_a * x_b + y_a * y_b + z_a * z_b$

And it will extend in similar fashion to the number of dimensions we need.


Notice that if we compute the dot product of a vector an itself, we are squaring its components and adding them together. Which is just one step from computing the length (taking the square root):

$|a| = \sqrt{a·a}$

That is:

$a·a = |a|²$


The dot product distributes around vector addition. That is, $(a + b)·c = a·c + b·c$. I'm not including a proof of this on this answer. However, I'll use this fact later.


Also, the dot product has the following trigonometric identity:

$a·b = |a||b|cos(θ)$

Where $θ$ is the angle between the vectors $a$ and $b$. I will include how to deduce this from the law of cosine at the end.


Inverse operations

We can get a vector of the same length as another, but in the opposite direction, by scaling it by $-1$. We are going to treat this as the negative of the vector. That is $-a = a * -1$.

And we can define vector subtraction as the addition with the negative vector. That is $a - b = a + (b * -1)$.

These operations behave as expected with vector addition. For example, $b - b$ gives us the zero vector.


Similarly we can define a scalar division. It will be the scalar product by the multiplicative inverse of the scalar. That is $a/f = a * 1/f$.

This allows us to say that $a = a/f * f$ (as long as $f$ is not zero).


Normalization

Given a vector $a$, we can find a vector of length 1 (also known as a unit vector) $\hat{a}$, by scaling the vector by the inverse of its length.

That is $\hat{a} = a/|a|$

Or, if you prefer $\hat{a} = a * 1/|a|$

This unit vector represents the direction of the vector. Using this we can decompose any non-zero vector in direction and length:

$a = \hat{a} * |a|$


Vector Projection

The projection of a vector $a$ on another vector $b$, denoted $proj_b(a)$, is a new vector that is either in the same or opposite direction as $b$, and its length is how much $a$ goes in the direction of $b$.

Please notice that "how much $a$ goes in the direction of $b$" does not make sense if $b$ has no direction. That is, if $b$ is the zero vector, we cannot do the projection.

Projection of the vector a over the vector b

We could also say that the projection of a vector $a$ on another vector $b$ is the result of scaling the vector $b$ such that it forms a right angle (quarter turn) triangle such as the one shown above.

A more formal definition is that the projection of a vector $a$ on another $b$ is: the orthogonal projection of the position pointed by $a$ when placed at the origin, on the straight line that crosses the origin and the position pointed by $b$ when placed on the origin.


To be clear, we place both the vector we are projecting ($a$) and the vector we are projecting onto ($b$) on the same origin point (marked here in orange, on the bottom left):

…

That is, we have arrows that come from the same origin point, which represent the vector we are projecting ($a$) and the vector we are projecting onto ($b$).

Then the vector on which we are projecting ($b$) defines a straight line that crosses the origin point. And we are doing an orthogonal projection onto that straight line. The resulting vector is equivalent to scaling $b$ such that we have a right angle (quarter turn) towards $a$, such as depicted above.


By the way, notice that when $b$ is the zero vector, it points to the origin when placed at the origin. And there are infinite possible straight lines that cross the origin.


Finding the vector projection formula

I'll be working with these vectors to match the picture on the question:

…

We are going to project the vector $l$ on the vector $n$, that is $proj_n(l)$.

Remember that the projection of a vector $l$ on another vector $n$ is the result of scaling the vector $n$ by some factor. That is $proj_n(l) = \hat{n} * f$. We don't know $f$, but it is the length of the projection.


Now, let us consider the angle between our vectors, which is labelled as $θ$. Given that we have a right angle (quarter turn) triangle, from trigonometry, we can find the length of the projection:

$f = |l|cos(θ)$

And since we had $proj_n(l) = \hat{n} * f$ we can replace $f$ to get:

$proj_n(l) = \hat{n} * |l|cos(θ)$

We don't know $cos(θ)$.


Now we are going to use this identity: $l·n = |l||n|cos(θ)$. Notice it has $cos(θ)$ that we need. So, let us solve for that:

$l·n = |l||n|cos(θ)$

$\implies$

$(l·n)/|l||n| = cos(θ)$

And we can replace that in $proj_n(l) = \hat{n} * |l|cos(θ)$ to get:

$proj_n(l) = \hat{n} * |l|((l·n)/|l||n|)$

$\implies$

$proj_n(l) = \hat{n} * (l·n)/|n|$

And that is our vector projection.


We may also find it written like this:

$proj_n(l) = n/|n| * (l·n)/|n|$

Or like this:

$proj_n(l) = n * (l·n)/|n|²$

Or like this:

$proj_n(l) = n * (l·n)/(n·n)$


Vector reflection

For the vector reflection we want to find a vector that is flipped around the normal:

…

Here I have labelled the reflection as $r$. I have also labelled the projection as $t$. That is $t = proj_n(l) = \hat{n} * (l·n)/|n|$.

And I have marked a vector $q$ placed where $t$ points and pointing to where $l$ points to. That is known as a "vector rejection".

The vector projection and vector rejection combine to make the original vector by adding them together. As I explained when talking about vector addition, we can find the addition of vectors when placing them one after the other. Which is how $q$ and $t$ are placed. So we have that $t + q = l$.

From there we can solve for $q$:

$t + q = l$

$\implies$

$t + q - t = l - t$

$\implies$

$q = l - t$


Now, to get our reflection $r$, we can either start with $t$ and subtract $q$, or we can start with $l$ and subtract $q$ twice. I'm going to do the latter:

$r = l - 2q$

$\implies$

$r = l - 2(l - t)$

$\implies$

$r = l - 2l + 2t$

$\implies$

$r = 2t - l$

Then we replace $t$ with the projection:

$r = 2(\hat{n} * (l·n)/|n|) - l$

And rearrange:

$r = \hat{n} * 2(l·n)/|n| - l$

And that is our vector reflection.


We could also have it written like this:

$r = n/|n| * 2(l·n)/|n| - l$

Or like this:

$r = n * 2(l·n)/|n|² - l$

Or like this:

$r = n * 2(l·n)/(n·n) - l$


Finally, if $n$ was a unit vector (a vector of length 1) to begin with, then $|n| = 1$ and $\hat{n} = n$. Which gives us:

$r = n * 2(l·n) - l$

Which is the formula on the question.


Bonus: Deducing the dot product trigonometric identity

Here I will deduce that $l·n = |l||n|cos(θ)$. And the starting point will be the law of cosine. I'm not including a proof of the law of cosines in this answer.

Consider the triangle we have been working with:

…

The cosine law tells us that:

$|q|² = |t|² + |l|² - 2|t||l|cos(θ)$

This is a generalization of the Pythagoras' Theorem for an arbitrary angles. This formula will work even if the triangle didn't have a right angle (quarter turn).

Now, notice that when we do a dot product of a vector by itself we squaring and adding its components. That is, we are doing every step to compute the length, except we didn't take the square root at the end.

That is: $a·a = |a|²$. Let us replace that:

$q·q = t·t + l·l - 2|t||l|cos(θ)$


Now, we are going to compute $q·q$ (remember that $q = l - t$) by distributing the dot product:

$q·q = (l - t)·(l - t)$

$\implies$

$q·q = l·(l - t) - t·(l - t)$

$\implies$

$q·q = (l·l - l·t) - (t·l - t·t)$

$\implies$

$q·q = l·l - l·t - t·l + t·t$

$\implies$

$q·q = t·t + l·l - 2 * l·t$


Now we are going to replace $q·q$ in the prior equation with what we just found:

$t·t + l·l - 2 * l·t = t·t + l·l - 2|t||l|cos(θ)$

And simplify:

$l·t = |t||l|cos(θ)$

Which is our dot product trigonometric identity.