/* in this version, main defines seven different matrices representing different transformations (their names suggest what they do) the last line of main: animate(rotz, line, 360); can be given any of those matrices as its first parameter, and any line as the second. It will draw the line, wait one second, apply the transformation defined by the matrix and draw it again, this is repeated 360 (third parameter) times. So if you stay with rotz as the matrix you will see the line slosly rotating thought a whole circle */ #include "library.h" const int winsize = 500; const int halfwinsize = winsize / 2; double matvecmul(const double m[4][4], const double v[4], const int i, const int p) { if (p == 4) return 0.0; return m[i][p] * v[p] + matvecmul(m, v, i, p + 1); } double matvecmul(const double m[4][4], const double v[4], const int i) { return matvecmul(m, v, i, 0); } const double pi = acos(-1.0); double degrees(const double x) { return x * pi / 180.0; } void move_to(const double p[4]) { move_to(halfwinsize + p[0], halfwinsize - p[1]); } void draw_to(const double p[4]) { draw_to(halfwinsize + p[0], halfwinsize - p[1]); } void animate(const double m[4][4], const double v[4], const int nsteps) { if (nsteps == 0) return; const double rotated[4] = { matvecmul(m, v, 0), matvecmul(m, v, 1), matvecmul(m, v, 2), matvecmul(m, v, 3) }; const double centre[4] = { 0, 0, 0, 1 }; const int c = get_pen_color(); move_to(centre); draw_to(rotated); wait(0.01); set_pen_color(color::white); move_to(centre); draw_to(rotated); set_pen_color(c); animate(m, rotated, nsteps - 1); } void main() { make_window(winsize, winsize); set_pen_width(3); const double rotz[4][4] = { { cos(degrees(1)), sin(degrees(1)), 0, 0 }, { -sin(degrees(1)), cos(degrees(1)), 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 } }; const double roty[4][4] = { { cos(degrees(1)), 0, sin(degrees(1)), 0 }, { 0, 1, 0, 0 }, { -sin(degrees(1)), 0, cos(degrees(1)), 0 }, { 0, 0, 0, 1 } }; const double rotx[4][4] = { { 1, 0, 0, 0 }, { 0, cos(degrees(1)), sin(degrees(1)), 0 }, { 0, -sin(degrees(1)), cos(degrees(1)), 0 }, { 0, 0, 0, 1 } }; const double grow[4][4] = { { 1.01, 0, 0, 0 }, { 0, 1.01, 0, 0 }, { 0, 0, 1.01, 0 }, { 0, 0, 0, 1 } }; const double shrink[4][4] = { { 0.98, 0, 0, 0 }, { 0, 0.98, 0, 0 }, { 0, 0, 0.98, 0 }, { 0, 0, 0, 1 } }; const double movx[4][4] = { { 1, 0, 0, 0.5 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 } }; const double movxy[4][4] = { { 1, 0, 0, 2 }, { 0, 1, 0, -2 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 } }; const double line[4] = { 50, 150, 150, 1 }; set_pen_color(color::red); animate(rotz, line, 360); }