diff --git a/CelestialObject.c b/CelestialObject.c index 95b1292da646cc3b640b61c59131ce716f0793ce..2d0086f11889f81a4922b71a9b4192ce60bff747 100644 --- a/CelestialObject.c +++ b/CelestialObject.c @@ -18,6 +18,8 @@ CelestialObject *celestial_object_create(double mass, double semi_major_axis, do 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; return object; } diff --git a/CelestialObject.h b/CelestialObject.h index 266f603f86c9fda21c33d15efb527a15374a62b8..0b1b3a87b984a5ec4095345f8dc2f35871ec3f10 100644 --- a/CelestialObject.h +++ b/CelestialObject.h @@ -3,7 +3,6 @@ #include "Vector2.h" -typedef struct CelestialObject CelestialObject; typedef struct CelestialObject { double mass; Vector2 previous_position; @@ -12,6 +11,8 @@ typedef struct CelestialObject { double eccentricity; uint32_t drawing_disc_radius; uint32_t drawing_color; + Vector2 *points; + int32_t points_length; } CelestialObject; CelestialObject *celestial_object_create(double mass, double semi_major_axis, double eccentricity, uint32_t drawing_disc_radius, uint32_t drawing_color); diff --git a/PlanetarySystem.c b/PlanetarySystem.c index 962676b780b3b6ed322d36e17c0bb96b16ad5a91..0205d56e72cceff57737fa7b69eb735b857d55e4 100644 --- a/PlanetarySystem.c +++ b/PlanetarySystem.c @@ -68,7 +68,7 @@ Vector2 calculate_gravitational_acceleration(PlanetarySystem *planetary_system, return a; } -void planetary_system_update(PlanetarySystem *planetary_system, double interval) { +void planetary_system_update(PlanetarySystem *planetary_system, double interval, bool save_position) { for (uint32_t i = 1; i < planetary_system->objects_length; i += 1) { CelestialObject *object = planetary_system->objects[i]; Vector2 current_position = object->current_position; @@ -101,33 +101,62 @@ void planetary_system_update(PlanetarySystem *planetary_system, double interval) object->previous_position = object->current_position; object->current_position = new_position; + + if (object->points_length < 200 && save_position) { + object->points[object->points_length] = object->current_position; + object->points_length += 1; + } else if (save_position) { + for (int32_t j = 1; j < object->points_length; j += 1) { + object->points[j - 1] = object->points[j]; + } + + object->points[object->points_length - 1] = object->current_position; + } } } -Vector2 scale_position(Vector2 position) { - Vector2 scaled_position = vector2_multiply(position, 1.0 / (260 * 1E9)); +Vector2 scale_position(PlanetarySystem *planetary_system, Vector2 object_position, Vector2 reference_frame_position) { + Vector2 unscaled_position = vector2_substract(object_position, reference_frame_position); + unscaled_position = vector2_multiply(unscaled_position, planetary_system->zoom_factor); + + Vector2 scaled_position = vector2_multiply(unscaled_position, 1.0 / (300 * 1E9)); scaled_position = vector2_fit_canvas(scaled_position, SCREEN_WIDTH, SCREEN_HEIGHT); return scaled_position; } +void draw_disc(Vector2 position, uint32_t radius) { + glBegin(GL_POLYGON); + for (uint32_t i = 0; i < 360; i += 1) { + double theta = i * 3.1415 / 180; + double x = position.x + radius * cos(theta); + double y = position.y + radius * sin(theta); + glVertex2f(x, y); + } + glEnd(); +} + void planetary_system_draw(PlanetarySystem *planetary_system) { + CelestialObject *reference_frame = planetary_system->objects[planetary_system->reference_frame_object_index]; + for (uint32_t i = 0; i < planetary_system->objects_length; i += 1) { CelestialObject *object = planetary_system->objects[i]; - Vector2 unscaled_position = vector2_substract(object->current_position, planetary_system->objects[planetary_system->reference_frame_object_index]->current_position); - unscaled_position = vector2_multiply(unscaled_position, planetary_system->zoom_factor); - Vector2 scaled_position = scale_position(unscaled_position); + Vector2 scaled_position = scale_position(planetary_system, object->current_position, reference_frame->current_position); uint32_t color = object->drawing_color; glColor3ub((color & 0xFF0000) >> 16, (color & 0x00FF00) >> 8, (color & 0x0000FF) >> 0); - glBegin(GL_POLYGON); - - for (uint32_t i = 0; i < 360; i += 1) { - double theta = i * 3.1415 / 180; - double x = scaled_position.x + object->drawing_disc_radius * cos(theta); - double y = scaled_position.y + object->drawing_disc_radius * sin(theta); - glVertex2f(x, y); + draw_disc(scaled_position, object->drawing_disc_radius); + + if (i != 5) { + glLineWidth(4.0); + + for (int32_t j = 0; j < object->points_length - 1; j += 1) { + glBegin(GL_LINES); + Vector2 aaa = scale_position(planetary_system, object->points[j], reference_frame->current_position); + glVertex2f(aaa.x, aaa.y); + Vector2 bbb = scale_position(planetary_system, object->points[j + 1], reference_frame->current_position); + glVertex2f(bbb.x, bbb.y); + glEnd(); + } } - - glEnd(); } } diff --git a/PlanetarySystem.h b/PlanetarySystem.h index 7c7f12c4b45ded30596fdb4cfa28bfcd2200a81a..21fb7e80a5e45f11ad0c95e50881adfeb0dc9f9b 100644 --- a/PlanetarySystem.h +++ b/PlanetarySystem.h @@ -17,7 +17,7 @@ typedef struct { } PlanetarySystem; PlanetarySystem *planetary_system_create(); -void planetary_system_update(PlanetarySystem *planetary_system, double interval); +void planetary_system_update(PlanetarySystem *planetary_system, double interval, bool save_position); void planetary_system_draw(PlanetarySystem *planetary_system); #endif diff --git a/main.c b/main.c index 31e44e23080359a24451f75d87596366adbd2cdf..34f56666af6c8b15239a9db4dcc5fb45d8cdfe50 100644 --- a/main.c +++ b/main.c @@ -8,9 +8,9 @@ #include "Vector2.h" #define WINDOW_NAME "Solar System" -#define REFRESH_RATE 100 -#define UPDATE_RATE 10000 -#define TIME_ELASPING_PER_SECOND 3600 * 24 * 30 +#define REFRESH_RATE 200 +#define TIME_ELASPING_PER_SECOND 3600 * 24 * 80 +#define TIME_ELASPING_PER_UPDATE 100 // https://stackoverflow.com/questions/3417837/what-is-the-best-way-to-suppress-a-unused-variable-x-warning #ifdef UNUSED @@ -29,12 +29,15 @@ uint32_t true_time_shift = 0; void draw_timer() { glutPostRedisplay(); glutTimerFunc(1000 / REFRESH_RATE, draw_timer, 0); - elapsed_time += 1; } void update_timer() { - for (uint32_t i = 0; i < UPDATE_RATE / REFRESH_RATE; i += 1) { - planetary_system_update(planetary_system, (double)TIME_ELASPING_PER_SECOND / UPDATE_RATE); + if (elapsed_time == 0) + true_time_shift = time(NULL) % 1000; + elapsed_time += 1; + + for (uint32_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, i == 0); } glutTimerFunc(1000 / REFRESH_RATE, update_timer, 0); @@ -44,7 +47,7 @@ void draw() { glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); - if (elapsed_time % REFRESH_RATE == 0) { + 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); @@ -84,10 +87,6 @@ void handle_mouse_input(int button, int state, int UNUSED(x), int UNUSED(y)) { planetary_system->zoom_factor *= 1.1; } else { planetary_system->zoom_factor /= 1.1; - - if (planetary_system->zoom_factor < 1) { - planetary_system->zoom_factor = 1; - } } } } @@ -110,7 +109,6 @@ int main(int argc, char *argv[]) { glutSpecialFunc(handle_special_keyboard_input); glutMouseFunc(handle_mouse_input); - true_time_shift = time(NULL) % 1000; glutTimerFunc(1000 / REFRESH_RATE, update_timer, 0); glutTimerFunc(1000 / REFRESH_RATE, draw_timer, 0);