We consider three kinds of transformations:
-
Translation
-
Scaling
-
Rotation
In this extension, you will implement the mathematical part of transformations. On top of these, you will be able to build
Transformations are represented as matrices. For example, 2D scaling by a factor \(s\) is represented by the following 3×3 matrix:
Transformations can be combined using matrix multiplication. For example, translating \((2, 3)\) followed by scaling by \(5\) gives ()
Important
|
Matrices and functions that create transformation-representing matrices have already been written for you.
You can find them in |
During the implementation of the ray tracer you will need transformations and their inverse. For example, the inverse operation of "rotating something 90° around the X-axis" is "rotating -90° around the X-axis."
While it is possible the compute the inverse of a matrix, doing so can be quite computationally expensive. For instance, say you are given
Inverting this requires some tricky calculations: However, because we know from above that this is actually translating and scaling, we can compute the inverse in a much simpler way:
-
The inverse of translating by \((2, 3)\) is translating by \((-2, -3)\).
-
The inverse of scaling by \(5\) is scaling by \(\frac15\).
-
Inverting a combined transformation involves changing the order of the transformations.
Knowing this, we can easily compute the inverse matrix:
The moral of the story is that inverting a matrix is much easier if you know which transformations it represents.
So, whenever we create a matrix, we will immediately create its inverse along with it.
We will bundle the matrix and its inverse in a separate object of type Transformation2D
(or Transformation3D
).
Important
|
Both |
1. 2D
1.1. 2D Translation
This transformation has already been defined for you. The code can act as a guide for you to implement the two other transformations.
1.2. 2D Rotation
In the files
|
1.3. 2D Scaling
In the files
|
2. 3D
2.1. 3D Translation
In the files
|
2.2. 3D Rotation
In the files
|
Note
|
The reason we define three separate functions for rotations is because rotations are not commutative. |
2.3. 3D Scaling
In the files
|
3. Bindings
No bindings are necessary: we won’t be needing this functionality in our scripting language. It will be used in other C++ code, though.
4. Evaluation
Write tests for each of the transformations, both in 2D and 3D. Write them concisely: define helper macros so that you can write your tests as
Note how that a single macro tests both the |