Skip to content
Snippets Groups Projects
Commit 85339a8e authored by florian.burgener's avatar florian.burgener
Browse files

Comments

parent 379eb58b
No related branches found
No related tags found
No related merge requests found
...@@ -17,6 +17,7 @@ CelestialObject *celestial_object_create(char *name, double mass, double semi_ma ...@@ -17,6 +17,7 @@ CelestialObject *celestial_object_create(char *name, double mass, double semi_ma
object->mass = mass; object->mass = mass;
object->previous_position = vector2_create_zero(); object->previous_position = vector2_create_zero();
// Calculates the position at the periapsis.
double periapsis = semi_major_axis * (1 - eccentricity); double periapsis = semi_major_axis * (1 - eccentricity);
object->position = vector2_create(-periapsis, 0); object->position = vector2_create(-periapsis, 0);
...@@ -50,10 +51,12 @@ Vector2 calculate_gravitational_acceleration(int32_t object_index, CelestialObje ...@@ -50,10 +51,12 @@ Vector2 calculate_gravitational_acceleration(int32_t object_index, CelestialObje
for (int32_t i = 0; i < objects_length; i += 1) { for (int32_t i = 0; i < objects_length; i += 1) {
if (i == object_index) { if (i == object_index) {
// All except himself.
continue; continue;
} }
Vector2 r = vector2_substract((i < object_index) ? objects[i]->previous_position : objects[i]->position, objects[object_index]->position); 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); 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)); 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 ...@@ -65,16 +68,21 @@ void celestial_object_first_update(int32_t object_index, CelestialObject **objec
CelestialObject *object = objects[object_index]; CelestialObject *object = objects[object_index];
CelestialObject *main_object = objects[main_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))); // Speed at the periapsis.
periapsis_velocity_scalar += vector2_norm(vector2_substract(main_object->position, main_object->previous_position)); 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 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); 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 new_position = vector2_add(object->position, periapsis_velocity);
Vector2 a = calculate_gravitational_acceleration(object_index, objects, objects_length); Vector2 a = calculate_gravitational_acceleration(object_index, objects, objects_length);
// Adds the acceleration.
new_position = vector2_add(new_position, vector2_multiply(a, 0.5)); new_position = vector2_add(new_position, vector2_multiply(a, 0.5));
object->previous_position = object->position; object->previous_position = object->position;
...@@ -85,8 +93,10 @@ void celestial_object_update(int32_t object_index, CelestialObject **objects, in ...@@ -85,8 +93,10 @@ void celestial_object_update(int32_t object_index, CelestialObject **objects, in
CelestialObject *object = objects[object_index]; CelestialObject *object = objects[object_index];
double interval_multiplier = interval / previous_interval; 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 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); 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))); new_position = vector2_add(new_position, vector2_multiply(a, pow(interval, 2)));
object->previous_position = object->position; object->previous_position = object->position;
...@@ -96,17 +106,21 @@ void celestial_object_update(int32_t object_index, CelestialObject **objects, in ...@@ -96,17 +106,21 @@ void celestial_object_update(int32_t object_index, CelestialObject **objects, in
} }
void celestial_object_update_previous_positions(CelestialObject *object) { 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; object->previous_positions[0] = object->position;
int32_t length = object->previous_positions_length; int32_t length = object->previous_positions_length;
if (length > 1 && vector2_norm(vector2_substract(object->previous_positions[1], object->position)) < 1E9) { 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; 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) { 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[j] = object->previous_positions[j - 1];
} }
// Sets the position of the object to index 1.
object->previous_positions[1] = object->position; object->previous_positions[1] = object->position;
if (length < PREVIOUS_POSITIONS_MAXIMUM_LENGTH) { if (length < PREVIOUS_POSITIONS_MAXIMUM_LENGTH) {
...@@ -116,11 +130,13 @@ void celestial_object_update_previous_positions(CelestialObject *object) { ...@@ -116,11 +130,13 @@ void celestial_object_update_previous_positions(CelestialObject *object) {
void celestial_object_draw(CelestialObject *object, Vector2 reference_frame, double zoom_factor) { void celestial_object_draw(CelestialObject *object, Vector2 reference_frame, double zoom_factor) {
int32_t color = object->drawing_color; int32_t color = object->drawing_color;
// Changes the color by decomposing the hexadecimal.
glColor3ub((color & 0xFF0000) >> 16, (color & 0x00FF00) >> 8, (color & 0x0000FF) >> 0); glColor3ub((color & 0xFF0000) >> 16, (color & 0x00FF00) >> 8, (color & 0x0000FF) >> 0);
Vector2 scaled_position = scale_position(object->position, reference_frame, zoom_factor); Vector2 scaled_position = scale_position(object->position, reference_frame, zoom_factor);
draw_disc(scaled_position, get_zoomed_drawing_disc_radius(object, 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)) { 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); 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 ...@@ -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) { void celestial_object_draw_name(CelestialObject *object, Vector2 reference_frame, double zoom_factor) {
Vector2 scaled_position = scale_position(object->position, reference_frame, 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) { if (strcmp(object->name, "Moon") == 0 && zoom_factor < 36) {
return; return;
} }
// Condition hard coded (should be dynamic to be cleaner).
if (strcmp(object->name, "Apollo 11") == 0 && zoom_factor < 2000) { if (strcmp(object->name, "Apollo 11") == 0 && zoom_factor < 2000) {
return; return;
} }
int32_t zoomed_drawing_disc_radius = get_zoomed_drawing_disc_radius(object, zoom_factor); 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))); draw_text(object->name, vector2_add(scaled_position, vector2_create(zoomed_drawing_disc_radius + 5, -10)));
} }
...@@ -92,6 +92,9 @@ const double CORUSCANT_ECCENTRICITY = 0.4675; ...@@ -92,6 +92,9 @@ const double CORUSCANT_ECCENTRICITY = 0.4675;
const int32_t CORUSCANT_DRAWING_RADIUS = 35; const int32_t CORUSCANT_DRAWING_RADIUS = 35;
const int32_t CORUSCANT_COLOR = 0x5C4033; 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; const int32_t OBJECTS_LENGTH = 11;
PlanetarySystem *planetary_system_create() { PlanetarySystem *planetary_system_create() {
...@@ -116,8 +119,9 @@ PlanetarySystem *planetary_system_create() { ...@@ -116,8 +119,9 @@ PlanetarySystem *planetary_system_create() {
planetary_system->objects[i] = object; 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) { for (int32_t i = 0; i < planetary_system->objects_length; i += 1) {
if (i != 0) { if (i != 0) {
celestial_object_first_update(i, planetary_system->objects, planetary_system->objects_length, main_object_indexes[i]); celestial_object_first_update(i, planetary_system->objects, planetary_system->objects_length, main_object_indexes[i]);
...@@ -128,7 +132,7 @@ PlanetarySystem *planetary_system_create() { ...@@ -128,7 +132,7 @@ PlanetarySystem *planetary_system_create() {
} }
void planetary_system_destroy(PlanetarySystem *planetary_system) { 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) { for (int32_t i = 0; i < planetary_system->objects_length; i += 1) {
celestial_object_destroy(planetary_system->objects[i]); celestial_object_destroy(planetary_system->objects[i]);
} }
...@@ -143,6 +147,7 @@ Vector2 planetary_system_get_reference_frame(PlanetarySystem *planetary_system) ...@@ -143,6 +147,7 @@ Vector2 planetary_system_get_reference_frame(PlanetarySystem *planetary_system)
} }
void planetary_system_update(PlanetarySystem *planetary_system, double interval) { void planetary_system_update(PlanetarySystem *planetary_system, double interval) {
// Updates all objects.
for (int32_t i = 1; i < planetary_system->objects_length; i += 1) { 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); 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) ...@@ -153,6 +158,7 @@ void planetary_system_update(PlanetarySystem *planetary_system, double interval)
void planetary_system_draw(PlanetarySystem *planetary_system) { void planetary_system_draw(PlanetarySystem *planetary_system) {
Vector2 reference_frame = planetary_system_get_reference_frame(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) { for (int32_t i = 0; i < planetary_system->objects_length; i += 1) {
CelestialObject *object = planetary_system->objects[i]; CelestialObject *object = planetary_system->objects[i];
celestial_object_draw(object, reference_frame, planetary_system->zoom_factor); celestial_object_draw(object, reference_frame, planetary_system->zoom_factor);
......
...@@ -14,8 +14,10 @@ const int32_t FONT_HEIGHT = 15; ...@@ -14,8 +14,10 @@ const int32_t FONT_HEIGHT = 15;
Vector2 scale_position(Vector2 position, Vector2 reference_frame, double zoom_factor) { Vector2 scale_position(Vector2 position, Vector2 reference_frame, double zoom_factor) {
Vector2 unscaled_position = vector2_substract(position, reference_frame); Vector2 unscaled_position = vector2_substract(position, reference_frame);
// Applies the zoom.
unscaled_position = vector2_multiply(unscaled_position, zoom_factor); 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); Vector2 scaled_position = vector2_multiply(unscaled_position, 1.0 / PLANETARY_SYSTEM_WIDTH);
scaled_position = vector2_fit_canvas(scaled_position, SCREEN_WIDTH, SCREEN_HEIGHT); scaled_position = vector2_fit_canvas(scaled_position, SCREEN_WIDTH, SCREEN_HEIGHT);
return scaled_position; return scaled_position;
...@@ -48,6 +50,7 @@ void draw_scaled_lines(Vector2 *points, int32_t points_length, Vector2 reference ...@@ -48,6 +50,7 @@ void draw_scaled_lines(Vector2 *points, int32_t points_length, Vector2 reference
glLineWidth(LINE_WIDTH * zoom_factor); glLineWidth(LINE_WIDTH * zoom_factor);
} }
// Draws the lines between all the points.
for (int32_t i = 0; i < points_length - 1; i += 1) { for (int32_t i = 0; i < points_length - 1; i += 1) {
Vector2 p1 = scale_position(points[i], reference_frame, zoom_factor); Vector2 p1 = scale_position(points[i], reference_frame, zoom_factor);
Vector2 p2 = scale_position(points[i + 1], reference_frame, zoom_factor); Vector2 p2 = scale_position(points[i + 1], reference_frame, zoom_factor);
......
...@@ -75,9 +75,11 @@ int64_t get_current_time() { ...@@ -75,9 +75,11 @@ int64_t get_current_time() {
void update() { void update() {
int64_t current_time = get_current_time(); int64_t current_time = get_current_time();
int64_t elapsed_time = current_time - previous_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; double remaining_time = (double)elapsed_time / ONE_SECOND_IN_MICROSECONDS * simulation_speed;
while (remaining_time >= PLANETARY_SYSTEM_INTERVAL) { 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); planetary_system_update(planetary_system, PLANETARY_SYSTEM_INTERVAL);
remaining_time -= PLANETARY_SYSTEM_INTERVAL; remaining_time -= PLANETARY_SYSTEM_INTERVAL;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment