#ifndef POLYGONS_H_INCLUDED #define POLYGONS_H_INCLUDED #include "color.h" #include "vec2d.h" #include #include #include #include typedef std::pair rect; class polygon { private: void update_global_points(); public: vec2d center; double angle; std::vector points; double inertia; double mass; std::string label; color_t color; std::vector global_points = points; vec2d speed; double angular_speed; void draw(cairo_t* cr) const; void draw_bounding_rect(cairo_t* cr) const; rect get_bounding_box() const { vec2d tl{INFINITY, INFINITY}, tr{-INFINITY, -INFINITY}; for (auto& point : this->global_points) { if (point.x < tl.x) tl.x = point.x; if (point.y < tl.y) tl.y = point.y; if (point.x > tr.x) tr.x = point.x; if (point.y > tr.y) tr.y = point.y; } return {tl, tr}; } 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(double as) { angular_speed = as; return *this; } polygon& set_angle(double a) { angle = a; update_global_points(); return *this; } polygon& set_mass(double m) { mass = m; // TODO: This is pretty shit, but it's good to make stuff work now, // since the only time we change the mass of an object is the wall, // otherwise we take the area and the polygon_generator module handles // that. But what's to be done is to extract the intertia calcualtion to // a new module so that we can import it here, and recalculate the // intertia of the polygon if the mass changes. if (m == INFINITY) inertia = INFINITY; return *this; } polygon& translate(vec2d delta) { center += delta; update_global_points(); return *this; } polygon& rotate(double delta) { angle += delta; update_global_points(); return *this; } vec2d centroid() const { double x = 0, y = 0; for (auto& p : global_points) x += p.x, y += p.y; return vec2d{x, y} / points.size(); } friend std::ostream& operator<<(std::ostream& os, polygon& p) { vec2d c = p.centroid(); os << p.label << ": " << std::endl; os << " mass: " << p.mass << std::endl; os << " position: " << c << std::endl; os << " angle: " << p.angle << std::endl; os << " speed: " << p.speed << std::endl; os << " angular speed: " << p.angular_speed << std::endl; os << " intertia: " << p.inertia << std::endl; return os; } }; extern polygon* polygons; extern uint n_polygons; extern bool draw_speed; extern void polygons_init_state(); extern void polygons_update_state(); extern void polygons_draw(cairo_t* cr); extern void polygons_destroy(); #endif