2023-03-14 21:46:36 +01:00
|
|
|
#ifndef POLYGONS_H_INCLUDED
|
|
|
|
#define POLYGONS_H_INCLUDED
|
|
|
|
|
2023-06-13 13:50:07 +02:00
|
|
|
#include "color.h"
|
2023-03-14 21:46:36 +01:00
|
|
|
#include "vec2d.h"
|
|
|
|
|
2023-03-25 10:57:32 +01:00
|
|
|
#include <cmath>
|
2023-03-14 21:46:36 +01:00
|
|
|
#include <gtk/gtk.h>
|
2023-03-25 10:57:32 +01:00
|
|
|
#include <utility>
|
2023-03-14 21:46:36 +01:00
|
|
|
#include <vector>
|
|
|
|
|
2023-04-02 21:53:21 +02:00
|
|
|
typedef std::pair<vec2d, vec2d> rect;
|
|
|
|
|
2023-03-14 21:46:36 +01:00
|
|
|
class polygon {
|
2023-03-25 10:57:32 +01:00
|
|
|
private:
|
|
|
|
void update_global_points();
|
|
|
|
|
2023-03-14 21:46:36 +01:00
|
|
|
public:
|
|
|
|
vec2d center;
|
|
|
|
double angle;
|
|
|
|
std::vector<vec2d> points;
|
2023-04-02 21:53:21 +02:00
|
|
|
double inertia;
|
|
|
|
double mass;
|
2023-05-17 13:21:06 +02:00
|
|
|
std::string label;
|
2023-04-02 21:53:21 +02:00
|
|
|
|
2023-06-13 13:50:07 +02:00
|
|
|
color_t color;
|
2023-03-25 10:57:32 +01:00
|
|
|
std::vector<vec2d> global_points = points;
|
|
|
|
|
2023-03-25 14:03:07 +01:00
|
|
|
vec2d speed;
|
|
|
|
double angular_speed;
|
2023-03-14 21:46:36 +01:00
|
|
|
|
|
|
|
void draw(cairo_t* cr) const;
|
2023-03-25 10:57:32 +01:00
|
|
|
void draw_bounding_rect(cairo_t* cr) const;
|
|
|
|
|
2023-04-02 21:53:21 +02:00
|
|
|
rect get_bounding_box() const {
|
|
|
|
vec2d tl{INFINITY, INFINITY}, tr{-INFINITY, -INFINITY};
|
2023-03-25 10:57:32 +01:00
|
|
|
|
|
|
|
for (auto& point : this->global_points) {
|
2023-04-02 21:53:21 +02:00
|
|
|
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;
|
2023-03-25 10:57:32 +01:00
|
|
|
}
|
2023-04-02 21:53:21 +02:00
|
|
|
return {tl, tr};
|
2023-03-25 10:57:32 +01:00
|
|
|
}
|
2023-03-14 23:09:48 +01:00
|
|
|
|
|
|
|
polygon& set_center(vec2d c) {
|
|
|
|
center = c;
|
2023-03-25 10:57:32 +01:00
|
|
|
update_global_points();
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
polygon& set_speed(vec2d s) {
|
|
|
|
speed = s;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2023-03-25 14:03:07 +01:00
|
|
|
polygon& set_angular_speed(double as) {
|
2023-03-25 10:57:32 +01:00
|
|
|
angular_speed = as;
|
2023-03-14 23:09:48 +01:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
polygon& set_angle(double a) {
|
|
|
|
angle = a;
|
2023-03-25 10:57:32 +01:00
|
|
|
update_global_points();
|
2023-03-14 23:09:48 +01:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2023-04-02 21:53:21 +02:00
|
|
|
polygon& set_mass(double m) {
|
|
|
|
mass = m;
|
2023-05-19 16:31:38 +02:00
|
|
|
// 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;
|
2023-04-02 21:53:21 +02:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2023-03-14 23:09:48 +01:00
|
|
|
polygon& translate(vec2d delta) {
|
|
|
|
center += delta;
|
2023-03-25 10:57:32 +01:00
|
|
|
update_global_points();
|
2023-03-14 23:09:48 +01:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
polygon& rotate(double delta) {
|
|
|
|
angle += delta;
|
2023-03-25 10:57:32 +01:00
|
|
|
update_global_points();
|
2023-03-14 23:09:48 +01:00
|
|
|
return *this;
|
|
|
|
}
|
2023-04-02 21:53:21 +02:00
|
|
|
|
|
|
|
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();
|
|
|
|
}
|
2023-05-17 13:21:06 +02:00
|
|
|
|
|
|
|
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;
|
2023-05-19 16:31:38 +02:00
|
|
|
os << " intertia: " << p.inertia << std::endl;
|
2023-05-17 13:21:06 +02:00
|
|
|
return os;
|
|
|
|
}
|
2023-03-14 21:46:36 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
extern polygon* polygons;
|
|
|
|
extern uint n_polygons;
|
|
|
|
|
2023-06-13 13:50:07 +02:00
|
|
|
extern bool draw_speed;
|
|
|
|
|
2023-03-14 21:46:36 +01:00
|
|
|
extern void polygons_init_state();
|
|
|
|
extern void polygons_update_state();
|
|
|
|
extern void polygons_draw(cairo_t* cr);
|
2023-05-19 10:18:49 +02:00
|
|
|
extern void polygons_destroy();
|
2023-03-14 21:46:36 +01:00
|
|
|
|
|
|
|
#endif
|