Skip to content

Lab 4: 2D Transformations

ArthurFirmino edited this page Feb 5, 2018 · 1 revision

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".

Getting set up

git clone --recursive https://github.com/arthurfirmino/icg.git

2D transform matrix and hierarchy

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());

References

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/

Clone this wiki locally