diff --git a/CelestialObject.c b/CelestialObject.c
index 7f51146a9250a8bedf0c7a3dd57f6f663ee8c45e..61d9cff28abe6bdd2e17fa00d133a84536a677ae 100644
--- a/CelestialObject.c
+++ b/CelestialObject.c
@@ -6,8 +6,7 @@
 
 #include "drawing.h"
 
-#define G 6.67e-11
-#define SUN_MASS 1.989e30
+const int32_t PREVIOUS_POSITIONS_LENGTH = 200;
 
 CelestialObject *celestial_object_create(char *name, double mass, double semi_major_axis, double eccentricity, uint32_t drawing_disc_radius, uint32_t drawing_color) {
     CelestialObject *object = (CelestialObject *)malloc(sizeof(CelestialObject));
@@ -21,39 +20,34 @@ CelestialObject *celestial_object_create(char *name, double mass, double semi_ma
 
     object->semi_major_axis = semi_major_axis;
     object->eccentricity = eccentricity;
+
     object->drawing_disc_radius = drawing_disc_radius;
     object->drawing_color = drawing_color;
-    object->points = (Vector2 *)malloc(sizeof(Vector2) * 200);
-    object->points_length = 0;
+
+    object->previous_positions = (Vector2 *)malloc(sizeof(Vector2) * PREVIOUS_POSITIONS_LENGTH);
+    object->previous_positions_length = 0;
 
     return object;
 }
 
-void celestial_object_draw(CelestialObject *object, Vector2 reference_frame, double zoom_factor) {
-    Vector2 scaled_position = scale_position(zoom_factor, object->current_position, reference_frame);
+uint32_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(CelestialObject *object, Vector2 reference_frame, double zoom_factor) {
     uint32_t color = object->drawing_color;
     glColor3ub((color & 0xFF0000) >> 16, (color & 0x00FF00) >> 8, (color & 0x0000FF) >> 0);
 
-    if (zoom_factor < 1)
-        draw_disc(scaled_position, object->drawing_disc_radius * zoom_factor);
-    else
-        draw_disc(scaled_position, object->drawing_disc_radius);
+    Vector2 scaled_position = scale_position(zoom_factor, object->current_position, reference_frame);
+    draw_disc(scaled_position, get_zoomed_drawing_disc_radius(object, zoom_factor));
 
     if (strcmp(object->name, "Moon") != 0) {
-        if (zoom_factor < 1)
-            glLineWidth(4.0 * zoom_factor);
-        else
-            glLineWidth(4.0);
-
-        for (int32_t j = 0; j < object->points_length - 1; j += 1) {
-            Vector2 p1 = scale_position(zoom_factor, object->points[j], reference_frame);
-            Vector2 p2 = scale_position(zoom_factor, object->points[j + 1], reference_frame);
-            draw_line(p1, p2);
-        }
+        draw_scaled_lines(object->previous_positions, object->previous_positions_length, reference_frame, zoom_factor);
     }
-
-    // celestial_object_draw_name(object, reference_frame,zoom_factor);
 }
 
 void celestial_object_draw_name(CelestialObject *object, Vector2 reference_frame, double zoom_factor) {
@@ -63,11 +57,6 @@ void celestial_object_draw_name(CelestialObject *object, Vector2 reference_frame
         return;
     }
 
-    uint32_t drawing_disc_radius = object->drawing_disc_radius;
-
-    if (zoom_factor < 1) {
-        drawing_disc_radius *= zoom_factor;
-    }
-
-    draw_text(object->name, vector2_add(scaled_position, vector2_create(drawing_disc_radius + 8, 7)));
+    uint32_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 bd7f28ff76ec05906620069a936af51ff6a1ddf9..55925d7be25c629127c965a82b87a3ead343b938 100644
--- a/CelestialObject.h
+++ b/CelestialObject.h
@@ -4,6 +4,7 @@
 #include "Vector2.h"
 
 typedef struct CelestialObject {
+    char name[100];
     double mass;
     Vector2 previous_position;
     Vector2 current_position;
@@ -11,9 +12,8 @@ typedef struct CelestialObject {
     double eccentricity;
     uint32_t drawing_disc_radius;
     uint32_t drawing_color;
-    Vector2 *points;
-    int32_t points_length;
-    char name[100];
+    Vector2 *previous_positions;
+    int32_t previous_positions_length;
 } CelestialObject;
 
 CelestialObject *celestial_object_create(char *name, double mass, double semi_major_axis, double eccentricity, uint32_t drawing_disc_radius, uint32_t drawing_color);
diff --git a/Makefile b/Makefile
index 25019ee4e9b4d46db44836a9318bc24ceab3c652..eecedfe98605be8b4627f643a98ef99a6616db71 100644
--- a/Makefile
+++ b/Makefile
@@ -19,4 +19,4 @@ $(TARGET): main.o Vector2.o CelestialObject.o PlanetarySystem.o drawing.o
 	$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
 
 clean:
-	-rm -f *.o $(TARGET)
+	-rm -f *.o $(TARGET) $(TARGET).exe
diff --git a/PlanetarySystem.c b/PlanetarySystem.c
index 3418957a16b34597a8739f6a23078f113816279e..85d4983f01502b27f8c560d8ab85102cd850e20f 100644
--- a/PlanetarySystem.c
+++ b/PlanetarySystem.c
@@ -2,6 +2,7 @@
 
 #include <GL/glut.h>
 #include <math.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -10,8 +11,8 @@
 #include "Vector2.h"
 #include "drawing.h"
 
-const uint32_t SCREEN_WIDTH = 800;
-const uint32_t SCREEN_HEIGHT = 800;
+const int32_t SCREEN_WIDTH = 800;
+const int32_t SCREEN_HEIGHT = 800;
 
 const double G = 6.67430 * 1E-11;
 
@@ -40,7 +41,8 @@ PlanetarySystem *planetary_system_create() {
     system->objects_length = 9;
     system->objects = (CelestialObject **)malloc(sizeof(PlanetarySystem *) * system->objects_length);
     system->zoom_factor = 1;
-    system->reference_frame_object_index = 0;
+    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.
@@ -113,36 +115,52 @@ void planetary_system_update(PlanetarySystem *planetary_system, double interval)
         object->previous_position = object->current_position;
         object->current_position = new_position;
 
-        int32_t length = object->points_length;
+        object->previous_positions[0] = object->current_position;
 
-        if (length > 0 && vector2_norm(vector2_substract(object->points[0], object->current_position)) < 1E9)
+        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 >= 1; j -= 1) {
-            object->points[j] = object->points[j - 1];
+        for (int32_t j = (length == 200) ? length - 1 : length; j >= 2; j -= 1) {
+            object->previous_positions[j] = object->previous_positions[j - 1];
         }
 
-        object->points[0] = object->current_position;
+        object->previous_positions[1] = object->current_position;
 
-        if (length < 200)
-            object->points_length += 1;
+        if (length < 200) {
+            object->previous_positions_length += 1;
+        }
     }
 }
 
-void planetary_system_draw(PlanetarySystem *ps) {
-    CelestialObject *object_reference_frame = ps->objects[ps->reference_frame_object_index];
-    Vector2 reference_frame = object_reference_frame->current_position;
+Vector2 planetary_system_get_reference_frame(PlanetarySystem *system) {
+    CelestialObject *object_reference_frame = system->objects[system->reference_frame_index];
+    return object_reference_frame->current_position;
+}
 
-    for (int32_t i = 0; i < ps->objects_length; i += 1) {
-        CelestialObject *object = ps->objects[i];
-        celestial_object_draw(object, reference_frame, ps->zoom_factor);
-    }
+void planetary_system_draw(PlanetarySystem *system) {
+    Vector2 reference_frame = planetary_system_get_reference_frame(system);
 
-    for (int32_t i = 0; i < ps->objects_length; i += 1) {
-        CelestialObject *object = ps->objects[i];
-        celestial_object_draw_name(object, reference_frame, ps->zoom_factor);
+    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);
     }
 
+    planetary_system_draw_object_names(system);
+
     char text[200];
-    sprintf(text, "Focused Object : %s", object_reference_frame->name);
-    draw_text(text, vector2_create(8, 64));
+    sprintf(text, "Focused Object : %s", system->objects[system->reference_frame_index]->name);
+    draw_text(text, vector2_create(5, 15));
+}
+
+void planetary_system_draw_object_names(PlanetarySystem *system) {
+    if (!system->show_names) {
+        return;
+    }
+
+    Vector2 reference_frame = planetary_system_get_reference_frame(system);
+
+    for (int32_t i = 0; i < system->objects_length; i += 1) {
+        celestial_object_draw_name(system->objects[i], reference_frame, system->zoom_factor);
+    }
 }
diff --git a/PlanetarySystem.h b/PlanetarySystem.h
index 29019531a590d6f17f107f13e111747667f85e47..768cee71c56b9dc1f851285504610e7266be6ed9 100644
--- a/PlanetarySystem.h
+++ b/PlanetarySystem.h
@@ -1,23 +1,26 @@
 #ifndef PLANETARY_SYSTEM_H
 #define PLANETARY_SYSTEM_H
 
+#include <stdbool.h>
 #include <stdint.h>
 
 #include "CelestialObject.h"
 
-extern const uint32_t SCREEN_WIDTH;
-extern const uint32_t SCREEN_HEIGHT;
+extern const int32_t SCREEN_WIDTH;
+extern const int32_t SCREEN_HEIGHT;
 
 typedef struct PlanetarySystem {
     int32_t objects_length;
     CelestialObject **objects;
-    double interval;
     double zoom_factor;
-    int32_t reference_frame_object_index;
+    int32_t reference_frame_index;
+    bool show_names;
 } PlanetarySystem;
 
 PlanetarySystem *planetary_system_create();
 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);
 
 #endif
diff --git a/Vector2.c b/Vector2.c
index 459a285a32ff701c18d201431ecd31509f50213d..1f8931f78d8c23bf10267b081dbf263cba9d199b 100644
--- a/Vector2.c
+++ b/Vector2.c
@@ -1,9 +1,9 @@
 #include "Vector2.h"
 
 #include <math.h>
+#include <stdbool.h>
 #include <stdint.h>
 #include <stdio.h>
-#include <stdlib.h>
 
 Vector2 vector2_create(double x, double y) {
     return (Vector2){.x = x, .y = y};
@@ -46,11 +46,7 @@ Vector2 vector2_normalize(Vector2 v) {
     return vector2_create(v.x / norm, v.y / norm);
 }
 
-bool vector2_is_similiar(Vector2 a, Vector2 b, double epsilon) {
-    return vector2_norm(vector2_substract(a, b)) < epsilon;
-}
-
-Vector2 vector2_fit_canvas(Vector2 v, uint32_t width, uint32_t height) {
+Vector2 vector2_fit_canvas(Vector2 v, int32_t width, int32_t height) {
     double x = width / 2.0 * (1 + v.x);
     double y = height / 2.0 * (1 + v.y);
     return vector2_create(x, y);
diff --git a/Vector2.h b/Vector2.h
index 59e09d219f04d95537afa6b2ce8793ad099a8abf..31f8483305ce698bacaef6db335506d287ceb35c 100644
--- a/Vector2.h
+++ b/Vector2.h
@@ -19,8 +19,7 @@ double vector2_dot_product(Vector2 a, Vector2 b);
 double vector2_norm_sqr(Vector2 v);
 double vector2_norm(Vector2 v);
 Vector2 vector2_normalize(Vector2 v);
-bool vector2_is_similiar(Vector2 a, Vector2 b, double epsilon);
-Vector2 vector2_fit_canvas(Vector2 v, uint32_t width, uint32_t height);
+Vector2 vector2_fit_canvas(Vector2 v, int32_t width, int32_t height);
 void vector2_print(Vector2 v);
 
 #endif
diff --git a/drawing.c b/drawing.c
index b8eefeb65e5607fc22224d1b38d08a6d6781ea07..4d817dff1982b1b709890bad433bb1d9bd971f0d 100644
--- a/drawing.c
+++ b/drawing.c
@@ -26,12 +26,25 @@ void draw_line(Vector2 a, Vector2 b) {
     glEnd();
 }
 
+void draw_scaled_lines(Vector2 *points, int32_t points_length, Vector2 reference_frame, double zoom_factor) {
+    glLineWidth(4.0);
+
+    if (zoom_factor < 1)
+        glLineWidth(4.0 * 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);
+        draw_line(p1, p2);
+    }
+}
+
 void draw_text(char *text, Vector2 position) {
     glColor3f(1.0, 1.0, 1.0);
-    glRasterPos2f(position.x, position.y);
+    glRasterPos2f(position.x, position.y + 15);
 
     for (int32_t i = 0; i < (int32_t)strlen(text); i++) {
-        glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, text[i]);
+        glutBitmapCharacter(GLUT_BITMAP_9_BY_15, text[i]);
     }
 }
 
diff --git a/drawing.h b/drawing.h
index b9de5c9cee093c4a22b3eb6b108bf8991f249096..ca03066b2c375618cc8570f648c8c2ea28d4549b 100644
--- a/drawing.h
+++ b/drawing.h
@@ -7,6 +7,7 @@
 
 void draw_disc(Vector2 position, uint32_t radius);
 void draw_line(Vector2 a, Vector2 b);
+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);
 
diff --git a/main.c b/main.c
index 39b543c4521a705ab20f5d6aa600d965f7298b12..eeb37f7be7b4df15f99400fc6467fff6f6a654a7 100644
--- a/main.c
+++ b/main.c
@@ -3,17 +3,32 @@
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
+#include <sys/time.h>
 #include <time.h>
 
 #include "PlanetarySystem.h"
-#include "Vector2.h"
 #include "drawing.h"
 
-#define WINDOW_NAME "Solar System"
-#define REFRESH_RATE 200
-#define TIME_ELASPING_PER_SECOND 3600 * 24 * 10
-#define TIME_ELASPING_PER_UPDATE 100
+// Name of the window.
+const char WINDOW_NAME[] = "Solar System";
+// Refresh rate in Hz.
+const int32_t REFRESH_RATE = 200;
+// Number of microseconds in 1 second.
+const int32_t ONE_SECOND_IN_MICROSECONDS = 1E6;
+// Number of milliseconds in 1 second.
+const int32_t ONE_SECOND_IN_MILLISECONDS = 1000;
+// Number of seconds in a day.
+const int32_t ONE_DAY_IN_SECONDS = 86400;
+// Zoom multiplier at each wheel movement.
+const double ZOOM_MULTIPLIER = 1.1;
+// Default simulation speed in days.
+const int32_t DEFAULT_SIMULATION_SPEED_IN_DAYS = 10;
+// Maximum speed of the simulation in days.
+const int32_t SIMULATION_MAXIMUM_SPEED_IN_DAYS = 500;
+// Time that elapses in the planetary system per second.
+const int32_t DEFAULT_SIMULATION_SPEED_IN_SECONDS = DEFAULT_SIMULATION_SPEED_IN_DAYS * ONE_DAY_IN_SECONDS;
+// 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;
 
 // https://stackoverflow.com/questions/3417837/what-is-the-best-way-to-suppress-a-unused-variable-x-warning
 #ifdef UNUSED
@@ -26,79 +41,99 @@
 #endif
 
 PlanetarySystem *planetary_system;
-int32_t elapsed_time = 0;
-int32_t true_time_shift = 0;
-int32_t time_elasping_per_second = TIME_ELASPING_PER_SECOND;
-
-void draw_timer() {
-    glutPostRedisplay();
-    glutTimerFunc(1000 / REFRESH_RATE, draw_timer, 0);
+int32_t simulation_speed = DEFAULT_SIMULATION_SPEED_IN_SECONDS;
+int64_t start_time;
+int64_t previous_time;
+
+int64_t get_current_time() {
+    struct timeval time;
+    gettimeofday(&time, NULL);
+    return (int64_t)time.tv_sec * (int64_t)ONE_SECOND_IN_MICROSECONDS + (int64_t)time.tv_usec;
 }
 
-void update_timer() {
-    if (elapsed_time == 0)
-        true_time_shift = time(NULL) % 1000;
-    elapsed_time += 1;
+void update() {
+    int64_t current_time = get_current_time();
+    int64_t elapsed_time = current_time - previous_time;
+    double remaining_time = (double)elapsed_time / ONE_SECOND_IN_MICROSECONDS * simulation_speed;
 
-    for (int32_t i = 0; i < time_elasping_per_second / REFRESH_RATE / TIME_ELASPING_PER_UPDATE; i += 1) {
-        planetary_system_update(planetary_system, TIME_ELASPING_PER_UPDATE);
+    while (remaining_time >= PLANETARY_SYSTEM_INTERVAL) {
+        planetary_system_update(planetary_system, PLANETARY_SYSTEM_INTERVAL);
+        remaining_time -= PLANETARY_SYSTEM_INTERVAL;
     }
 
-    glutTimerFunc(1000 / REFRESH_RATE, update_timer, 0);
+    if (remaining_time > 0) {
+        planetary_system_update(planetary_system, remaining_time);
+    }
+
+    previous_time = current_time;
+}
+
+void update_timer() {
+    update();
+    glutTimerFunc(ONE_SECOND_IN_MILLISECONDS / REFRESH_RATE, update_timer, 0);
 }
 
 void draw() {
     glClearColor(0.0, 0.0, 0.0, 1.0);
     glClear(GL_COLOR_BUFFER_BIT);
 
-    if (elapsed_time % REFRESH_RATE == 0 && elapsed_time != 0) {
-        char title[100];
-        sprintf(title, "Solar System (%d : %ld)", elapsed_time / REFRESH_RATE, (time(NULL) - true_time_shift) % 1000);
-        glutSetWindowTitle(title);
-    }
+    char title[100];
+    double elapsed_time = (get_current_time() - start_time) / ONE_SECOND_IN_MICROSECONDS;
+    sprintf(title, "Solar System (%.2lf)", elapsed_time);
+    glutSetWindowTitle(title);
 
     planetary_system_draw(planetary_system);
 
     char text[100];
-    sprintf(text, "Simulation Speed : %d days per second", time_elasping_per_second / 86400);
-    draw_text(text, vector2_create(8, 32));
+    sprintf(text, "Simulation Speed : %d days per second", simulation_speed / ONE_DAY_IN_SECONDS);
+    draw_text(text, vector2_create(5, 0));
 
     glutSwapBuffers();
 }
 
+void draw_timer() {
+    glutPostRedisplay();
+    glutTimerFunc(ONE_SECOND_IN_MILLISECONDS / REFRESH_RATE, draw_timer, 0);
+}
+
 void handle_keyboard_input(unsigned char key, int UNUSED(x), int UNUSED(y)) {
     if (key == 27) {
+        // TODO : Free
         exit(0);
     }
+
+    if (key == 116) {
+        planetary_system->show_names = !planetary_system->show_names;
+    }
 }
 
 void handle_special_keyboard_input(int key, int UNUSED(x), int UNUSED(y)) {
     if (key == GLUT_KEY_LEFT) {
-        planetary_system->reference_frame_object_index -= 1;
+        planetary_system->reference_frame_index -= 1;
 
-        if (planetary_system->reference_frame_object_index < 0) {
-            planetary_system->reference_frame_object_index = planetary_system->objects_length - 1;
+        if (planetary_system->reference_frame_index < 0) {
+            planetary_system->reference_frame_index = planetary_system->objects_length - 1;
         }
     }
 
     if (key == GLUT_KEY_RIGHT) {
-        planetary_system->reference_frame_object_index += 1;
-        planetary_system->reference_frame_object_index %= planetary_system->objects_length;
+        planetary_system->reference_frame_index += 1;
+        planetary_system->reference_frame_index %= planetary_system->objects_length;
     }
 
     if (key == GLUT_KEY_UP) {
-        time_elasping_per_second += 86400;
+        simulation_speed += ONE_DAY_IN_SECONDS;
 
-        if (time_elasping_per_second > 86400 * 300) {
-            time_elasping_per_second = 86400 * 300;
+        if (simulation_speed > ONE_DAY_IN_SECONDS * SIMULATION_MAXIMUM_SPEED_IN_DAYS) {
+            simulation_speed = ONE_DAY_IN_SECONDS * SIMULATION_MAXIMUM_SPEED_IN_DAYS;
         }
     }
 
     if (key == GLUT_KEY_DOWN) {
-        time_elasping_per_second -= 86400;
+        simulation_speed -= ONE_DAY_IN_SECONDS;
 
-        if (time_elasping_per_second < 0) {
-            time_elasping_per_second = 0;
+        if (simulation_speed < 0) {
+            simulation_speed = 0;
         }
     }
 }
@@ -108,9 +143,9 @@ void handle_mouse_input(int button, int state, int UNUSED(x), int UNUSED(y)) {
         if (state == GLUT_UP) return;
 
         if (button == 3) {
-            planetary_system->zoom_factor *= 1.1;
+            planetary_system->zoom_factor *= ZOOM_MULTIPLIER;
         } else {
-            planetary_system->zoom_factor /= 1.1;
+            planetary_system->zoom_factor /= ZOOM_MULTIPLIER;
         }
     }
 }
@@ -134,8 +169,12 @@ int main(int argc, char *argv[]) {
     glutSpecialFunc(handle_special_keyboard_input);
     glutMouseFunc(handle_mouse_input);
 
-    glutTimerFunc(1000 / REFRESH_RATE, update_timer, 0);
-    glutTimerFunc(1000 / REFRESH_RATE, draw_timer, 0);
+    start_time = get_current_time();
+    previous_time = start_time;
+
+    glutTimerFunc(ONE_SECOND_IN_MILLISECONDS / REFRESH_RATE, update_timer, 0);
+    glutTimerFunc(ONE_SECOND_IN_MILLISECONDS / REFRESH_RATE, draw_timer, 0);
+
     glutMainLoop();
 
     return EXIT_SUCCESS;