From 4d14f2a30b20e856294939249fb5ff93e9847ff7 Mon Sep 17 00:00:00 2001 From: Karma Riuk Date: Sat, 25 Mar 2023 10:57:32 +0100 Subject: [PATCH] Added wall bouncing logic (flawed); added bounding box computation and display --- polygons.cc | 80 +++++++++++++++++++++++++++++++++++++++-------------- polygons.h | 40 +++++++++++++++++++++++++++ 2 files changed, 99 insertions(+), 21 deletions(-) diff --git a/polygons.cc b/polygons.cc index 9208fa6..2b23d49 100644 --- a/polygons.cc +++ b/polygons.cc @@ -1,22 +1,28 @@ #include "polygons.h" +#include "cairo.h" +#include "game.h" #include "matrix.h" #include "polygon_generator.h" -#include #include polygon* polygons = nullptr; -uint n_polygons = 3; +uint n_polygons = 1; void polygons_init_state() { polygons = new polygon[n_polygons]; + std::cout << "width" << width << std::endl; + // polygons[0] = poly_generate::square(200) + // .set_center({400, 600}) + // .set_angle(37) + // .set_speed({1, -1}); 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}); + .set_angle(45) + .set_speed({3, 2}); + // polygons[2] = poly_generate::rectangle(200, 100).set_center({600, 600}); } static double to_rad(double angle_in_deg) { @@ -24,31 +30,63 @@ static double to_rad(double angle_in_deg) { 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}); +static void check_border_collision(polygon* p) { + for (auto& point : p->global_points) { + if (point.x <= 0 || point.x >= width) { + p->speed.x *= -1; + break; + } + if (point.y <= 0 || point.y >= height) { + p->speed.y *= -1; + break; + } } - angle -= .03; } -void polygon::draw(cairo_t* cr) const { - const vec2d& center = this->center; - cairo_set_source_rgb(cr, 1, 1, 1); +void polygons_update_state() { + for (polygon* p = polygons; p != polygons + n_polygons; ++p) { + p->rotate(1); + check_border_collision(p); + p->translate(p->speed); + } +} +void polygon::update_global_points() { 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); + for (uint i = 0; i < this->points.size(); ++i) + this->global_points[i] = rotation * this->points[i] + this->center; +} + +void polygon::draw_bounding_rect(cairo_t* cr) const { + cairo_set_source_rgb(cr, .7, .7, .7); + double dashes[] = {5, 10}; + cairo_set_dash(cr, dashes, 2, 0); + + auto bb = this->get_bounding_box(); + vec2d min = bb.first, max = bb.second; + + cairo_line_to(cr, min.x, min.y); + cairo_line_to(cr, min.x, max.y); + cairo_line_to(cr, max.x, max.y); + cairo_line_to(cr, max.x, min.y); + cairo_line_to(cr, min.x, min.y); + cairo_stroke(cr); + cairo_set_dash(cr, 0, 0, 0); // disable dashes +} + +void polygon::draw(cairo_t* cr) const { + this->draw_bounding_rect(cr); + + cairo_set_source_rgb(cr, 1, 1, 1); + + for (auto& point : this->global_points) + cairo_line_to(cr, point.x, point.y); + + cairo_line_to(cr, this->global_points[0].x, this->global_points[0].y); cairo_stroke(cr); } diff --git a/polygons.h b/polygons.h index 168b225..ca26ce2 100644 --- a/polygons.h +++ b/polygons.h @@ -3,34 +3,74 @@ #include "vec2d.h" +#include #include +#include #include class polygon { + private: + void update_global_points(); + public: vec2d center; double angle; std::vector points; + std::vector global_points = points; + + vec2d speed, angular_speed; void draw(cairo_t* cr) const; + void draw_bounding_rect(cairo_t* cr) const; + + std::pair get_bounding_box() const { + vec2d min{INFINITY, INFINITY}, max{-INFINITY, -INFINITY}; + + for (auto& point : this->global_points) { + if (point.x < min.x) + min.x = point.x; + if (point.y < min.y) + min.y = point.y; + + if (point.x > max.x) + max.x = point.x; + if (point.y > max.y) + max.y = point.y; + } + return {min, max}; + } polygon& set_center(vec2d c) { center = c; + update_global_points(); + return *this; + } + + polygon& set_speed(vec2d s) { + speed = s; + return *this; + } + + polygon& set_angular_speed(vec2d as) { + angular_speed = as; return *this; } polygon& set_angle(double a) { angle = a; + update_global_points(); return *this; } polygon& translate(vec2d delta) { center += delta; + update_global_points(); return *this; } polygon& rotate(double delta) { angle += delta; + update_global_points(); return *this; } };