diff --git a/.gitignore b/.gitignore index fd015c1bac4fa00a0b317bf72a2259fc8107cbbd..95916b85437d46518c6531e342efa1517d93339e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ -*.o -main +*.o +main +.vscode diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 85f136c4f708fa967f5c26d708e06386089d9b1c..0000000000000000000000000000000000000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "files.associations": { - "solarsystem.h": "c" - } -} diff --git a/CelestialObject.c b/CelestialObject.c index b3362edc68598a6fcf3a8eebf67de347c408e328..95b1292da646cc3b640b61c59131ce716f0793ce 100644 --- a/CelestialObject.c +++ b/CelestialObject.c @@ -5,14 +5,19 @@ #define G 6.67e-11 #define SUN_MASS 1.989e30 -CelestialObject *celestial_object_create(double mass, double semi_major_half, double orbital_eccentricity) { +CelestialObject *celestial_object_create(double mass, double semi_major_axis, double eccentricity, uint32_t drawing_disc_radius, uint32_t drawing_color) { CelestialObject *object = (CelestialObject*)malloc(sizeof(CelestialObject)); object->mass = mass; object->previous_position = vector2_create_zero(); - double perihelion = semi_major_half * (1 - orbital_eccentricity); - object->current_position = vector2_create(-perihelion, 0); + double periapsis = semi_major_axis * (1 - eccentricity); + object->current_position = vector2_create(-periapsis, 0); + + object->semi_major_axis = semi_major_axis; + object->eccentricity = eccentricity; + object->drawing_disc_radius = drawing_disc_radius; + object->drawing_color = drawing_color; return object; } diff --git a/CelestialObject.h b/CelestialObject.h index 468b2b8a068d408df290239a33bc884576d14de9..1732f78a5383e3a85ef62d4de9e25aa889523816 100644 --- a/CelestialObject.h +++ b/CelestialObject.h @@ -9,8 +9,12 @@ typedef struct CelestialObject { double mass; Vector2 previous_position; Vector2 current_position; + double semi_major_axis; + double eccentricity; + uint32_t drawing_disc_radius; + uint32_t drawing_color; } CelestialObject; -CelestialObject *celestial_object_create(double mass, double semi_major_half, double orbital_eccentricity); +CelestialObject *celestial_object_create(double mass, double semi_major_axis, double eccentricity, uint32_t drawing_disc_radius, uint32_t drawing_color); #endif diff --git a/Makefile b/Makefile index 1e2510a3cb168f3425c6464fde18c7006ce57e95..b8b51028b0c6945ea9c5a358e5a1e2d25742298b 100644 --- a/Makefile +++ b/Makefile @@ -2,13 +2,14 @@ TARGET = main CC:=gcc # CFLAGS:=-g -Ofast -Wall -Wextra -fsanitize=address -fsanitize=leak -std=gnu11 # CFLAGS:=-fsanitize=address +CFLAGS:=-g -Ofast -Wall -Wextra -std=gnu11 LDFLAGS:=-lm -lSDL2 VPATH:=gfx %.o: %.c $(HEADERS) $(CC) $(CFLAGS) -c $< -o $@ -$(TARGET): main.o Vector2.o CelestialObject.o SolarSystem.o gfx.o +$(TARGET): main.o Vector2.o CelestialObject.o PlanetarySystem.o gfx.o $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) clean: diff --git a/PlanetarySystem.c b/PlanetarySystem.c new file mode 100644 index 0000000000000000000000000000000000000000..efbda9bbcc987848c226f52de03afd4b5cb08624 --- /dev/null +++ b/PlanetarySystem.c @@ -0,0 +1,125 @@ +#include "PlanetarySystem.h" + +#include <stdlib.h> + +#include "CelestialObject.h" +#include "Vector2.h" +#include "gfx/gfx.h" + +const uint32_t SCREEN_WIDTH = 1000; +const uint32_t SCREEN_HEIGHT = 1000; + +const double G = 6.67430 * 1E-11; + +// Eccentricity : https://fr.wikipedia.org/wiki/Excentricit%C3%A9_orbitale +const double MERCURY_ECCENTRICITY = 0.20563069; +const double VENUS_ECCENTRICITY = 0.00677323; +const double EARTH_ECCENTRICITY = 0.01671022; +const double MARS_ECCENTRICITY = 0.09341233; + +// Mass : https://promenade.imcce.fr/fr/pages5/557.html +const double SUN_MASS = 1.988900 * 1E30; +const double MERCURY_MASS = 0.33018 * 1E24; +const double VENUS_MASS = 4.8685 * 1E24; +const double EARTH_MASS = 5.9736 * 1E24; +const double MARS_MASS = 0.64185 * 1E24; + +// Semi-major axis : https://www.le-systeme-solaire.net/demi-grand-axe.html +const double MERCURY_SEMI_MAJOR_AXIS = 579.09227 * 1E8; +const double VENUS_SEMI_MAJOR_AXIS = 108.208475 * 1E9; +const double EARTH_SEMI_MAJOR_AXIS = 149.598262 * 1E9; +const double MARS_SEMI_MAJOR_AXIS = 227.943824 * 1E9; + +PlanetarySystem *planetary_system_create(double interval) { + PlanetarySystem *planetary_system = (PlanetarySystem *)malloc(sizeof(PlanetarySystem)); + + planetary_system->objects_length = 6; + planetary_system->objects = (CelestialObject **)malloc(sizeof(PlanetarySystem *) * planetary_system->objects_length); + planetary_system->interval = interval; + + planetary_system->objects[0] = celestial_object_create(SUN_MASS, 0, 0, 50, 0x00FFFFFF); + planetary_system->objects[1] = celestial_object_create(MERCURY_MASS, MERCURY_SEMI_MAJOR_AXIS, MERCURY_ECCENTRICITY, 10, 0x00DBCECA); + planetary_system->objects[2] = celestial_object_create(VENUS_MASS, VENUS_SEMI_MAJOR_AXIS, VENUS_ECCENTRICITY, 20, 0x008B7D82); + planetary_system->objects[3] = celestial_object_create(EARTH_MASS, EARTH_SEMI_MAJOR_AXIS, EARTH_ECCENTRICITY, 20, 0x006b93d6); + planetary_system->objects[4] = celestial_object_create(MARS_MASS, MARS_SEMI_MAJOR_AXIS, MARS_ECCENTRICITY, 12, 0x00BC2732); + planetary_system->objects[5] = celestial_object_create(7.34767309 * 1E22, 384.399 * 1E6, 0.0549, 5, 0x8A2BE2); + planetary_system->objects[5]->current_position.x += planetary_system->objects[3]->current_position.x; + + return planetary_system; +} + +CelestialObject *planetary_system_get_star(PlanetarySystem *planetary_system) { + return planetary_system->objects[0]; +} + +Vector2 calculate_gravitational_acceleration(PlanetarySystem *planetary_system, uint32_t object_index) { + Vector2 a = vector2_create_zero(); + + for (uint32_t i = 0; i < planetary_system->objects_length; i += 1) { + if (i == object_index) + continue; + Vector2 r = vector2_substract(planetary_system->objects[i]->current_position, planetary_system->objects[object_index]->current_position); + double a_scalar = G * planetary_system->objects[i]->mass * pow(pow(vector2_norm(r), 2), -1); + a = vector2_add(a, vector2_multiply(vector2_normalize(r), a_scalar)); + } + + return a; +} + +void planetary_system_update(PlanetarySystem *planetary_system) { + for (uint32_t i = 1; i < planetary_system->objects_length; i += 1) { + CelestialObject *object = planetary_system->objects[i]; + Vector2 current_position = object->current_position; + Vector2 new_position; + + if (vector2_is_zero(object->previous_position)) { + CelestialObject *star = planetary_system_get_star(planetary_system); + + if (i == 5) { + star = planetary_system->objects[3]; + } + + double periapsis_velocity_scalar = sqrt((G * star->mass * (1 + object->eccentricity)) / (object->semi_major_axis * (1 - object->eccentricity))); + + if (i == 5) { + printf("%lf\n", periapsis_velocity_scalar); + periapsis_velocity_scalar += 30290.322245; + } + + Vector2 r = vector2_normalize(vector2_create(current_position.y, -current_position.x)); + Vector2 periapsis_velocity = vector2_multiply(r, periapsis_velocity_scalar); + vector2_print(periapsis_velocity); + + new_position = vector2_add(current_position, vector2_multiply(periapsis_velocity, planetary_system->interval)); + Vector2 a = calculate_gravitational_acceleration(planetary_system, i); + new_position = vector2_add(new_position, vector2_multiply(a, 0.5 * pow(planetary_system->interval, 2))); + } else { + // continue; + new_position = vector2_substract(vector2_multiply(current_position, 2), object->previous_position); + Vector2 a = calculate_gravitational_acceleration(planetary_system, i); + new_position = vector2_add(new_position, vector2_multiply(a, pow(planetary_system->interval, 2))); + } + + object->previous_position = object->current_position; + object->current_position = new_position; + } +} + +Vector2 scale_position(Vector2 position) { + Vector2 scaled_position = vector2_multiply(position, 1.0 / (250 * 1E9)); + scaled_position = vector2_fit_canvas(scaled_position, SCREEN_WIDTH, SCREEN_HEIGHT); + return scaled_position; +} + +void planetary_system_draw(PlanetarySystem *planetary_system, struct gfx_context_t *context) { + gfx_clear(context, COLOR_BLACK); + + for (uint32_t i = 0; i < planetary_system->objects_length; i += 1) { + CelestialObject *object = planetary_system->objects[i]; + // Vector2 tmp = vector2_substract(object->current_position, planetary_system->objects[3]->current_position); + // tmp = vector2_multiply(tmp, 1); + Vector2 scaled_position = scale_position(object->current_position); + + draw_full_circle(context, scaled_position.x, scaled_position.y, object->drawing_disc_radius, object->drawing_color); + } +} diff --git a/PlanetarySystem.h b/PlanetarySystem.h new file mode 100644 index 0000000000000000000000000000000000000000..9fb902ab7cba65b7548fc9e111f04c6308fe28fa --- /dev/null +++ b/PlanetarySystem.h @@ -0,0 +1,22 @@ +#ifndef PLANETARY_SYSTEM_H +#define PLANETARY_SYSTEM_H + +#include <stdint.h> + +#include "CelestialObject.h" +#include "gfx/gfx.h" + +const uint32_t SCREEN_WIDTH; +const uint32_t SCREEN_HEIGHT; + +typedef struct { + uint32_t objects_length; + CelestialObject **objects; + double interval; +} PlanetarySystem; + +PlanetarySystem *planetary_system_create(double interval); +void planetary_system_update(PlanetarySystem *planetary_system); +void planetary_system_draw(PlanetarySystem *planetary_system, struct gfx_context_t *context); + +#endif diff --git a/SolarSystem.c b/SolarSystem.c deleted file mode 100644 index 6415ea0b6e3456bfcabaf9155b9b81b67b6465ed..0000000000000000000000000000000000000000 --- a/SolarSystem.c +++ /dev/null @@ -1,145 +0,0 @@ -#include "SolarSystem.h" - -#include <stdlib.h> - -#include "CelestialObject.h" -#include "Vector2.h" -#include "gfx/gfx.h" - -#define SCREEN_WIDTH 1000 -#define SCREEN_HEIGHT 1000 - -const int SUN_INDEX = 0; -const int MERCURE_INDEX = 1; -const int VENUS_INDEX = 2; -const int EARTH_INDEX = 3; -const int MARS_INDEX = 4; - -const double G = 6.67430 * 1E-11; - -// Eccentricties found at : https://fr.wikipedia.org/wiki/Excentricit%C3%A9_orbitale -const double MERCURE_ECCENTRICITY = 0.20563069; -const double VENUS_ECCENTRICITY = 0.00677323; -const double EARTH_ECCENTRICITY = 0.01671022; -const double MARS_ECCENTRICITY = 0.09341233; - -// CelestialObjects Masses found at : https://promenade.imcce.fr/fr/pages5/557.html -const double SUN_MASS = 1.9889 * 1E30; -const double MERCURE_MASS = 0.33018 * 1E24; -const double VENUS_MASS = 4.8685 * 1E24; -const double EARTH_MASS = 5.9736 * 1E24; -const double MARS_MASS = 0.64185 * 1E24; - -// CelestialObjects Semi-major axis found at : https://www.le-systeme-solaire.net/demi-grand-axe.html -const double MERCURE_SEMI_MAJOR_AXIS = 579.1 * 1E8; -const double VENUS_SEMI_MAJOR_AXIS = 108.2 * 1E9; -const double EARTH_SEMI_MAJOR_AXIS = 149.6 * 1E9; -const double MARS_SEMI_MAJOR_AXIS = 227.9 * 1E9; - -SolarSystem *solar_system_create(double interval) { - SolarSystem *solar_system = (SolarSystem *)malloc(sizeof(SolarSystem)); - - solar_system->objects_length = 5; - solar_system->objects = (CelestialObject **)malloc(sizeof(SolarSystem *) * solar_system->objects_length); - solar_system->interval = interval; - - solar_system->objects[SUN_INDEX] = celestial_object_create(SUN_MASS, 0, 0); - - solar_system->objects[MERCURE_INDEX] = celestial_object_create(MERCURE_MASS, MERCURE_SEMI_MAJOR_AXIS, MERCURE_ECCENTRICITY); - - solar_system->objects[VENUS_INDEX] = celestial_object_create(VENUS_MASS, VENUS_SEMI_MAJOR_AXIS, VENUS_ECCENTRICITY); - - solar_system->objects[EARTH_INDEX] = celestial_object_create(EARTH_MASS, EARTH_SEMI_MAJOR_AXIS, EARTH_ECCENTRICITY); - - solar_system->objects[MARS_INDEX] = celestial_object_create(MARS_MASS, MARS_SEMI_MAJOR_AXIS, MARS_ECCENTRICITY); - - return solar_system; -} - -CelestialObject *solar_system_get_star(SolarSystem *solar_system) { - return solar_system->objects[0]; -} - -Vector2 calculate_gravitational_acceleration(SolarSystem *solar_system, int32_t object_index) { - Vector2 a = vector2_create_zero(); - - for (int32_t i = 0; i < solar_system->objects_length; i += 1) { - if (i == object_index) - continue; - Vector2 r = vector2_substract(solar_system->objects[i]->current_position, solar_system->objects[object_index]->current_position); - double a_scalar = G * solar_system->objects[i]->mass * pow(pow(vector2_norm(r), 2), -1); - a = vector2_add(a, vector2_multiply(vector2_normalize(r), a_scalar)); - } - - return a; -} - -void solar_system_update(SolarSystem *solar_system) { - for (int32_t i = 1; i < solar_system->objects_length; i += 1) { - CelestialObject *object = solar_system->objects[i]; - - if (vector2_is_zero(solar_system->objects[i]->previous_position)) { - // https://i.ytimg.com/vi/hbEbD1Z_tNQ/maxresdefault.jpg - - CelestialObject *star = solar_system->objects[SUN_INDEX]; - double perihelion_speed = 0; - - if (i == MERCURE_INDEX) { - perihelion_speed = sqrt((G * star->mass * (1 + MERCURE_ECCENTRICITY)) / (MERCURE_SEMI_MAJOR_AXIS * (1 - MERCURE_ECCENTRICITY))); - - } else if (i == VENUS_INDEX) { - perihelion_speed = sqrt((G * star->mass * (1 + VENUS_ECCENTRICITY)) / (VENUS_SEMI_MAJOR_AXIS * (1 - VENUS_ECCENTRICITY))); - } else if (i == EARTH_INDEX) { - perihelion_speed = sqrt((G * star->mass * (1 + EARTH_ECCENTRICITY)) / (EARTH_SEMI_MAJOR_AXIS * (1 - EARTH_ECCENTRICITY))); - } else if (i == MARS_INDEX) { - perihelion_speed = sqrt((G * star->mass * (1 + MARS_ECCENTRICITY)) / (MARS_SEMI_MAJOR_AXIS * (1 - MARS_ECCENTRICITY))); - } - - Vector2 tmp = object->current_position; - Vector2 r = vector2_normalize(vector2_create(tmp.y, -tmp.x)); - Vector2 v = vector2_multiply(r, perihelion_speed); - - Vector2 current_position = object->current_position; - Vector2 new_position = vector2_add(current_position, vector2_multiply(v, solar_system->interval)); - object->previous_position = object->current_position; - object->current_position = new_position; - } else { - Vector2 new_position = vector2_substract(vector2_multiply(object->current_position, 2), object->previous_position); - Vector2 a = calculate_gravitational_acceleration(solar_system, i); - new_position = vector2_add(new_position, vector2_multiply(a, pow(solar_system->interval, 2))); - object->previous_position = object->current_position; - object->current_position = new_position; - } - } -} - -void solar_system_draw(SolarSystem *solar_system, struct gfx_context_t *context) { - gfx_clear(context, COLOR_BLACK); - - for (int32_t i = 0; i < solar_system->objects_length; i += 1) { - CelestialObject *object = solar_system->objects[i]; - - Vector2 scaled_position = vector2_multiply(object->current_position, 1.0 / (300 * 1E9)); - scaled_position = vector2_fit_canvas(scaled_position, SCREEN_WIDTH, SCREEN_HEIGHT); - - if (i == SUN_INDEX) { - draw_full_circle(context, scaled_position.x, scaled_position.y, 50, COLOR_YELLOW); - } - - if (i == MERCURE_INDEX) { - draw_full_circle(context, scaled_position.x, scaled_position.y, 10, (COLOR_WHITE + COLOR_BLACK)); - } - - if (i == VENUS_INDEX) { - draw_full_circle(context, scaled_position.x, scaled_position.y, 20, (COLOR_RED + COLOR_YELLOW)); - } - - if (i == EARTH_INDEX) { - draw_full_circle(context, scaled_position.x, scaled_position.y, 20, COLOR_BLUE); - } - - if (i == MARS_INDEX) { - draw_full_circle(context, scaled_position.x, scaled_position.y, 12, COLOR_RED); - } - } -} diff --git a/SolarSystem.h b/SolarSystem.h deleted file mode 100644 index a9f10107c5a91daaa50c62e2b19881d08c4479fd..0000000000000000000000000000000000000000 --- a/SolarSystem.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef SOLAR_SYSTEM_H -#define SOLAR_SYSTEM_H - -#include <stdint.h> - -#include "CelestialObject.h" -#include "gfx/gfx.h" - -typedef struct { - uint32_t objects_length; - CelestialObject **objects; - double interval; -} SolarSystem; - -SolarSystem *solar_system_create(double interval); -void solar_system_update(SolarSystem *solar_system); -void solar_system_draw(SolarSystem *solar_system, struct gfx_context_t *context); - -// void show_system(struct gfx_context_t *ctxt, system_t *system); -// void update_system(system_t *system, double interval); -// void free_system(system_t *system); - -#endif diff --git a/main.c b/main.c index bcd78bb5e4bd52c66546f7cf05ee816f7ab39312..d21add36503dab0b00bee9da06b481fa0cd85133 100644 --- a/main.c +++ b/main.c @@ -3,16 +3,13 @@ #include <stdlib.h> #include <time.h> -#include "SolarSystem.h" +#include "PlanetarySystem.h" #include "Vector2.h" -// #include "gfx/gfx.h" - -#define SCREEN_WIDTH 1000 -#define SCREEN_HEIGHT 1000 +#include "gfx/gfx.h" int main() { // srand(time(NULL)); - srand(0); + // srand(0); struct gfx_context_t *context = gfx_create("Solar System", SCREEN_WIDTH, SCREEN_HEIGHT); @@ -21,19 +18,20 @@ int main() { return EXIT_FAILURE; } - int32_t time_elapsing_per_second = 3600 * 24 * 100; - int32_t refresh_rate = 240; + int32_t time_elapsing_per_second = 3600 * 24 * 10; + int32_t refresh_rate = 480; int32_t elapsed_time = 0; double sleep_duration = 1.0 / refresh_rate * 1E9; + printf("%lf\n", (double)time_elapsing_per_second / refresh_rate); - SolarSystem *solar_system = solar_system_create(time_elapsing_per_second / refresh_rate); + PlanetarySystem *planetary_system = planetary_system_create((double)time_elapsing_per_second / refresh_rate); int64_t tmp = time(NULL) % 1000; while (true) { - solar_system_update(solar_system); + planetary_system_update(planetary_system); gfx_present(context); - solar_system_draw(solar_system, context); + planetary_system_draw(planetary_system, context); if (elapsed_time % refresh_rate == 0) { char title[100];