A faith that cannot survive collision with the truth is not worth many regrets.
— Arthur C. Clarke, The Exploration of Space
Simple Bounce Physics
A previous tutorial showcased a Kicker-table with a ball bouncing off its edges. This behaviour is easily
simulated by observing that the angle of reflection equals the angle of incidence. When the ball hits one of the sides
of the table, then it always reflects off the side at an angle equal and opposite to its initial trajectory.
Here is the C++-code of that demo:
This seems to be a bit too complicated — there is no way I want to think about angles each time I want an object to
bounce from a surface. In the following, we will derive a much easier formula by using simple geometry and a
mathematical technique called projection.
Planes of any Orientation
This tutorial tries to give a better explanation to the above phenomenon by deriving the equations of reflection from
any hypersurface, i.e. off a line in 2D and off a plane in 3D. Once again, we observe that the angle of reflection
equals the angle of incidence relative to the normal vector of the plane:
If you forgot what the normal vector of a plane is, check out this tutorial.
In the 2D case, basically speaking, the normal vector of a line can be found by using the scalar product of the underlying vector space. Let and
be two points in a plane, and the vector joining those two points,
then the normal vector of the line defined by those two points must satisfy: , i.e.
, which is satisfied for the vector . All that is now left to do is to normalize the
vector: .
Projections
Now, how does the normal vector help to find the vector of reflection? First, the projection of the vector of incidence
along the normal vector must be computed (think of the shadow cast by shining a light from the left of the above
figure). The following figure shows the projection of a point to a vector space:
A projection on a vector space is an idempotent linear map . If the vectors
define a basis of , the projection of any point to the vector space can be computed using the underlying
scalar product as follows: .
Thus, in our 2D-example, the projection of the vector to the line defined by the vector , denoted by
, can be computed using the scalar product of the underlying vector space as follows: . Basically, this just tells us that the shadow cast by the vector is times the vector . The negative sign comes from the fact that we have chosen the origin of
our coordinate system to be the origin of the normal vector.
Finding the Vector of Reflection
Now finding the vector of reflection, , is rather easy. Using the shadow we just cast, we can find a vector
joining the starting point of the vector of incidence and the normal vector: ,
thus the vector of reflection is given by: , which yields the desired result:
, where , thus, if we really
want to express the vector of reflection purely by the vector of incidence and the normal vector: . This is surely easier than having to think about angles all the time.
An Example
As an example, let us compute the reflection vector when the vector of incidence is given by and the
normal vector by :
Implementation
The function to compute the vector of reflection is straightforward, we simply use the above formula to change the
vector of incidence to become the vector of reflection:
With this function, it is now possible to greatly simplify the above code to handle the collision of the ball with the
walls of the Kicker-table:
As you can see, it is no longer necessary to think about angles and Pi or whatever, all that needs to be done is to
define a normal vector for each wall and the rest is just mathemagical. (I have always wanted to make that joke!)
In the next tutorial, we will learn how to improve the above collision detection code.
References
Geogebra
Tricks of the Windows Programming Gurus, by A. LaMothe