Compare commits

...

8 Commits

Author SHA1 Message Date
fad703d504 made videos links prettier 2023-08-02 19:12:19 +02:00
da802cff9d Added toc to readme 2023-08-02 19:09:42 +02:00
a64670503a removed before.webm 2023-08-02 19:09:32 +02:00
d6a2727755 finally got videos to work!!
god github's video thing is scuffed...
2023-08-02 19:03:40 +02:00
de4e741d6a trying to make the video in the readme work :) 2023-08-02 18:07:03 +02:00
2b844647f4 trying to make the video in the readme work :) 2023-08-02 18:05:30 +02:00
e9f90bd11c Added before vs after to readme 2023-08-02 17:55:43 +02:00
87b4febc5d Added README with abstract 2023-08-02 17:34:11 +02:00
5 changed files with 109 additions and 16 deletions

70
README.md Normal file
View File

@ -0,0 +1,70 @@
# From Flying Balls to Colliding Polygons
## Table of contents
- [Abstract](#abstract)
- [Before vs After](#before-vs-after)
- [Context](#context)
- [Before](#before)
- [After](#after)
- [Contact](#contact)
## Abstract
> (text taken from the abstract of my report that you can find
> [here](https://github.com/karma-riuk/bachelor-project-report/blob/main/bachelorproject.pdf)
Physics engines are a fun and interesting way to learn about the laws of
physics, as well as computer science. They provide a real-time simulation of
common physical phenomena, and therefore illustrate theoretical concepts such as
the equations that dictate the motion of objects.
The goal of this project was to extend an existing physics engine built for
demonstration purposes. This engine was initially designed and developed to
simulate circular objects ("balls") in 2D.
With this project, we intended to extend this engine to also simulate arbitrary
polygons, again in a physically accurate way. The main technical challenges of
the project is therefore the correct simulation of the dynamics of rigid,
polygonal objects. In particular, we developed a model of polygonal rigid
objects:
- we implemented a simulation of their inertial motion, possibly in the
presence of a constant force field such as gravity;
- we detect collisions between objects;
- we compute and then simulate the dynamic effects of collisions.
The simulations are animated and displayed in real-time. It is also therefore
crucial that the simulation code be efficient to obtain smooth animations.
## Before vs After
### Context
A little of context for the follow videos:
- in the first video, the special ball with an arrow inside is a "spaceship",
that can be controlled by the user;
- the yellow bar that appears after midway through both videos represent the
restitution coefficient of the collision resolution (the lower it is, the
greater the dampening on impact between objects);
- the white line with a ball at the end that appears after the restitution
coefficient bar represents the gravity vector that gets applied to the speed
of each object at each frame, the ball is the direction the vector is pointing
it.
### Before
[before](https://github.com/karma-riuk/flying-balls/assets/30158492/ddc0d608-9667-4a21-8132-e056e443e0e2)
### After
[after](https://github.com/karma-riuk/flying-balls/assets/30158492/bd4013b8-bc01-4d52-aa2f-44dbc25de717)
<!-- ## Controls -->
<!---->
<!-- ## Installation -->
## Contact
If you have any question concerning this work, feel free to contact me at [arno.fauconnet@gmail.com](mailto:arno.fauconnet@gmail.com)

BIN
after.mp4 Normal file

Binary file not shown.

BIN
before.mp4 Normal file

Binary file not shown.

4
game.h
View File

@ -13,8 +13,8 @@ extern double delta; /* simulation time delta in seconds */
extern int width; /* game canvas width */
extern int height; /* game canvas height */
#define DEFAULT_WIDTH 800
#define DEFAULT_HEIGHT 800
#define DEFAULT_WIDTH 1000
#define DEFAULT_HEIGHT 1000
extern GtkWidget* canvas; /* game canvas object */

View File

@ -14,7 +14,7 @@
#include <utility>
#define ARROW_VAL_RATIO 1.7
#define SUBSETPS 5
bool draw_speed = true;
@ -35,6 +35,21 @@ static double random_color_component() {
return 1.0 * (rand() % 200 + 56) / 255;
};
static vec2d random_velocity() {
double r2;
vec2d v;
do {
v.x = v_min + rand() % (v_max + 1 - v_min);
v.y = v_min + rand() % (v_max + 1 - v_min);
r2 = vec2d::dot(v, v);
} while (r2 > v_max * v_max || r2 < v_min * v_min);
if (rand() % 2)
v.x = -v.x;
if (rand() % 2)
v.y = -v.y;
return v;
}
void polygons_init_state() {
n_polygons = 20;
polygons = new polygon[n_polygons];
@ -68,7 +83,6 @@ void polygons_init_state() {
.set_center({width / 2., height - height / 17.})
.set_angle(45);
// ---------- Shapes flying around start here ----------
polygons[n++] = poly_generate::regular(100, 3)
.set_center({100, 400})
@ -88,9 +102,14 @@ void polygons_init_state() {
.set_speed({10, 0});
polygons[n++] = poly_generate::rectangle(100, 150).set_center({600, 200});
polygons[n++] = poly_generate::regular(72, 8)
.set_center({500, 500})
.set_speed({100, 0});
polygons[n++] = poly_generate::regular(50, 5)
.set_center({150, 150})
.set_speed({100, 0});
.set_speed({150, 0});
polygons[n++] = poly_generate::general({{40, 20},
{40, 40},
@ -232,19 +251,24 @@ static void check_collisions(polygon* current_p) {
}
void polygons_update_state() {
const static float sub_delta = delta / SUBSETPS;
for (uint i = SUBSETPS; i--;) {
for (polygon* p = polygons; p != polygons + n_polygons; ++p) {
if (p->mass == INFINITY) // immovable objects don't need to be updated
// immovable objects don't need to be updated
if (p->mass == INFINITY)
continue;
check_collisions(p);
p->rotate(delta * p->angular_speed);
p->rotate(sub_delta * p->angular_speed);
p->angle = std::fmod(p->angle, 360);
p->translate(delta * p->speed);
p->translate(sub_delta * p->speed);
vec2d g = gravity_vector(p);
p->translate(.5 * delta * delta * g);
p->speed += delta * g;
p->translate(.5 * sub_delta * sub_delta * g);
p->speed += sub_delta * g;
}
}
}
@ -308,7 +332,6 @@ void polygon::draw(cairo_t* cr) const {
vec2d centroid = this->centroid();
draw_circle(cr, centroid, 1);
// draw speed
if (draw_speed && this->mass != INFINITY) {
hsv_t hsv = rgb2hsv(this->color);