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

Add tail line

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