diff --git a/gravity.c b/gravity.c index cd27349..eb254c3 100644 --- a/gravity.c +++ b/gravity.c @@ -4,23 +4,22 @@ #include void gravity(universe_t *uni) { - mass_body_t body_1; - mass_body_t body_2; - for (unsigned int i = 0; i < uni->num_bodies - 1; i++) { - body_1 = uni->bodies[i]; + const float dt = 1.0f / simx; + for (unsigned int i = 0; i < uni->num_bodies; i++) { + mass_body_t *body_1 = &uni->bodies[i]; for (unsigned int y = i + 1; y < uni->num_bodies; y++) { - body_2 = uni->bodies[y]; - float force = - simx * NEWTON_G * body_1.mass * body_2.mass / - (vec2_len(vec2_diff(body_2.position, body_1.position)) * TIMESTEP); - Vector2 acceleration = - vec2_normalize(vec2_diff(body_2.position, body_1.position)); - Vector2 acceleration_1 = vec2_scale(acceleration, force / body_1.mass); - Vector2 acceleration_2 = vec2_scale(acceleration, -force / body_2.mass); - body_1.speed = vec2_sum(body_1.speed, acceleration_1); - body_2.speed = vec2_sum(body_1.speed, acceleration_2); - uni->bodies[y] = body_2; + mass_body_t *body_2 = &uni->bodies[y]; + Vector2 separation = vec2_diff(body_2->position, body_1->position); + float distance_squared = vec2_dot(separation, separation); + if (distance_squared == 0.0f) { + continue; + } + Vector2 direction = vec2_normalize(separation); + float factor = NEWTON_G * dt / distance_squared; + body_1->speed = + vec2_sum(body_1->speed, vec2_scale(direction, factor * body_2->mass)); + body_2->speed = vec2_sum(body_2->speed, + vec2_scale(direction, -factor * body_1->mass)); } - uni->bodies[i] = body_1; } } diff --git a/main.c b/main.c index 696a166..bf864ed 100644 --- a/main.c +++ b/main.c @@ -4,6 +4,7 @@ #include "gravity.h" #include "mechanics.h" #include "objects.h" +#include "vec_utils.h" #include #include #include @@ -31,9 +32,8 @@ void *physics(void *args) { universe_t *uni = (universe_t *)args; struct timespec ot, ct; while (true) { - printf("a"); clock_gettime(CLOCK_MONOTONIC, &ct); - // gravity(uni); + gravity(uni); mechanics(uni); ot = ct; long long elapsed = timespec_diff_ns(ct, ot); @@ -59,10 +59,15 @@ int main(void) { const char *welcome_text = "Welcome to Fucked Physics!"; universe_t universe = {0, NULL}; universe.bodies = malloc(1024 * sizeof(mass_body_t)); - universe.num_bodies = 2; + universe.num_bodies = 3; + + universe.bodies[0] = + (mass_body_t){10000000000000.0f, 1000, {-0, 0}, {0, 0}, 200}; + universe.bodies[1] = + (mass_body_t){100000000.0f, 0.1, {-10000.1, 0}, {0, -0.2}, 50}; + universe.bodies[2] = + (mass_body_t){100000000.0f, 0.1, {10000, 0}, {0, -0.2}, 50}; - universe.bodies[0] = (mass_body_t){100000000000.0f, 200, {0, 0}, {0, 0}}; - universe.bodies[1] = (mass_body_t){100, 50, {500, 0}, {0, 2}}; SetConfigFlags(FLAG_WINDOW_RESIZABLE); InitWindow(800, 450, "Fucked Physics"); SetTargetFPS(120); @@ -75,11 +80,17 @@ int main(void) { key_pressed = GetKeyPressed(); switch (key_pressed) { case KEY_I: - v_scale += 0.1; + if (v_scale >= 0.1) { + v_scale += 0.1; + } else { + v_scale += 0.01; + } break; case KEY_O: if (v_scale > 0.1) { v_scale -= 0.1; + } else if (v_scale > 0.01) { + v_scale -= 0.01; } break; case KEY_LEFT: @@ -97,23 +108,35 @@ int main(void) { } } while (key_pressed != 0); + if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON) || + IsMouseButtonDown(MOUSE_RIGHT_BUTTON)) { + Vector2 mouse_pos = vec2_scale( + transform_to_center(vec2_scale(GetMousePosition(), -1)), -1); + mouse_pos = vec2_scale(mouse_pos, 1 / v_scale); + + universe.bodies[universe.num_bodies] = + (mass_body_t){100000.0f, 0.1, mouse_pos, {0, 0}, 10}; + universe.num_bodies++; + } + if (canvas_offset.x + GetRenderWidth() * 0.5 / v_scale > - GetRenderWidth() * 5) { + GetRenderWidth() * 50) { canvas_offset.x = - -GetRenderWidth() * 0.5 / v_scale + GetRenderWidth() * 5; + -GetRenderWidth() * 0.5 / v_scale + GetRenderWidth() * 50; } else if (canvas_offset.x - GetRenderWidth() * 0.5 / v_scale < - -GetRenderWidth() * 5) { - canvas_offset.x = GetRenderWidth() * 0.5 / v_scale - GetRenderWidth() * 5; + -GetRenderWidth() * 50) { + canvas_offset.x = + GetRenderWidth() * 0.5 / v_scale - GetRenderWidth() * 50; } if (canvas_offset.y + GetRenderHeight() * 0.5 / v_scale > - GetRenderHeight() * 5) { + GetRenderHeight() * 50) { canvas_offset.y = - -GetRenderHeight() * 0.5 / v_scale + GetRenderHeight() * 5; + -GetRenderHeight() * 0.5 / v_scale + GetRenderHeight() * 50; } else if (canvas_offset.y - GetRenderHeight() * 0.5 / v_scale < - -GetRenderHeight() * 5) { + -GetRenderHeight() * 50) { canvas_offset.y = - GetRenderHeight() * 0.5 / v_scale - GetRenderHeight() * 5; + GetRenderHeight() * 0.5 / v_scale - GetRenderHeight() * 50; } BeginDrawing(); @@ -123,9 +146,9 @@ int main(void) { Vector2 body_position = vec2_scale(universe.bodies[i].position, v_scale); body_position = vec2_sum(body_position, scaled_offset); DrawCircleV(transform_to_center(body_position), - universe.bodies[i].radius * v_scale, - (Color){((256 / universe.num_bodies) * i) % 256, - 255 * (i % 2), 255 * (i % 2) * (i % 3), 255}); + universe.bodies[i].draw_radius * v_scale, + (Color){((256 / universe.num_bodies) * i) % 256 / 2, + 255 * (i % 2) / 2, 255 * (i % 2) * (i % 3) / 2, 255}); } DrawText(welcome_text, center_x_text(welcome_text, GetRenderWidth(), 20), diff --git a/mechanics.c b/mechanics.c index d0c83f8..9c0857e 100644 --- a/mechanics.c +++ b/mechanics.c @@ -48,8 +48,8 @@ void collide(mass_body_t *a, mass_body_t *b, const Vector2 normal, } void collide_rigid(mass_body_t *a, float restitution) { - float max_x = GetRenderWidth() * 10 / 2.0f - a->radius; - float max_y = GetRenderHeight() * 10 / 2.0f - a->radius; + float max_x = GetRenderWidth() * 100 / 2.0f - a->radius; + float max_y = GetRenderHeight() * 100 / 2.0f - a->radius; if (a->position.x > max_x) { a->position.x = max_x; @@ -86,7 +86,7 @@ void mechanics(universe_t *uni) { body_2 = uni->bodies[y]; collision = body_collision(&body_1, &body_2); if (!vec2_is_null(collision)) { - collide(&body_1, &body_2, collision, 1.0); + collide(&body_1, &body_2, collision, 0.99); } uni->bodies[y] = body_2; } diff --git a/objects.h b/objects.h index 14ad1b5..c01398c 100644 --- a/objects.h +++ b/objects.h @@ -7,6 +7,7 @@ typedef struct { float radius; Vector2 position; Vector2 speed; + float draw_radius; } mass_body_t; typedef struct universe {