Repository navigation
Lab 4: 2D Transformations
In this lab, we will practice making a simple 2D animation with hierarchies of transforms. Please go to the GitHub repo and look at the project directory "transform".
git clone --recursive https://github.com/arthurfirmino/icg.git
This programming example should be filled in /transform/main.cpp.
We use the Eigen math library to calculate all the transform matrices. Keep in mind that we practise everything on a 2D plane in this practise, so there should be no change on the Z-axis. There are several important matrix functions being used in this practise:
- Transform::Identity() returns an identity 4x4 matrix.
- Eigen::Translation3f(x, y, z) returns the translation matrix of a 3D translation. We should keep z == 0 in our example.
- Eigen::AngleAxisf(angle, axis) creates a rotational matrix of angle around the axis. Because we only make animation in 2D space in this example, axis here is the z axis, which is represented by Eigen::Vector3f::UnitZ().
- Eigen::AlignedScaling3f(x, y, z) returns the scaling matrix of a 3D scaling transform. We should keep z == 1 in our example.
The following code segment creates an animation of an earth orbiting around the sun, and a moon going around the earth. Note that many simple animation effects can be created with sinusoidal or circular movements, which is implemented by the std::sin and std::cos functions.
float freq = M_PI*time_s*SPEED_FACTOR;
// **** Sun transform
Transform sun_M = Transform::Identity();
sun_M *= Eigen::Translation3f(0.2, 0.0, 0.0);
sun_M *= Eigen::AngleAxisf(-freq/SUN_ROT_PERIOD, Eigen::Vector3f::UnitZ());
//scale_t: make the sun become bigger and smaller over the time!
float scale_t = 0.01*std::sin(freq);
sun_M *= Eigen::AlignedScaling3f(0.2 +scale_t, 0.2 +scale_t, 1.0);
// **** Earth transform
Transform earth_M = Transform::Identity();
//calculate the earth's orbit as an ellipse around the sun
float x_earth_orbit = 0.7*std::cos(-freq/EARTH_ORBITAL_PERIOD);
float y_earth_orbit = 0.5*std::sin(-freq/EARTH_ORBITAL_PERIOD);
earth_M *= Eigen::Translation3f(x_earth_orbit, y_earth_orbit, 0.0);
//save the earth's transform before spinning, so we don't spin the moon
//with the earth!
Transform earth_M_prespin = earth_M;
earth_M *= Eigen::AngleAxisf(-freq/EARTH_ROT_PERIOD, Eigen::Vector3f::UnitZ());
//make the picture of earth smaller
earth_M *= Eigen::AlignedScaling3f(0.08, 0.08, 1.0);
// **** Moon transform
Transform moon_M = earth_M_prespin;
// Make the moon orbit around the earth with 0.2 units of distance
moon_M *= Eigen::AngleAxisf(freq/MOON_ORBITAL_PERIOD, Eigen::Vector3f::UnitZ());
moon_M *= Eigen::Translation3f(0.2, 0.0, 0.0);
// Make the moon spining according to MOON_ROT_PERIOD
moon_M *= Eigen::AngleAxisf(-freq/MOON_ROT_PERIOD, -Eigen::Vector3f::UnitZ());
// Make the picture of moon smaller!
moon_M *= Eigen::AlignedScaling3f(0.04, 0.04, 1.0);
// draw the sun, the earth and the moon
sun.draw(sun_M.matrix());
earth.draw(earth_M.matrix());
moon.draw(moon_M.matrix());Eigen Math Library: http://eigen.tuxfamily.org/index.php?title=Main_Page
GLFW: http://www.glfw.org/
We use glfw 3 in our programming excises, its documentation can be found at: http://www.glfw.org/docs/latest/