From 89e250dcba695a2401f5e7bfa85e99d27a9a165f Mon Sep 17 00:00:00 2001 From: Karma Riuk Date: Fri, 19 May 2023 16:31:38 +0200 Subject: [PATCH] Removed the passing of the mass through parameters. Now the mass is determined by the area of the polygon --- polygon_generator.cc | 102 +++++++++++++++++++++++++------------------ polygon_generator.h | 28 ++++-------- polygons.cc | 24 ++++++---- polygons.h | 9 ++++ 4 files changed, 93 insertions(+), 70 deletions(-) diff --git a/polygon_generator.cc b/polygon_generator.cc index 42f3117..d91457e 100644 --- a/polygon_generator.cc +++ b/polygon_generator.cc @@ -3,29 +3,36 @@ #include #include +#define MASS_COEF .1 + static double to_rad(double angle_in_deg) { static double PI_180 = M_PI / 180; return angle_in_deg * PI_180; } -polygon poly_generate::rectangle( - double width, double height, double mass, std::string label) { +polygon +poly_generate::rectangle(double width, double height, std::string label) { assert(width > 0); assert(height > 0); static const double one_over_twelve = 1. / 12; - return polygon{{0, 0}, + + double mass = MASS_COEF * width * height; + + return polygon{ + {0, 0}, 0, {{-width / 2, -height / 2}, - {-width / 2, height / 2}, - {width / 2, height / 2}, - {width / 2, -height / 2}}, + {-width / 2, height / 2}, + {width / 2, height / 2}, + {width / 2, -height / 2}}, one_over_twelve * mass * (width * width + height * height), mass, label}; } polygon poly_generate::triangle( - double side1, double side2, double angle, double mass, std::string label) { + double side1, double side2, double angle, std::string label +) { assert(side1 > 0); assert(side2 > 0); static const double one_over_36 = 1. / 36; @@ -33,16 +40,21 @@ polygon poly_generate::triangle( base = side1; height = side2 * std::sin(to_rad(angle)); vec2d points[] = { - {0, 0}, {side1, 0}, {side2 * std::cos(to_rad(angle)), height}}; + {0, 0}, + {side1, 0}, + {side2 * std::cos(to_rad(angle)), height}}; vec2d barycenter = { (points[0].x + points[1].x + points[2].x) / 3, (points[0].y + points[1].y + points[2].y) / 3, }; + double mass = MASS_COEF * base * height * .5; + for (unsigned int i = 0; i < 3; ++i) points[i] -= barycenter; - return polygon{{0, 0}, + return polygon{ + {0, 0}, 0, {std::begin(points), std::end(points)}, one_over_36 * mass * base * std::pow(height, 3), @@ -50,28 +62,6 @@ polygon poly_generate::triangle( label}; } -polygon poly_generate::regular( - double radius, uint n_sides, double mass, std::string label) { - assert(n_sides > 2); - std::vector points; - label += " "; - label += n_sides; - points.reserve(n_sides); - double theta = 2 * M_PI / n_sides; - - for (uint i = 0; i < n_sides; i++) - points.push_back({radius * cos(i * theta), radius * sin(i * theta)}); - - double l = vec2d::norm(points[1] - points[0]); - - double sin_, cos_; - sincos(M_PI / n_sides, &sin_, &cos_); - double cot = cos_ / sin_; - - double inertia = mass * l * l / 24 * (1 + 3 * cot * cot); - return polygon{{0, 0}, 0, points, inertia, mass, label}; -} - static double area_of_triangle(vec2d& a, vec2d& b, vec2d& c) { return std::abs(vec2d::cross(c - a, b - a)) / 2; } @@ -80,23 +70,46 @@ static double area_of_poly(std::vector& points, vec2d& centroid) { double area = 0; for (int i = 0; i < points.size(); ++i) area += area_of_triangle( - centroid, points[i], points[(i + 1) % points.size()]); + centroid, + points[i], + points[(i + 1) % points.size()] + ); return area; } -static double intertia_of_polygon_subtriangle(double total_mass, - double total_area, - vec2d& centroid, - vec2d& p1, - vec2d& p2) { +polygon poly_generate::regular(double radius, uint n_sides, std::string label) { + assert(n_sides > 2); + std::vector points; + points.reserve(n_sides); + double theta = 2 * M_PI / n_sides; + + + for (uint i = 0; i < n_sides; i++) + points.push_back({radius * cos(i * theta), radius * sin(i * theta)}); + + vec2d centroid = {0, 0}; + double mass = MASS_COEF * area_of_poly(points, centroid); + double l = vec2d::norm(points[1] - points[0]); + + double sin_, cos_; + sincos(M_PI / n_sides, &sin_, &cos_); + double cot = cos_ / sin_; + + double inertia = mass * l * l / 24 * (1 + 3 * cot * cot); + return polygon{centroid, 0, points, inertia, mass, label}; +} + +static double intertia_of_polygon_subtriangle( + double total_mass, double total_area, vec2d& centroid, vec2d& p1, vec2d& p2 +) { double partial_area = area_of_triangle(centroid, p1, p2); double partial_mass = total_mass * partial_area / total_area; vec2d CA = p1 - centroid; vec2d AB = p2 - p1; - return partial_mass / 2 * - (vec2d::norm2(AB) / 3 + vec2d::dot(AB, CA) + vec2d::norm2(CA)); + return partial_mass / 2 + * (vec2d::norm2(AB) / 3 + vec2d::dot(AB, CA) + vec2d::norm2(CA)); } static vec2d centroid(std::vector& points) { @@ -107,15 +120,20 @@ static vec2d centroid(std::vector& points) { return vec2d{x, y} / points.size(); } -polygon poly_generate::general( - std::vector points, double mass, std::string label) { +polygon poly_generate::general(std::vector points, std::string label) { double intertia = 0; vec2d c = centroid(points); double area = area_of_poly(points, c); + double mass = MASS_COEF * area; for (int i = 0; i < points.size(); ++i) intertia += intertia_of_polygon_subtriangle( - mass, area, c, points[i], points[(i + 1) % points.size()]); + mass, + area, + c, + points[i], + points[(i + 1) % points.size()] + ); for (auto& p : points) // set the center of the polygon to it's centroid p -= c; diff --git a/polygon_generator.h b/polygon_generator.h index 77304ad..ad90a83 100644 --- a/polygon_generator.h +++ b/polygon_generator.h @@ -7,31 +7,21 @@ namespace poly_generate { - polygon rectangle(double width, - double height, - double mass = 1, - std::string label = "rectangle"); + polygon + rectangle(double width, double height, std::string label = "rectangle"); - inline polygon square( - double width, double mass = 1, std::string label = "square") { + inline polygon square(double width, std::string label = "square") { assert(width > 0); - return rectangle(width, width, mass, label); + return rectangle(width, width, label); }; - polygon triangle(double side1, - double side2, - double angle, - double mass = 1, - std::string label = "triangle"); + polygon triangle( + double side1, double side2, double angle, std::string label = "triangle" + ); - polygon regular(double radius, - uint n_sides, - double mass = 1, - std::string label = "regular"); + polygon regular(double radius, uint n_sides, std::string label = "regular"); - polygon general(std::vector points, - double mass = 1, - std::string label = "general"); + polygon general(std::vector points, std::string label = "general"); }; // namespace poly_generate #endif diff --git a/polygons.cc b/polygons.cc index 2850b74..16ca336 100644 --- a/polygons.cc +++ b/polygons.cc @@ -22,22 +22,27 @@ void polygons_init_state() { int wall_thickness = 50; uint n = 0; // north wall - polygons[n++] = poly_generate::rectangle(width, wall_thickness, INFINITY) + polygons[n++] = poly_generate::rectangle(width, wall_thickness) + .set_mass(INFINITY) .set_center({width / 2., -wall_thickness / 2.}); // south wall - polygons[n++] = poly_generate::rectangle(width, wall_thickness, INFINITY) + polygons[n++] = poly_generate::rectangle(width, wall_thickness) + .set_mass(INFINITY) .set_center({width / 2., height + wall_thickness / 2.}); // west wall - polygons[n++] = poly_generate::rectangle(wall_thickness, height, INFINITY) + polygons[n++] = poly_generate::rectangle(wall_thickness, height) + .set_mass(INFINITY) .set_center({-wall_thickness / 2., height / 2.}); // east wall - polygons[n++] = poly_generate::rectangle(wall_thickness, height, INFINITY) + polygons[n++] = poly_generate::rectangle(wall_thickness, height) + .set_mass(INFINITY) .set_center({width + wall_thickness / 2., height / 2.}); // middle wall - polygons[n++] = poly_generate::rectangle(50, height / 2., INFINITY) + polygons[n++] = poly_generate::rectangle(50, height / 2.) + .set_mass(INFINITY) .set_center({25 + width * 1. / 2, height / 2.}) - .set_angle(0); + .set_angle(30); polygons[n++] = poly_generate::regular(100, 3) .set_center({100, 400}) @@ -50,15 +55,16 @@ void polygons_init_state() { .set_speed({-200, -10}); polygons[n++] = poly_generate::general( - {{0, 0}, {100, 0}, {100, 100}, {50, 150}, {0, 100}}, - 3 + {{0, 0}, {100, 0}, {100, 100}, {50, 150}, {0, 100}} ) .set_center({200, 600}) .set_angle(45) .set_speed({10, 0}); polygons[n++] = poly_generate::rectangle(100, 150).set_center({600, 200}); - polygons[n++] = poly_generate::regular(50, 5).set_center({150, 150}); + polygons[n++] = poly_generate::regular(50, 5) + .set_center({150, 150}) + .set_speed({50, -50}); polygons[n++] = poly_generate::general({{0, 0}, {50, 80}, {0, 160}, {-50, 80}}) .set_center({700, 700}) diff --git a/polygons.h b/polygons.h index fcc0c10..a72ff6a 100644 --- a/polygons.h +++ b/polygons.h @@ -71,6 +71,14 @@ class polygon { 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; } @@ -102,6 +110,7 @@ class polygon { 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; } };