diff --git a/CelestialObject.c b/CelestialObject.c index d15849e3266a1296eb0c137dd2187f9d48543cc3..1bc7bacda333f4c64c48c29611feaa84bb1d6fe9 100644 --- a/CelestialObject.c +++ b/CelestialObject.c @@ -1,12 +1,14 @@ #include "CelestialObject.h" #include <GL/glut.h> +#include <math.h> #include <stdlib.h> #include <string.h> #include "drawing.h" -const int32_t PREVIOUS_POSITIONS_LENGTH = 200; +const double G = 6.67430 * 1E-11; +const int32_t PREVIOUS_POSITIONS_MAXIMUM_LENGTH = 200; CelestialObject *celestial_object_create(char *name, double mass, double semi_major_axis, double eccentricity, int32_t drawing_disc_radius, int32_t drawing_color) { CelestialObject *object = (CelestialObject *)malloc(sizeof(CelestialObject)); @@ -16,7 +18,7 @@ CelestialObject *celestial_object_create(char *name, double mass, double semi_ma object->previous_position = vector2_create_zero(); double periapsis = semi_major_axis * (1 - eccentricity); - object->current_position = vector2_create(-periapsis, 0); + object->position = vector2_create(-periapsis, 0); object->semi_major_axis = semi_major_axis; object->eccentricity = eccentricity; @@ -24,7 +26,7 @@ CelestialObject *celestial_object_create(char *name, double mass, double semi_ma object->drawing_disc_radius = drawing_disc_radius; object->drawing_color = drawing_color; - object->previous_positions = (Vector2 *)malloc(sizeof(Vector2) * PREVIOUS_POSITIONS_LENGTH); + object->previous_positions = (Vector2 *)malloc(sizeof(Vector2) * PREVIOUS_POSITIONS_MAXIMUM_LENGTH); object->previous_positions_length = 0; return object; @@ -35,33 +37,106 @@ void celestial_object_destroy(CelestialObject *object) { free(object); } -int32_t get_zoomed_drawing_disc_radius(CelestialObject *object, double zoom_factor) { - if (zoom_factor < 1) { - return object->drawing_disc_radius * zoom_factor; +void celestial_object_first_update(int32_t object_index, CelestialObject **objects, int32_t objects_length, int32_t main_object_index) { + CelestialObject *object = objects[object_index]; + CelestialObject *main_object = objects[main_object_index]; + + double periapsis_velocity_scalar = sqrt((G * main_object->mass * (1 + object->eccentricity)) / (object->semi_major_axis * (1 - object->eccentricity))); + periapsis_velocity_scalar += vector2_norm(vector2_substract(main_object->position, main_object->previous_position)); + + Vector2 r = vector2_normalize(vector2_create(object->position.y, -object->position.x)); + Vector2 periapsis_velocity = vector2_multiply(r, periapsis_velocity_scalar); + + object->position = vector2_add(object->position, main_object->previous_position); + + Vector2 new_position = vector2_add(object->position, periapsis_velocity); + Vector2 a = calculate_gravitational_acceleration(object_index, objects, objects_length); + new_position = vector2_add(new_position, vector2_multiply(a, 0.5)); + + object->previous_position = object->position; + object->position = new_position; +} + +void celestial_object_update(int32_t object_index, CelestialObject **objects, int32_t objects_length, double interval, double previous_interval) { + CelestialObject *object = objects[object_index]; + + double interval_multiplier = interval / previous_interval; + Vector2 new_position = vector2_add(object->position, vector2_multiply(vector2_substract(object->position, object->previous_position), interval_multiplier)); + Vector2 a = calculate_gravitational_acceleration(object_index, objects, objects_length); + new_position = vector2_add(new_position, vector2_multiply(a, pow(interval, 2))); + + object->previous_position = object->position; + object->position = new_position; + + celestial_object_update_previous_positions(object); +} + +Vector2 calculate_gravitational_acceleration(int32_t object_index, CelestialObject **objects, int32_t objects_length) { + Vector2 a = vector2_create_zero(); + + for (int32_t i = 0; i < objects_length; i += 1) { + if (i == object_index) { + continue; + } + + Vector2 r = vector2_substract((i < object_index) ? objects[i]->previous_position : objects[i]->position, objects[object_index]->position); + double a_scalar = G * objects[i]->mass * pow(pow(vector2_norm(r), 2), -1); + a = vector2_add(a, vector2_multiply(vector2_normalize(r), a_scalar)); } - return object->drawing_disc_radius; + return a; +} + +void celestial_object_update_previous_positions(CelestialObject *object) { + object->previous_positions[0] = object->position; + int32_t length = object->previous_positions_length; + + if (length > 1 && vector2_norm(vector2_substract(object->previous_positions[1], object->position)) < 1E9) { + return; + } + + for (int32_t j = (length == PREVIOUS_POSITIONS_MAXIMUM_LENGTH) ? length - 1 : length; j >= 2; j -= 1) { + object->previous_positions[j] = object->previous_positions[j - 1]; + } + + object->previous_positions[1] = object->position; + + if (length < PREVIOUS_POSITIONS_MAXIMUM_LENGTH) { + object->previous_positions_length += 1; + } } void celestial_object_draw(CelestialObject *object, Vector2 reference_frame, double zoom_factor) { int32_t color = object->drawing_color; glColor3ub((color & 0xFF0000) >> 16, (color & 0x00FF00) >> 8, (color & 0x0000FF) >> 0); - Vector2 scaled_position = scale_position(zoom_factor, object->current_position, reference_frame); + Vector2 scaled_position = scale_position(object->position, reference_frame, zoom_factor); draw_disc(scaled_position, get_zoomed_drawing_disc_radius(object, zoom_factor)); - if (strcmp(object->name, "Moon") != 0) { + if ((strcmp(object->name, "Moon") != 0 && strcmp(object->name, "Apollo 11") != 0)) { draw_scaled_lines(object->previous_positions, object->previous_positions_length, reference_frame, zoom_factor); } } +int32_t get_zoomed_drawing_disc_radius(CelestialObject *object, double zoom_factor) { + if (zoom_factor < 1) { + return object->drawing_disc_radius * zoom_factor; + } + + return object->drawing_disc_radius; +} + void celestial_object_draw_name(CelestialObject *object, Vector2 reference_frame, double zoom_factor) { - Vector2 scaled_position = scale_position(zoom_factor, object->current_position, reference_frame); + Vector2 scaled_position = scale_position(object->position, reference_frame, zoom_factor); if (strcmp(object->name, "Moon") == 0 && zoom_factor < 36) { return; } + if (strcmp(object->name, "Apollo 11") == 0 && zoom_factor < 2000) { + return; + } + int32_t zoomed_drawing_disc_radius = get_zoomed_drawing_disc_radius(object, zoom_factor); draw_text(object->name, vector2_add(scaled_position, vector2_create(zoomed_drawing_disc_radius + 5, -10))); } diff --git a/CelestialObject.h b/CelestialObject.h index 45553ebe0fa594135e4a0c71e923352534ea0fd9..d395fbdd387f7fe1a657b49f086e1f81ca6114e0 100644 --- a/CelestialObject.h +++ b/CelestialObject.h @@ -7,7 +7,7 @@ typedef struct CelestialObject { char name[100]; double mass; Vector2 previous_position; - Vector2 current_position; + Vector2 position; double semi_major_axis; double eccentricity; int32_t drawing_disc_radius; @@ -18,7 +18,12 @@ typedef struct CelestialObject { CelestialObject *celestial_object_create(char *name, double mass, double semi_major_axis, double eccentricity, int32_t drawing_disc_radius, int32_t drawing_color); void celestial_object_destroy(CelestialObject *object); +void celestial_object_first_update(int32_t object_index, CelestialObject **objects, int32_t objects_length, int32_t main_object_index); +void celestial_object_update(int32_t object_index, CelestialObject **objects, int32_t objects_length, double interval, double previous_interval); +Vector2 calculate_gravitational_acceleration(int32_t object_index, CelestialObject **objects, int32_t objects_length); +void celestial_object_update_previous_positions(CelestialObject *object); void celestial_object_draw(CelestialObject *object, Vector2 reference_frame, double zoom_factor); +int32_t get_zoomed_drawing_disc_radius(CelestialObject *object, double zoom_factor); void celestial_object_draw_name(CelestialObject *object, Vector2 reference_frame, double zoom_factor); #endif diff --git a/PlanetarySystem.c b/PlanetarySystem.c index 324fb4053e869c29eab59c85faf0cee6ba06a306..9a19bab2c071aeed7eaaa212fdfdb7cdad707e0f 100644 --- a/PlanetarySystem.c +++ b/PlanetarySystem.c @@ -14,56 +14,108 @@ const int32_t SCREEN_WIDTH = 800; const int32_t SCREEN_HEIGHT = 800; -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; +// Sun (https://nssdc.gsfc.nasa.gov/planetary/factsheet/sunfact.html) +const char SUN_NAME[] = "Sun"; +const double SUN_MASS = 1988500 * 1E24; +const double SUN_SEMI_MAJOR_AXIS = 0; +const double SUN_ECCENTRICITY = 0; +const int32_t SUN_DRAWING_RADIUS = 50; +const int32_t SUN_COLOR = 0xFFCC33; +// Mercury (https://nssdc.gsfc.nasa.gov/planetary/factsheet/mercuryfact.html) +const char MERCURY_NAME[] = "Mercury"; +const double MERCURY_MASS = 0.33010 * 1E24; +const double MERCURY_SEMI_MAJOR_AXIS = 57.909 * 1E9; +const double MERCURY_ECCENTRICITY = 0.2056; +const int32_t MERCURY_DRAWING_RADIUS = 10; +const int32_t MERCURY_COLOR = 0xDBCECA; +// Venus (https://nssdc.gsfc.nasa.gov/planetary/factsheet/venusfact.html) +const char VENUS_NAME[] = "Venus"; +const double VENUS_MASS = 4.8673 * 1E24; +const double VENUS_SEMI_MAJOR_AXIS = 108.209 * 1E9; +const double VENUS_ECCENTRICITY = 0.0067; +const int32_t VENUS_DRAWING_RADIUS = 20; +const int32_t VENUS_COLOR = 0x8B7D82; +// Earth (https://nssdc.gsfc.nasa.gov/planetary/factsheet/earthfact.html) +const char EARTH_NAME[] = "Earth"; +const double EARTH_MASS = 5.9722 * 1E24; +const double EARTH_SEMI_MAJOR_AXIS = 149.596 * 1E9; +const double EARTH_ECCENTRICITY = 0.0167; +const int32_t EARTH_DRAWING_RADIUS = 10; +const int32_t EARTH_COLOR = 0x6b93d6; +// Moon (https://nssdc.gsfc.nasa.gov/planetary/factsheet/moonfact.html) +const char MOON_NAME[] = "Moon"; +const double MOON_MASS = 0.07346 * 1E24; +const double MOON_SEMI_MAJOR_AXIS = 0.3844 * 1E9; +const double MOON_ECCENTRICITY = 0.0549; +const int32_t MOON_DRAWING_RADIUS = 5; +const int32_t MOON_COLOR = 0x7D7B67; +// Apollo 11 +const char APOLLO_11_NAME[] = "Apollo 11"; +const double APOLLO_11_MASS = 28800; +const double APOLLO_11_SEMI_MAJOR_AXIS = 1E7 * 2; +const double APOLLO_11_ECCENTRICITY = 0; +const int32_t APOLLO_11_DRAWING_RADIUS = 2; +const int32_t APOLLO_11_COLOR = 0x0B3D91; +// Mars (https://nssdc.gsfc.nasa.gov/planetary/factsheet/marsfact.html) +const char MARS_NAME[] = "Mars"; +const double MARS_MASS = 0.64169 * 1E24; +const double MARS_SEMI_MAJOR_AXIS = 227.923 * 1E9; +const double MARS_ECCENTRICITY = 0.0935; +const int32_t MARS_DRAWING_RADIUS = 12; +const int32_t MARS_COLOR = 0xBC2732; +// Jupiter (https://nssdc.gsfc.nasa.gov/planetary/factsheet/jupiterfact.html) +const char JUPITER_NAME[] = "Jupiter"; +const double JUPITER_MASS = 1898.13 * 1E24; +const double JUPITER_SEMI_MAJOR_AXIS = 778.570 * 1E9; +const double JUPITER_ECCENTRICITY = 0.0489; +const int32_t JUPITER_DRAWING_RADIUS = 30; +const int32_t JUPITER_COLOR = 0xD8CA9D; +// // Naboo +// const char JUPITER_NAME[] = "Jupiter"; +// const double JUPITER_MASS = 1898.13 * 1E24; +// const double JUPITER_SEMI_MAJOR_AXIS = 778.570 * 1E9; +// const double JUPITER_ECCENTRICITY = 0.0489; +// const int32_t JUPITER_DRAWING_RADIUS = 30; +// const int32_t JUPITER_COLOR = 0xD8CA9D; +// // Endor + +const int32_t OBJECTS_LENGTH = 10; PlanetarySystem *planetary_system_create() { - PlanetarySystem *system = (PlanetarySystem *)malloc(sizeof(PlanetarySystem)); - - system->objects_length = 9; - system->objects = (CelestialObject **)malloc(sizeof(PlanetarySystem *) * system->objects_length); - system->zoom_factor = 1; - system->reference_frame_index = 0; - system->show_names = true; - - // The moon is initialized with real life values. - // Naboo, Jupiter and Endor are all fake planets. - // Note that Jupitaire follows the orbit of Jupyter but its mass is different. - char names[][100] = {"Sun", "Mercury", "Venus", "Earth", "Mars", "Moon", "Naboo", "Jupitaire", "Endor"}; - double masses[] = {SUN_MASS, MERCURY_MASS, VENUS_MASS, EARTH_MASS, MARS_MASS, 7.34767309 * 1E22, 1000000, 1898.6 * 1E10, 1E23, 100 * 1E9}; - double semi_major_axes[] = {0, MERCURY_SEMI_MAJOR_AXIS, VENUS_SEMI_MAJOR_AXIS, EARTH_SEMI_MAJOR_AXIS, MARS_SEMI_MAJOR_AXIS, 384.399 * 1E6, 800.598262 * 1E9, 778.340821 * 1E9, 100 * 1E9}; - double eccentricities[] = {0, MERCURY_ECCENTRICITY, VENUS_ECCENTRICITY, EARTH_ECCENTRICITY, MARS_ECCENTRICITY, 0.0549, 0.8, 0.04839266, 0.34}; - double disc_radiuses[] = {50, 10, 20, 10, 12, 5, 12, 12, 12}; - int32_t colors[] = {0xFFCC33, 0xDBCECA, 0x8B7D82, 0x6b93d6, 0xBC2732, 0x7D7B67, 0x007700, 0x007700, 0x007700}; - - for (int32_t i = 0; i < system->objects_length; i += 1) { - CelestialObject *object = celestial_object_create(names[i], masses[i], semi_major_axes[i], eccentricities[i], disc_radiuses[i], colors[i]); - system->objects[i] = object; + PlanetarySystem *planetary_system = (PlanetarySystem *)malloc(sizeof(PlanetarySystem)); + + planetary_system->objects = (CelestialObject **)malloc(sizeof(PlanetarySystem *) * OBJECTS_LENGTH); + planetary_system->objects_length = OBJECTS_LENGTH; + planetary_system->reference_frame_index = 0; + planetary_system->zoom_factor = 1; + planetary_system->previous_interval = 1; + planetary_system->show_names = true; + + char *names[] = {(char *)SUN_NAME, (char *)MERCURY_NAME, (char *)VENUS_NAME, (char *)EARTH_NAME, (char *)MOON_NAME, (char *)APOLLO_11_NAME, (char *)MARS_NAME, (char *)JUPITER_NAME, "Naboo", "Endor"}; + double masses[] = {SUN_MASS, MERCURY_MASS, VENUS_MASS, EARTH_MASS, MOON_MASS, APOLLO_11_MASS, MARS_MASS, JUPITER_MASS, 1000000, 1E23}; + double semi_major_axes[] = {SUN_SEMI_MAJOR_AXIS, MERCURY_SEMI_MAJOR_AXIS, VENUS_SEMI_MAJOR_AXIS, EARTH_SEMI_MAJOR_AXIS, MOON_SEMI_MAJOR_AXIS, APOLLO_11_SEMI_MAJOR_AXIS, MARS_SEMI_MAJOR_AXIS, JUPITER_SEMI_MAJOR_AXIS, 800.598262 * 1E9, 100 * 1E9}; + double eccentricities[] = {SUN_ECCENTRICITY, MERCURY_ECCENTRICITY, VENUS_ECCENTRICITY, EARTH_ECCENTRICITY, MOON_ECCENTRICITY, APOLLO_11_ECCENTRICITY, MARS_ECCENTRICITY, JUPITER_ECCENTRICITY, 0.8, 0.34}; + int32_t drawing_disc_radiuses[] = {SUN_DRAWING_RADIUS, MERCURY_DRAWING_RADIUS, VENUS_DRAWING_RADIUS, EARTH_DRAWING_RADIUS, MOON_DRAWING_RADIUS, APOLLO_11_DRAWING_RADIUS, MARS_DRAWING_RADIUS, JUPITER_DRAWING_RADIUS, 12, 12}; + int32_t drawing_colors[] = {SUN_COLOR, MERCURY_COLOR, VENUS_COLOR, EARTH_COLOR, MOON_COLOR, APOLLO_11_COLOR, MARS_COLOR, JUPITER_COLOR, 0x007700, 0x007700}; + + for (int32_t i = 0; i < planetary_system->objects_length; i += 1) { + CelestialObject *object = celestial_object_create(names[i], masses[i], semi_major_axes[i], eccentricities[i], drawing_disc_radiuses[i], drawing_colors[i]); + planetary_system->objects[i] = object; } - system->objects[5]->current_position.x += system->objects[3]->current_position.x; - return system; + int32_t main_object_indexes[] = {0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 0}; + + for (int32_t i = 0; i < planetary_system->objects_length; i += 1) { + if (i != 0) { + celestial_object_first_update(i, planetary_system->objects, planetary_system->objects_length, main_object_indexes[i]); + } + } + + return planetary_system; } void planetary_system_destroy(PlanetarySystem *planetary_system) { + // Destruction of all objects. for (int32_t i = 0; i < planetary_system->objects_length; i += 1) { celestial_object_destroy(planetary_system->objects[i]); } @@ -72,104 +124,43 @@ void planetary_system_destroy(PlanetarySystem *planetary_system) { free(planetary_system); } -CelestialObject *planetary_system_get_star(PlanetarySystem *planetary_system) { - return planetary_system->objects[0]; -} - -Vector2 calculate_gravitational_acceleration(PlanetarySystem *planetary_system, int32_t object_index) { - Vector2 a = vector2_create_zero(); - - for (int32_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; +Vector2 planetary_system_get_reference_frame(PlanetarySystem *planetary_system) { + CelestialObject *object_reference_frame = planetary_system->objects[planetary_system->reference_frame_index]; + return object_reference_frame->position; } void planetary_system_update(PlanetarySystem *planetary_system, double interval) { for (int32_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) { - 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); - - new_position = vector2_add(current_position, vector2_multiply(periapsis_velocity, interval)); - Vector2 a = calculate_gravitational_acceleration(planetary_system, i); - new_position = vector2_add(new_position, vector2_multiply(a, 0.5 * pow(interval, 2))); - } else { - 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(interval, 2))); - } - - object->previous_position = object->current_position; - object->current_position = new_position; - - object->previous_positions[0] = object->current_position; - - int32_t length = object->previous_positions_length; - - if (length > 1 && vector2_norm(vector2_substract(object->previous_positions[1], object->current_position)) < 1E9) - continue; - for (int32_t j = (length == 200) ? length - 1 : length; j >= 2; j -= 1) { - object->previous_positions[j] = object->previous_positions[j - 1]; - } - - object->previous_positions[1] = object->current_position; - - if (length < 200) { - object->previous_positions_length += 1; - } + celestial_object_update(i, planetary_system->objects, planetary_system->objects_length, interval, planetary_system->previous_interval); } -} -Vector2 planetary_system_get_reference_frame(PlanetarySystem *system) { - CelestialObject *object_reference_frame = system->objects[system->reference_frame_index]; - return object_reference_frame->current_position; + planetary_system->previous_interval = interval; } -void planetary_system_draw(PlanetarySystem *system) { - Vector2 reference_frame = planetary_system_get_reference_frame(system); +void planetary_system_draw(PlanetarySystem *planetary_system) { + Vector2 reference_frame = planetary_system_get_reference_frame(planetary_system); - for (int32_t i = 0; i < system->objects_length; i += 1) { - CelestialObject *object = system->objects[i]; - celestial_object_draw(object, reference_frame, system->zoom_factor); + for (int32_t i = 0; i < planetary_system->objects_length; i += 1) { + CelestialObject *object = planetary_system->objects[i]; + celestial_object_draw(object, reference_frame, planetary_system->zoom_factor); } - planetary_system_draw_object_names(system); + // Drawing the names of the objects afterwards so that they are not under the rest of the drawings. + planetary_system_draw_object_names(planetary_system); - char text[200]; - sprintf(text, "Focused Object : %s", system->objects[system->reference_frame_index]->name); + char text[100]; + sprintf(text, "Focused Object : %s", planetary_system->objects[planetary_system->reference_frame_index]->name); draw_text(text, vector2_create(5, 15)); } -void planetary_system_draw_object_names(PlanetarySystem *system) { - if (!system->show_names) { +void planetary_system_draw_object_names(PlanetarySystem *planetary_system) { + if (!planetary_system->show_names) { return; } - Vector2 reference_frame = planetary_system_get_reference_frame(system); + Vector2 reference_frame = planetary_system_get_reference_frame(planetary_system); - for (int32_t i = 0; i < system->objects_length; i += 1) { - celestial_object_draw_name(system->objects[i], reference_frame, system->zoom_factor); + for (int32_t i = 0; i < planetary_system->objects_length; i += 1) { + celestial_object_draw_name(planetary_system->objects[i], reference_frame, planetary_system->zoom_factor); } } diff --git a/PlanetarySystem.h b/PlanetarySystem.h index 759638c41ba84e13461c86cbf16ea03dbe107e7c..66d4959cdd63f15a2b37d13f1d31d3972bfbe3c3 100644 --- a/PlanetarySystem.h +++ b/PlanetarySystem.h @@ -10,18 +10,19 @@ extern const int32_t SCREEN_WIDTH; extern const int32_t SCREEN_HEIGHT; typedef struct PlanetarySystem { - int32_t objects_length; CelestialObject **objects; - double zoom_factor; + int32_t objects_length; int32_t reference_frame_index; + double zoom_factor; + double previous_interval; bool show_names; } PlanetarySystem; PlanetarySystem *planetary_system_create(); void planetary_system_destroy(PlanetarySystem *planetary_system); +Vector2 planetary_system_get_reference_frame(PlanetarySystem *planetary_system); void planetary_system_update(PlanetarySystem *planetary_system, double interval); -Vector2 planetary_system_get_reference_frame(PlanetarySystem *system); void planetary_system_draw(PlanetarySystem *planetary_system); -void planetary_system_draw_object_names(PlanetarySystem *system); +void planetary_system_draw_object_names(PlanetarySystem *planetary_system); #endif diff --git a/README.md b/README.md index 332ccb2da867e54417fdd2f3073b4882cc0b3eb2..cb7494df7b8e0b0214fb857ca5965448bf5e3be4 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ Représente un corps céleste tel que : Une planète ou une étoile. typedef struct CelestialObject { double mass; Vector2 previous_position; - Vector2 current_position; + Vector2 position; double semi_major_axis; double eccentricity; uint32_t drawing_disc_radius; diff --git a/drawing.c b/drawing.c index 7d5c3115fba9fb3de33d9a6222309ac526da341b..60d05d0c74635b68a4611a6857e95e53f00fb02f 100644 --- a/drawing.c +++ b/drawing.c @@ -8,51 +8,58 @@ #include "PlanetarySystem.h" #include "Vector2.h" +const int64_t PLANETARY_SYSTEM_WIDTH = 280 * 1E9; +const double LINE_WIDTH = 4.0; +const int32_t FONT_HEIGHT = 15; + +Vector2 scale_position(Vector2 position, Vector2 reference_frame, double zoom_factor) { + Vector2 unscaled_position = vector2_substract(position, reference_frame); + unscaled_position = vector2_multiply(unscaled_position, zoom_factor); + + Vector2 scaled_position = vector2_multiply(unscaled_position, 1.0 / PLANETARY_SYSTEM_WIDTH); + scaled_position = vector2_fit_canvas(scaled_position, SCREEN_WIDTH, SCREEN_HEIGHT); + return scaled_position; +} + void draw_disc(Vector2 position, int32_t radius) { glBegin(GL_POLYGON); + for (int32_t i = 0; i < 360; i += 1) { - double theta = i * 3.1415 / 180; + double theta = i * 3.14159265 / 180; double x = position.x + radius * cos(theta); double y = position.y + radius * sin(theta); glVertex2f(x, y); } + glEnd(); } -void draw_line(Vector2 a, Vector2 b) { +void draw_line(Vector2 p1, Vector2 p2) { glBegin(GL_LINES); - glVertex2f(a.x, a.y); - glVertex2f(b.x, b.y); + glVertex2f(p1.x, p1.y); + glVertex2f(p2.x, p2.y); glEnd(); } void draw_scaled_lines(Vector2 *points, int32_t points_length, Vector2 reference_frame, double zoom_factor) { - glLineWidth(4.0); + glLineWidth(LINE_WIDTH); - if (zoom_factor < 1) - glLineWidth(4.0 * zoom_factor); + if (zoom_factor < 1) { + glLineWidth(LINE_WIDTH * zoom_factor); + } - for (int32_t j = 0; j < points_length - 1; j += 1) { - Vector2 p1 = scale_position(zoom_factor, points[j], reference_frame); - Vector2 p2 = scale_position(zoom_factor, points[j + 1], reference_frame); + for (int32_t i = 0; i < points_length - 1; i += 1) { + Vector2 p1 = scale_position(points[i], reference_frame, zoom_factor); + Vector2 p2 = scale_position(points[i + 1], reference_frame, zoom_factor); draw_line(p1, p2); } } void draw_text(char *text, Vector2 position) { glColor3f(1.0, 1.0, 1.0); - glRasterPos2f(position.x, position.y + 15); + glRasterPos2f(position.x, position.y + FONT_HEIGHT); - for (int32_t i = 0; i < (int32_t)strlen(text); i++) { + for (int32_t i = 0; i < (int32_t)strlen(text); i += 1) { glutBitmapCharacter(GLUT_BITMAP_9_BY_15, text[i]); } } - -Vector2 scale_position(double zoom_factor, Vector2 object_position, Vector2 reference_frame_position) { - Vector2 unscaled_position = vector2_substract(object_position, reference_frame_position); - unscaled_position = vector2_multiply(unscaled_position, zoom_factor); - - Vector2 scaled_position = vector2_multiply(unscaled_position, 1.0 / (280 * 1E9)); - scaled_position = vector2_fit_canvas(scaled_position, SCREEN_WIDTH, SCREEN_HEIGHT); - return scaled_position; -} diff --git a/drawing.h b/drawing.h index 45a772df8ef0e340fca8963c984e1001c19fee1d..955ea7c1ee606a63976a76cbd630265f99afe352 100644 --- a/drawing.h +++ b/drawing.h @@ -5,10 +5,10 @@ #include "Vector2.h" +Vector2 scale_position(Vector2 position, Vector2 reference_frame, double zoom_factor); void draw_disc(Vector2 position, int32_t radius); -void draw_line(Vector2 a, Vector2 b); +void draw_line(Vector2 p1, Vector2 p2); void draw_scaled_lines(Vector2 *points, int32_t points_length, Vector2 reference_frame, double zoom_factor); void draw_text(char *text, Vector2 position); -Vector2 scale_position(double zoom_factor, Vector2 object_position, Vector2 reference_frame_position); #endif diff --git a/main.c b/main.c index 44065841ff3d510863ba4d300c9264c148c35924..de71c1c353483305f98991ba7390a49e7494e4ce 100644 --- a/main.c +++ b/main.c @@ -30,8 +30,8 @@ const int32_t DEFAULT_SIMULATION_SPEED_IN_SECONDS = DEFAULT_SIMULATION_SPEED_IN_ // Maximum time that elapses in the planetary system at each call of the planetary_system_update function, this value must be small enough for the planetary system to work. const int32_t PLANETARY_SYSTEM_INTERVAL = 100; -const unsigned char KEYBOARD_ESCAPE_KEY = 27; -const unsigned char KEYBOARD_T_KEY = 't'; +#define GLUT_KEY_ESCAPE 27 +#define GLUT_KEY_T 116 // https://stackoverflow.com/questions/3417837/what-is-the-best-way-to-suppress-a-unused-variable-x-warning #ifdef UNUSED @@ -100,12 +100,12 @@ void draw_timer() { } void handle_keyboard_input(unsigned char key, int UNUSED(x), int UNUSED(y)) { - if (key == KEYBOARD_ESCAPE_KEY) { + if (key == GLUT_KEY_ESCAPE) { glutLeaveMainLoop(); return; } - if (key == KEYBOARD_T_KEY) { + if (key == GLUT_KEY_T) { planetary_system->show_names = !planetary_system->show_names; } }