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

Comments

parent 379eb58b
Branches
No related tags found
No related merge requests found
......@@ -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)));
}
......@@ -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);
......
......@@ -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);
......
......@@ -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;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment