diff --git a/src/CelestialObject.c b/src/CelestialObject.c index 363c685435d50afe382cbc9d28d2c7f148c5fe09..14245a4a39381d81ccf56718628c6865cf7e2e54 100644 --- a/src/CelestialObject.c +++ b/src/CelestialObject.c @@ -17,6 +17,7 @@ CelestialObject *celestial_object_create(char *name, double mass, double semi_ma object->mass = mass; object->previous_position = vector2_create_zero(); + // Calculates the position at the periapsis. double periapsis = semi_major_axis * (1 - eccentricity); object->position = vector2_create(-periapsis, 0); @@ -50,10 +51,12 @@ Vector2 calculate_gravitational_acceleration(int32_t object_index, CelestialObje for (int32_t i = 0; i < objects_length; i += 1) { if (i == object_index) { + // All except himself. continue; } Vector2 r = vector2_substract((i < object_index) ? objects[i]->previous_position : objects[i]->position, objects[object_index]->position); + // Calculates the acceleration. 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)); } @@ -65,16 +68,21 @@ void celestial_object_first_update(int32_t object_index, CelestialObject **objec 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)); + // Speed at the periapsis. + double periapsis_speed_scalar = sqrt((G * main_object->mass * (1 + object->eccentricity)) / (object->semi_major_axis * (1 - object->eccentricity))); + // Adds the speed of the main object. + periapsis_speed_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); + Vector2 periapsis_velocity = vector2_multiply(r, periapsis_speed_scalar); + // Adds the position of the main object. object->position = vector2_add(object->position, main_object->previous_position); + // Calculates the new position of the object according to its velocity at periapsis. Vector2 new_position = vector2_add(object->position, periapsis_velocity); Vector2 a = calculate_gravitational_acceleration(object_index, objects, objects_length); + // Adds the acceleration. new_position = vector2_add(new_position, vector2_multiply(a, 0.5)); object->previous_position = object->position; @@ -85,8 +93,10 @@ void celestial_object_update(int32_t object_index, CelestialObject **objects, in CelestialObject *object = objects[object_index]; double interval_multiplier = interval / previous_interval; + // Calculates its new position in relation to its previous and current position. 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); + // Adds the acceleration. new_position = vector2_add(new_position, vector2_multiply(a, pow(interval, 2))); object->previous_position = object->position; @@ -96,17 +106,21 @@ void celestial_object_update(int32_t object_index, CelestialObject **objects, in } void celestial_object_update_previous_positions(CelestialObject *object) { + // Index 0 is always equal to the position of the 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) { + // If the distance between the position of the object and the point at index 1 is smaller than 1E9 then the position of the object is not added. return; } + // Shifts all points to the right from index 1. 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]; } + // Sets the position of the object to index 1. object->previous_positions[1] = object->position; if (length < PREVIOUS_POSITIONS_MAXIMUM_LENGTH) { @@ -116,11 +130,13 @@ void celestial_object_update_previous_positions(CelestialObject *object) { void celestial_object_draw(CelestialObject *object, Vector2 reference_frame, double zoom_factor) { int32_t color = object->drawing_color; + // Changes the color by decomposing the hexadecimal. glColor3ub((color & 0xFF0000) >> 16, (color & 0x00FF00) >> 8, (color & 0x0000FF) >> 0); Vector2 scaled_position = scale_position(object->position, reference_frame, zoom_factor); draw_disc(scaled_position, get_zoomed_drawing_disc_radius(object, zoom_factor)); + // Condition hard coded (should be dynamic to be cleaner). 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); } @@ -129,14 +145,17 @@ void celestial_object_draw(CelestialObject *object, Vector2 reference_frame, dou void celestial_object_draw_name(CelestialObject *object, Vector2 reference_frame, double zoom_factor) { Vector2 scaled_position = scale_position(object->position, reference_frame, zoom_factor); + // Condition hard coded (should be dynamic to be cleaner). if (strcmp(object->name, "Moon") == 0 && zoom_factor < 36) { return; } + // Condition hard coded (should be dynamic to be cleaner). 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); + // Draws the text just to the right of the object. draw_text(object->name, vector2_add(scaled_position, vector2_create(zoomed_drawing_disc_radius + 5, -10))); } diff --git a/src/PlanetarySystem.c b/src/PlanetarySystem.c index bccc01aeabe188d2d3eadba3ed5810309e4e409a..4ca32d84a2f81a2c59b9a4301d97608f61cf411c 100644 --- a/src/PlanetarySystem.c +++ b/src/PlanetarySystem.c @@ -92,6 +92,9 @@ const double CORUSCANT_ECCENTRICITY = 0.4675; const int32_t CORUSCANT_DRAWING_RADIUS = 35; const int32_t CORUSCANT_COLOR = 0x5C4033; +const int32_t SUN_INDEX = 0; +const int32_t EARTH_INDEX = 3; +const int32_t MOON_INDEX = 4; const int32_t OBJECTS_LENGTH = 11; PlanetarySystem *planetary_system_create() { @@ -116,8 +119,9 @@ PlanetarySystem *planetary_system_create() { planetary_system->objects[i] = object; } - int32_t main_object_indexes[] = {0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 0}; + int32_t main_object_indexes[] = {SUN_INDEX, SUN_INDEX, SUN_INDEX, SUN_INDEX, EARTH_INDEX, MOON_INDEX, SUN_INDEX, SUN_INDEX, SUN_INDEX, SUN_INDEX, SUN_INDEX}; + // Calculates the first position for all objects. 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]); @@ -128,7 +132,7 @@ PlanetarySystem *planetary_system_create() { } void planetary_system_destroy(PlanetarySystem *planetary_system) { - // Destruction of all objects. + // Destroys all objects. for (int32_t i = 0; i < planetary_system->objects_length; i += 1) { celestial_object_destroy(planetary_system->objects[i]); } @@ -143,6 +147,7 @@ Vector2 planetary_system_get_reference_frame(PlanetarySystem *planetary_system) } void planetary_system_update(PlanetarySystem *planetary_system, double interval) { + // Updates all objects. for (int32_t i = 1; i < planetary_system->objects_length; i += 1) { celestial_object_update(i, planetary_system->objects, planetary_system->objects_length, interval, planetary_system->previous_interval); } @@ -153,6 +158,7 @@ void planetary_system_update(PlanetarySystem *planetary_system, double interval) void planetary_system_draw(PlanetarySystem *planetary_system) { Vector2 reference_frame = planetary_system_get_reference_frame(planetary_system); + // Draws all objects. 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); diff --git a/src/drawing.c b/src/drawing.c index 60d05d0c74635b68a4611a6857e95e53f00fb02f..48dd049d33e5b60ee7972b120e8da25c4f1c01f3 100644 --- a/src/drawing.c +++ b/src/drawing.c @@ -14,8 +14,10 @@ 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); + // Applies the zoom. unscaled_position = vector2_multiply(unscaled_position, zoom_factor); + // Converts the position in relation to the width of the planetary system. 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; @@ -48,6 +50,7 @@ void draw_scaled_lines(Vector2 *points, int32_t points_length, Vector2 reference glLineWidth(LINE_WIDTH * zoom_factor); } + // Draws the lines between all the points. 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); diff --git a/src/main.c b/src/main.c index 87ba16c7a1249635a0b96ea3349101e59d824551..404a7a9cd94adc9a2bc94c5e1eab3acc03619930 100644 --- a/src/main.c +++ b/src/main.c @@ -75,9 +75,11 @@ int64_t get_current_time() { void update() { int64_t current_time = get_current_time(); int64_t elapsed_time = current_time - previous_time; + // Time that must elapse in the simulation at this frame. double remaining_time = (double)elapsed_time / ONE_SECOND_IN_MICROSECONDS * simulation_speed; while (remaining_time >= PLANETARY_SYSTEM_INTERVAL) { + // Move the planetary system forward by PLANETARY_SYSTEM_INTERVAL seconds while there is still time to go. planetary_system_update(planetary_system, PLANETARY_SYSTEM_INTERVAL); remaining_time -= PLANETARY_SYSTEM_INTERVAL; }