Skip to content
Snippets Groups Projects
Commit 06e8f994 authored by Florian Burgener's avatar Florian Burgener
Browse files

Refactoring + Moon

parent cf42040f
Branches
No related tags found
No related merge requests found
*.o
main
.vscode
{
"files.associations": {
"solarsystem.h": "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;
}
......@@ -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
......@@ -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:
......
#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);
}
}
#ifndef SOLAR_SYSTEM_H
#define SOLAR_SYSTEM_H
#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;
} 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);
} PlanetarySystem;
// 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);
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
#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);
}
}
}
......@@ -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];
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment