Fixed orbit

This commit is contained in:
h3cx committed 2026-10-01 19:09:54 +02:00
1 parent 2a7669aa21
commit c729ab4f90
7 files changed
+110 -85

No files matched your search

+56 -45
View File
@@ -1,17 +1,16 @@
#define _POSIX_C_SOURCE 200809L
#include "consts.h"
#include "gravity.h"
#include "mechanics.h"
#include "magnetism.h"
#include "mechanics.h"
#include "objects.h"
#include "vec_utils.h"
#include <bits/time.h>
#include <errno.h>
#include <math.h>
#include <pthread.h>
#include <raylib.h>
#include <stdio.h>
#include <stdlib.h>
#include <threads.h>
#include <time.h>
#include <unistd.h>
@@ -23,33 +22,31 @@ static inline int center_y_text(int height, int size) {
return (height - size) / 2;
}
long long timespec_diff_ns(struct timespec end, struct timespec start) {
return (end.tv_sec - start.tv_sec) * 1000000000LL +
(end.tv_nsec - start.tv_nsec);
}
void *physics(void *args) {
universe_t *uni = (universe_t *)args;
struct timespec ot, ct;
struct timespec next_step;
clock_gettime(CLOCK_MONOTONIC, &next_step);
while (true) {
clock_gettime(CLOCK_MONOTONIC, &ct);
gravity(uni);
mechanics(uni);
magnetism(uni);
ot = ct;
long long elapsed = timespec_diff_ns(ct, ot);
long long remaining = TIMESTEP / simx - elapsed;
if (remaining > 0) {
long long sleep_time = remaining * 9 / 10;
struct timespec sleep_time_spec = {0, sleep_time};
thrd_sleep(&sleep_time_spec, NULL);
next_step.tv_sec += LOOP_TIMESTEP / 1000000000LL;
next_step.tv_nsec += LOOP_TIMESTEP % 1000000000LL;
if (next_step.tv_nsec >= 1000000000L) {
next_step.tv_nsec -= 1000000000L;
next_step.tv_sec++;
}
gravity(uni);
magnetism(uni);
mechanics(uni);
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
if (now.tv_sec > next_step.tv_sec ||
(now.tv_sec == next_step.tv_sec && now.tv_nsec > next_step.tv_nsec)) {
next_step =
now; // An overrun starts a fresh schedule, without catch-up steps.
}
// Sleep only until the deadline; processing time is already included.
while (clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next_step, NULL) ==
EINTR) {
}
do {
clock_gettime(CLOCK_MONOTONIC, &ct);
} while (timespec_diff_ns(ct, ot) < TIMESTEP / simx);
}
}
@@ -60,22 +57,27 @@ 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 = 5;
universe.num_bodies = 7;
universe.bodies[0] =
(mass_body_t){330432.0f, 696, {-0, 0}, {0, 0}, 696};
universe.bodies[1] =
(mass_body_t){0.055f, 2.439, {0.387*UA/RT, 0}, {0, -38.86/RT}, 50};
universe.bodies[2] =
(mass_body_t){0.815f, 0.1, {0.723*UA/RT, 0}, {0, -34.79/RT}, 50};
universe.bodies[3] =
(mass_body_t){1.0f, 0.1, {1*UA/RT, 0}, {0, -29.29/RT}, 50};
universe.bodies[4] =
(mass_body_t){0.107f, 200, {1.524*UA/RT, 0}, {0, -21.97/RT}, 200};
universe.bodies[5] =
(mass_body_t){317.83f, 0.1, {5.203*UA/RT, 0}, {0, -12.43/RT}, 50};
universe.bodies[6] =
(mass_body_t){95.159f, 200, {9.582*UA/RT, 0}, {0, -9.11/RT}, 200};
(mass_body_t){330432.0f, 696340 / RT, {0, 0}, {0, 0}, 600, 0, "Sun"};
universe.bodies[1] = (mass_body_t){
0.055f, 2439.7 / RT, {0.387 * UA / RT, 0}, {0, -38.86 / RT}, 80,
0, "Mercury"};
universe.bodies[2] = (mass_body_t){
0.815f, 6051.8 / RT, {0.723 * UA / RT, 0}, {0, -34.79 / RT}, 190,
0, "Venus"};
universe.bodies[3] = (mass_body_t){
1.0f, 1.0f, {1 * UA / RT, 0}, {0, -29.29 / RT}, 200, 0, "Earth"};
universe.bodies[4] = (mass_body_t){
0.107f, 3389.5 / RT, {1.524 * UA / RT, 0}, {0, -21.97 / RT}, 106,
0, "Mars"};
universe.bodies[5] = (mass_body_t){
317.83f, 69911 / RT, {5.203 * UA / RT, 0}, {0, -12.43 / RT}, 400,
0, "Jupiter"};
universe.bodies[6] = (mass_body_t){
95.159f, 58232 / RT, {9.582 * UA / RT, 0}, {0, -9.11 / RT}, 300,
0, "Saturn"};
SetConfigFlags(FLAG_WINDOW_RESIZABLE);
InitWindow(800, 450, "Fucked Physics");
SetTargetFPS(120);
@@ -116,14 +118,18 @@ int main(void) {
}
} while (key_pressed != 0);
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON) ||
IsMouseButtonDown(MOUSE_RIGHT_BUTTON)) {
if (universe.num_bodies < 1024 &&
(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};
(mass_body_t){100000.0f, 0.1, mouse_pos, {0, 0}, 10, 0, ""};
snprintf(universe.bodies[universe.num_bodies].name,
sizeof(universe.bodies[universe.num_bodies].name), "Body %u",
universe.num_bodies + 1);
universe.num_bodies++;
}
@@ -153,10 +159,15 @@ int main(void) {
Vector2 scaled_offset = vec2_scale(canvas_offset, v_scale);
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].draw_radius * v_scale,
body_position = transform_to_center(body_position);
float draw_radius = universe.bodies[i].draw_radius * v_scale;
DrawCircleV(body_position, draw_radius,
(Color){((256 / universe.num_bodies) * i) % 256 / 2,
255 * (i % 2) / 2, 255 * (i % 2) * (i % 3) / 2, 255});
// Keep labels readable at every zoom level.
DrawText(universe.bodies[i].name,
(int)(body_position.x + draw_radius + 6),
(int)(body_position.y - 8), 16, BLACK);
}
DrawText(welcome_text, center_x_text(welcome_text, GetRenderWidth(), 20),