diff --git a/main.cc b/main.cc index 08d04bc..d75e0cb 100644 --- a/main.cc +++ b/main.cc @@ -44,6 +44,7 @@ void update_state() { check_collisions(); for (unsigned int i = 0; i < n_balls; ++i) ball_update_state(balls + i); + polygons_update_state(); spaceship_update_state(); } diff --git a/matrix.h b/matrix.h new file mode 100644 index 0000000..bb2a621 --- /dev/null +++ b/matrix.h @@ -0,0 +1,15 @@ +#ifndef MATRIX_H_INCLUDED +#define MATRIX_H_INCLUDED + +#include "vec2d.h" + +class matrix { + public: + vec2d b1, b2; +}; + +inline vec2d operator*(matrix m, vec2d v) { + return vec2d{v.x * m.b1.x + v.y * m.b2.x, v.x * m.b1.y + v.y * m.b2.y}; +} + +#endif diff --git a/polygon_generator.cc b/polygon_generator.cc index 0eb828d..fad40e5 100644 --- a/polygon_generator.cc +++ b/polygon_generator.cc @@ -3,27 +3,35 @@ #include #include -#define PI 3.141592653589793238462643323 - static double to_rad(double angle_in_deg) { - static double PI_180 = PI / 180; + static double PI_180 = M_PI / 180; return angle_in_deg * PI_180; } polygon poly_generate::rectangle(double width, double height) { assert(width > 0); assert(height > 0); - return polygon{ - {0, 0}, 0, {{0, 0}, {width, 0}, {width, height}, {0, height}}}; + return polygon{{0, 0}, + 0, + {{-width / 2, -height / 2}, + {width / 2, -height / 2}, + {width / 2, height / 2}, + {-width / 2, height / 2}}}; } polygon poly_generate::triangle(double side1, double side2, double angle) { assert(side1 > 0); assert(side2 > 0); - return polygon{{0, 0}, - 0, - {{0, 0}, - {side1, 0}, - {side2 * std::cos(to_rad(angle)), - side2 * std::sin(to_rad(angle))}}}; + vec2d points[] = {{0, 0}, + {side1, 0}, + {side2 * std::cos(to_rad(angle)), side2 * std::sin(to_rad(angle))}}; + + vec2d barycenter = { + (points[0].x + points[1].x + points[2].x) / 3, + (points[0].y + points[1].y + points[2].y) / 3, + }; + + for (unsigned int i = 0; i < 3; ++i) + points[i] -= barycenter; + return polygon{{0, 0}, 0, {std::begin(points), std::end(points)}}; } diff --git a/polygons.cc b/polygons.cc index d0d3ffe..9208fa6 100644 --- a/polygons.cc +++ b/polygons.cc @@ -1,7 +1,9 @@ #include "polygons.h" +#include "matrix.h" #include "polygon_generator.h" +#include #include polygon* polygons = nullptr; @@ -10,19 +12,43 @@ uint n_polygons = 3; void polygons_init_state() { polygons = new polygon[n_polygons]; - polygons[0] = poly_generate::triangle(200, 200, 30).set_center({300, 200}); - polygons[1] = poly_generate::square(200).set_center({100, 400}); - polygons[2] = poly_generate::rectangle(200, 100).set_center({400, 400}); + polygons[0] = poly_generate::triangle(150, 150, 30) + .set_center({400, 300}) + .set_angle(90); + polygons[1] = poly_generate::square(200).set_center({200, 600}); + polygons[2] = poly_generate::rectangle(200, 100).set_center({600, 600}); +} + +static double to_rad(double angle_in_deg) { + static double PI_180 = M_PI / 180; + return angle_in_deg * PI_180; +} + +void polygons_update_state() { + static double angle = 0; + for (polygon* p = polygons; p != polygons + n_polygons; ++p) { + p->rotate(1); + p->translate({2 * std::cos(angle), 0}); + } + angle -= .03; } void polygon::draw(cairo_t* cr) const { const vec2d& center = this->center; cairo_set_source_rgb(cr, 1, 1, 1); - for (auto& point : this->points) - cairo_line_to(cr, center.x + point.x, center.y + point.y); - cairo_line_to( - cr, center.x + this->points[0].x, center.y + this->points[0].y); + double cos_theta = std::cos(to_rad(this->angle)); + double sin_theta = std::sin(to_rad(this->angle)); + + matrix rotation = matrix{{cos_theta, sin_theta}, {-sin_theta, cos_theta}}; + + vec2d final_point; + for (auto& point : this->points) { + final_point = rotation * point; + cairo_line_to(cr, center.x + final_point.x, center.y + final_point.y); + } + final_point = rotation * this->points[0]; + cairo_line_to(cr, center.x + final_point.x, center.y + final_point.y); cairo_stroke(cr); }