Skip to content
Snippets Groups Projects
Commit ab22d687 authored by Florian Burgener's avatar Florian Burgener
Browse files

Refactoring

parent 97578236
Branches
No related tags found
No related merge requests found
......@@ -5,11 +5,11 @@
#define G 6.67e-11
#define SUN_MASS 1.989e30
CelestialObject *celestial_object_create(double mass, Vector2 *position) {
CelestialObject *celestial_object_create(double mass, Vector2 position) {
CelestialObject *object = (CelestialObject*)malloc(sizeof(CelestialObject));
object->mass = mass;
object->previous_position = NULL;
// object->previous_position = NULL;
object->current_position = position;
return object;
......
#ifndef CELESTIAL_OBJECT_H
#define CELESTIAL_OBJECT_H
#include "Vectors/Vector2.h"
#include "Vector2.h"
#include "gfx/gfx.h"
typedef struct CelestialObject CelestialObject;
typedef struct CelestialObject {
double mass;
Vector2 *previous_position;
Vector2 *current_position;
Vector2 previous_position;
Vector2 current_position;
} CelestialObject;
CelestialObject *celestial_object_create(double mass, Vector2 *position);
CelestialObject *celestial_object_create(double mass, Vector2 position);
#endif
#The compiler
TARGET = main
CC:=gcc
#The flags passed to the compiler
CFLAGS:=-g -Ofast -Wall -Wextra -fsanitize=address -fsanitize=leak -std=gnu11
#The flags passed to the linker
# CFLAGS:=-g -Ofast -Wall -Wextra -fsanitize=address -fsanitize=leak -std=gnu11
CFLAGS:=-fsanitize=address
LDFLAGS:=-lm -lSDL2
#Path to the lib Vec2
VPATH:=Vectors gfx
VPATH:=gfx
%.o: %.c $(HEADERS)
$(CC) $(CFLAGS) -c $< -o $@
main: main.o Vector2.o gfx.o CelestialObject.o SolarSystem.o
$(TARGET): main.o Vector2.o CelestialObject.o SolarSystem.o gfx.o
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
CelestialObject.o: CelestialObject.h
SolarSystem.o: SolarSystem.h
Vector2.o: Vector2.h
gfx.o: gfx.h
clean:
rm -f *.o main tests
-rm -f *.o $(TARGET)
......@@ -3,75 +3,64 @@
#include <stdlib.h>
#include "CelestialObject.h"
#include "Vectors/Vector2.h"
#include "Vector2.h"
#include "gfx/gfx.h"
#define SCREEN_WIDTH 1000
#define SCREEN_HEIGHT 1000
void __update(SolarSystem *solar_system) {
SolarSystem *solar_system_create(double interval) {
SolarSystem *solar_system = (SolarSystem *)malloc(sizeof(SolarSystem));
solar_system->objects_length = 2;
solar_system->objects = (CelestialObject **)malloc(sizeof(SolarSystem *) * solar_system->objects_length);
solar_system->objects[0] = celestial_object_create(1.989 * 1E30, vector2_create(0, 0));
double perihelion_1 = 149.6 * 1E9 * (1 - 0.01671123);
solar_system->objects[1] = celestial_object_create(5.972 * 1E24, vector2_create(-perihelion_1, 0));
// const double MARS_MASS = 6.39 * 1E23;
// double e_2 = 0.0934;
// double semi_major_2 = 227.9 * 1E9;
// double perihelion_2 = semi_major_2 * (1 - e_2);
// Vector2 *mars_position = vector2_create(-perihelion_2, 0);
// solar_system->celestial_objects[2] = celestial_object_create(MARS_MASS, mars_position);
// const double VENUS_MASS = 4.867 * 1E24;
// double e_3 = 0.00678;
// double semi_major_3 = 108.2095 * 1E9;
// double perihelion_3 = semi_major_3 * (1 - e_3);
// Vector2 *venus_position = vector2_create(-perihelion_3, 0);
// solar_system->celestial_objects[3] = celestial_object_create(VENUS_MASS, venus_position);
return solar_system;
}
void __draw(SolarSystem *solar_system, struct gfx_context_t *ctxt) {
for (int32_t i = 0; i < solar_system->celestial_objects_length; i += 1) {
CelestialObject *object = solar_system->celestial_objects[i];
void solar_system_update(SolarSystem *solar_system) {
}
void solar_system_draw(SolarSystem *solar_system, struct gfx_context_t *context) {
for (uint32_t i = 0; i < solar_system->objects_length; i += 1) {
CelestialObject *object = solar_system->objects[i];
Vector2 *tmp = object->current_position->multiply(object->current_position, 1.0 / (227.9 * 1E9 * 1.1));
Vector2 *tmp2 = object->current_position->fit_canvas(tmp, SCREEN_WIDTH, SCREEN_HEIGHT);
Vector2 scaled_position = vector2_multiply(object->current_position, 1.0 / (227.9 * 1E9 * 1.1));
scaled_position = vector2_fit_canvas(scaled_position, SCREEN_WIDTH, SCREEN_HEIGHT);
if (i == 0) {
draw_full_circle(ctxt, tmp2->x, tmp2->y, 70, COLOR_YELLOW);
draw_full_circle(context, scaled_position.x, scaled_position.y, 70, COLOR_YELLOW);
}
if (i == 1) {
draw_full_circle(ctxt, tmp2->x, tmp2->y, 15, COLOR_BLUE);
draw_full_circle(context, scaled_position.x, scaled_position.y, 15, COLOR_BLUE);
}
if (i == 2) {
draw_full_circle(ctxt, tmp2->x, tmp2->y, 8, COLOR_RED);
draw_full_circle(context, scaled_position.x, scaled_position.y, 8, COLOR_RED);
}
if (i == 3) {
draw_full_circle(ctxt, tmp2->x, tmp2->y, 15, COLOR_GREEN);
draw_full_circle(context, scaled_position.x, scaled_position.y, 15, COLOR_GREEN);
}
free(tmp);
free(tmp2);
}
}
SolarSystem *solar_system_create(double interval) {
SolarSystem *solar_system = (SolarSystem *)malloc(sizeof(SolarSystem));
solar_system->update = __update;
solar_system->draw = __draw;
solar_system->celestial_objects_length = 4;
solar_system->celestial_objects = (SolarSystem **)malloc(sizeof(SolarSystem *) * solar_system->celestial_objects_length);
const double SUN_MASS = 1.989 * 1E30;
Vector2 *sun_position = vector2_create(0, 0);
solar_system->celestial_objects[0] = celestial_object_create(SUN_MASS, sun_position);
const double EARTH_MASS = 5.972 * 1E24;
double e_1 = 0.01671123;
double semi_major_1 = 149.6 * 1E9;
double perihelion_1 = semi_major_1 * (1 - e_1);
Vector2 *earth_position = vector2_create(-perihelion_1, 0);
solar_system->celestial_objects[1] = celestial_object_create(EARTH_MASS, earth_position);
const double MARS_MASS = 6.39 * 1E23;
double e_2 = 0.0934;
double semi_major_2 = 227.9 * 1E9;
double perihelion_2 = semi_major_2 * (1 - e_2);
Vector2 *mars_position = vector2_create(-perihelion_2, 0);
solar_system->celestial_objects[2] = celestial_object_create(MARS_MASS, mars_position);
const double VENUS_MASS = 4.867 * 1E24;
double e_3 = 0.00678;
double semi_major_3 = 108.2095 * 1E9;
double perihelion_3 = semi_major_3 * (1 - e_3);
Vector2 *venus_position = vector2_create(-perihelion_3, 0);
solar_system->celestial_objects[3] = celestial_object_create(VENUS_MASS, venus_position);
return solar_system;
}
#ifndef SOLAR_SYSTEM_H
#define SOLAR_SYSTEM_H
#include <stdint.h>
#include "CelestialObject.h"
#include "gfx/gfx.h"
typedef struct SolarSystem SolarSystem;
struct SolarSystem {
// CelestialObject *star;
uint32_t celestial_objects_length;
CelestialObject **celestial_objects;
void (*update)(SolarSystem *solar_system);
void (*draw)(SolarSystem *solar_system, struct gfx_context_t *ctxt);
};
typedef struct {
uint32_t objects_length;
CelestialObject **objects;
} SolarSystem;
SolarSystem *solar_system_create(double interval);
void solar_system_update(SolarSystem *solar_system);
void solar_system_draw(SolarSystem *solar_system, struct gfx_context_t *context);
// void show_system(struct gfx_context_t *ctxt, system_t *system);
// void update_system(system_t *system, double interval);
// void free_system(system_t *system);
......
#include "Vector2.h"
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
Vector2 vector2_create(double x, double y) {
return (Vector2){.x = x, .y = y};
}
Vector2 vector2_create_zero() {
return vector2_create(0, 0);
}
Vector2 vector2_add(Vector2 a, Vector2 b) {
return vector2_create(a.x + b.x, a.y + b.y);
}
Vector2 vector2_substract(Vector2 a, Vector2 b) {
return vector2_create(a.x - b.x, a.y - b.y);
}
Vector2 vector2_multiply(Vector2 v, double scalar) {
return vector2_create(v.x * scalar, v.y * scalar);
}
double vector2_dot_product(Vector2 a, Vector2 b) {
return a.x * b.x + a.y * b.y;
}
double vector2_norm_sqr(Vector2 v) {
return vector2_dot_product(v, v);
}
double vector2_norm(Vector2 v) {
return sqrt(vector2_norm_sqr(v));
}
Vector2 vector2_normalize(Vector2 v) {
double norm = vector2_norm(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) {
double x = round((width - 1) / 2.0 + v.x * (width - 1) / 2.0);
double y = round((height - 1) / 2.0 + v.y * (height - 1) / 2.0);
return vector2_create(x, y);
}
void vector2_print(Vector2 v) {
printf("(%lf, %lf)\n", v.x, v.y);
}
#ifndef VECTOR2_H
#define VECTOR2_H
#include <stdbool.h>
#include <stdint.h>
typedef struct Vector2 Vector2;
struct Vector2 {
double x;
double y;
};
Vector2 vector2_create(double x, double y);
Vector2 vector2_create_zero();
Vector2 vector2_add(Vector2 a, Vector2 b);
Vector2 vector2_substract(Vector2 a, Vector2 b);
Vector2 vector2_multiply(Vector2 v, double scalar);
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);
void vector2_print(Vector2 v);
#endif
#include "Vector2.h"
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
Vector2 *__add(Vector2 *a, Vector2 *b) {
return vector2_create(a->x + b->x, a->y + b->y);
}
Vector2 *__substract(Vector2 *a, Vector2 *b) {
return vector2_create(a->x - b->x, a->y - b->y);
}
Vector2 *__multiply(Vector2 *v, double scalar) {
return vector2_create(v->x * scalar, v->y * scalar);
}
double __dot_product(Vector2 *a, Vector2 *b) {
return a->x * b->x + a->y * b->y;
}
double __norm_sqr(Vector2 *v) {
return v->dot_product(v, v);
}
double __norm(Vector2 *v) {
return sqrt(v->norm_sqr(v));
}
Vector2 *__normalize(Vector2 *v) {
double norm = v->norm(v);
return vector2_create(v->x / norm, v->y / norm);
}
bool __is_similiar(Vector2 *a, Vector2 *b, double epsilon) {
Vector2 *c = a->substract(a, b);
double norm = c->norm(c);
free(c);
return norm < epsilon;
}
Vector2 *__fit_canvas(Vector2 *v, uint32_t width, uint32_t height) {
double x = round((width - 1) / 2.0 + v->x * (width - 1) / 2.0);
double y = round((height - 1) / 2.0 + v->y * (height - 1) / 2.0);
return vector2_create(x, y);
}
void __print(Vector2 *v) {
printf("(%lf, %lf)\n", v->x, v->y);
}
Vector2 *vector2_create(double x, double y) {
Vector2 *v = (Vector2 *)malloc(sizeof(Vector2));
v->add = __add;
v->substract = __substract;
v->multiply = __multiply;
v->dot_product = __dot_product;
v->norm = __norm;
v->norm_sqr = __norm_sqr;
v->normalize = __normalize;
v->is_similiar = __is_similiar;
v->fit_canvas = __fit_canvas;
v->print = __print;
v->x = x;
v->y = y;
return v;
}
Vector2 *vector2_create_zero() {
return vector2_create(0, 0);
}
#ifndef VECTOR2_H
#define VECTOR2_H
#include <stdbool.h>
#include <stdint.h>
typedef struct Vector2 Vector2;
struct Vector2 {
double x;
double y;
Vector2 *(*add)(Vector2 *a, Vector2 *b);
Vector2 *(*substract)(Vector2 *a, Vector2 *b);
Vector2 *(*multiply)(Vector2 *v, double scalar);
double (*dot_product)(Vector2 *a, Vector2 *b);
double (*norm_sqr)(Vector2 *v);
double (*norm)(Vector2 *v);
Vector2 *(*normalize)(Vector2 *v);
bool (*is_similiar)(Vector2 *a, Vector2 *b, double epsilon);
Vector2 *(*fit_canvas)(Vector2 *v, uint32_t width, uint32_t height);
void (*print)(Vector2 *v);
};
Vector2 *vector2_create(double x, double y);
Vector2 *vector2_create_zero();
typedef struct _coordinates {
uint32_t row, column;
} coordinates;
#endif
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "Vector2.h"
typedef struct _test_result {
bool passed;
const char *name;
} test_result;
typedef test_result (*unit_test_t)(void);
void print_in_color(char *color, char *text) {
printf("\033%s", color);
printf("%s", text);
printf("\033[0m");
}
void print_in_red(char *text) {
print_in_color("[0;31m", text);
}
void print_in_green(char *text) {
print_in_color("[0;32m", text);
}
bool dbl_eq(double a, double b) {
return fabs(a - b) < 1e-6;
}
/*
*
* Write your tests here
*
*/
/* TODO
vec2 vec2_create(double x_, double y_); -- Ok
vec2 vec2_create_zero(); -- Ok
vec2 vec2_add(vec2 lhs, vec2 rhs); -- Ok
vec2 vec2_sub(vec2 lhs, vec2 rhs); -- Ok
vec2 vec2_mul(double scalar, vec2 lhs); -- Ok
double vec2_dot(vec2 lhs, vec2 rhs); -- Ok
double vec2_norm_sqr(vec2 v); -- Ok
double vec2_norm(vec2 v); -- Ok
vec2 vec2_normalize(vec2 v); -- Ok
bool vec2_is_approx_equal(vec2 lhs, vec2 rhs, double eps);
coordinates vec2_to_coordinates(vec2 v, uint32_t width, uint32_t height);
*/
const double u_x[] = {1.25, 3.53, 2.64, 8.8};
const double u_y[] = {3.42, 7.22, 5.32, 2.44};
const double v_x[] = {4.32, 6.21, 7.42, 9.32};
const double v_y[] = {5.22, 3.56, 8.65, 6.44};
const uint32_t nb_tests = sizeof(u_x) / sizeof(double);
test_result t_vec2_create_0() {
bool passed = true;
for (uint32_t i = 0; i < nb_tests; i++) {
Vector2 *v = vector2_create(u_x[i], u_y[i]);
if (u_x[i] != v->x || u_y[i] != v->y) {
passed = false;
break;
}
free(v);
}
return (test_result){.passed = passed, .name = "Test vec2_create 0"};
}
test_result t_vec2_create_zero_0() {
Vector2 *v = vector2_create_zero();
bool passed = v->x == 0.0 && v->y == 0.0;
free(v);
return (test_result){.passed = passed, .name = "Test vec2_create_zero 0"};
}
test_result t_vec2_add_0() {
double r_x[] = {5.57, 9.74, 10.06, 18.12};
double r_y[] = {8.64, 10.78, 13.97, 8.88};
bool passed = true;
for (uint32_t i = 0; i < nb_tests; i++) {
Vector2 *u = vector2_create(u_x[i], u_y[i]);
Vector2 *v = vector2_create(v_x[i], v_y[i]);
Vector2 *r = u->add(u, v);
if (!(dbl_eq(r->x, r_x[i]) && dbl_eq(r->y, r_y[i]))) {
passed = false;
break;
}
free(u);
free(v);
free(r);
}
return (test_result){.passed = passed, .name = "Test vec2_add 0"};
}
test_result t_vec2_sub_0() {
double r_x[] = {-3.07, -2.68, -4.78, -0.52};
double r_y[] = {-1.80, 3.66, -3.33, -4.00};
bool passed = true;
for (uint32_t i = 0; i < nb_tests; i++) {
Vector2 *u = vector2_create(u_x[i], u_y[i]);
Vector2 *v = vector2_create(v_x[i], v_y[i]);
Vector2 *r = u->substract(u, v);
if (!(dbl_eq(r->x, r_x[i]) && dbl_eq(r->y, r_y[i]))) {
passed = false;
break;
}
free(u);
free(v);
free(r);
}
return (test_result){.passed = passed, .name = "Test vec2_sub 0"};
}
test_result t_vec2_mul_0() {
double r_x[] = {5.40, 21.9213, 19.5888, 82.016};
double r_y[] = {14.7744, 44.8362, 39.4744, 22.740800};
bool passed = true;
for (uint32_t i = 0; i < nb_tests; i++) {
double alpha = v_x[i];
Vector2 *u = vector2_create(u_x[i], u_y[i]);
Vector2 *r = u->multiply(u, alpha);
if (!(dbl_eq(r->x, r_x[i]) && dbl_eq(r->y, r_y[i]))) {
passed = false;
break;
}
free(u);
free(r);
}
return (test_result){.passed = passed, .name = "Test vec2_mul 0"};
}
test_result t_vec2_dot_0() {
double r[] = {23.2524, 47.6245, 65.6068, 97.7296};
bool passed = true;
for (uint32_t i = 0; i < nb_tests; i++) {
Vector2 *u = vector2_create(u_x[i], u_y[i]);
Vector2 *v = vector2_create(v_x[i], v_y[i]);
double res = u->dot_product(u, v);
if (!dbl_eq(res, r[i])) {
passed = false;
break;
}
free(u);
free(v);
}
return (test_result){.passed = passed, .name = "Test vec2_dot 0"};
}
test_result t_vec2_norm_sqr_0() {
double r[] = {13.2589, 64.5893, 35.272, 83.3936};
bool passed = true;
for (uint32_t i = 0; i < nb_tests; i++) {
Vector2 *u = vector2_create(u_x[i], u_y[i]);
double res = u->norm_sqr(u);
if (!dbl_eq(res, r[i])) {
passed = false;
break;
}
free(u);
}
return (test_result){.passed = passed, .name = "Test vec2_norm_sqr 0"};
}
test_result t_vec2_norm_0() {
double r[] = {3.641277, 8.036747, 5.939023, 9.132010};
bool passed = true;
for (uint32_t i = 0; i < nb_tests; i++) {
Vector2 *u = vector2_create(u_x[i], u_y[i]);
double res = u->norm(u);
if (!dbl_eq(res, r[i])) {
passed = false;
break;
}
free(u);
}
return (test_result){.passed = passed, .name = "Test vec2_norm 0"};
}
test_result t_vec2_normalize_0() {
double r_x[] = {0.343286, 0.439232, 0.444518, 0.963643};
double r_y[] = {0.939231, 0.898373, 0.895770, 0.267192};
bool passed = true;
for (uint32_t i = 0; i < nb_tests; i++) {
Vector2 *u = vector2_create(u_x[i], u_y[i]);
Vector2 *r = u->normalize(u);
if (!(dbl_eq(r->x, r_x[i]) && dbl_eq(r->y, r_y[i]))) {
passed = false;
break;
}
free(u);
free(r);
}
return (test_result){.passed = passed, .name = "Test vec2_normalize 0"};
}
test_result t_vec2_is_approx_equal_0() {
bool r[] = {true, true, false, false};
double t_x[] = {u_x[0], u_x[1] + 1e-4, u_x[2] + 15.0, u_x[3] + 1e-2};
double t_y[] = {u_y[0], u_y[1] - 1e-4, u_y[2] + 15.0, u_y[3] + 1e-2};
bool passed = true;
for (uint32_t i = 0; i < nb_tests; i++) {
Vector2 *u = vector2_create(u_x[i], u_y[i]);
Vector2 *t = vector2_create(t_x[i], t_y[i]);
if (u->is_similiar(u, t, 1e-3) != r[i]) {
passed = false;
break;
}
free(u);
free(t);
}
return (test_result){.passed = passed, .name = "Test vec2_is_approx_equal 0"};
}
// test_result t_vec2_to_coordinates_0() {
// uint32_t height = 300;
// uint32_t width = 100;
// double t_x[] = {0.25, 0.5, 0.75, 1};
// double t_y[] = {0, 1.0 / 3.0, 2.0 / 3.0, 1};
// uint32_t r_col[] = {62, 74, 87, 99};
// uint32_t r_row[] = {150, 199, 249, 299};
// bool passed = true;
// for (uint32_t i = 0; i < nb_tests; i++) {
// vec2 t = vec2_create(t_x[i], t_y[i]);
// coordinates r = vec2_to_coordinates(t, width, height);
// if (r.row != r_row[i] || r.column != r_col[i]) {
// passed = false;
// break;
// }
// }
// return (test_result){.passed = passed, .name = "Test vec2_to_coordinates 0"};
// }
//Add or remove your test function name here
const unit_test_t tests[] = {
t_vec2_create_0,
t_vec2_create_zero_0,
t_vec2_add_0,
t_vec2_sub_0,
t_vec2_mul_0,
t_vec2_dot_0,
t_vec2_norm_sqr_0,
t_vec2_norm_0,
t_vec2_normalize_0,
t_vec2_is_approx_equal_0,
// t_vec2_to_coordinates_0,
};
int main() {
uint32_t nb_tests = sizeof(tests) / sizeof(unit_test_t);
char message[256];
bool all_passed = true;
for (uint32_t i = 0; i < nb_tests; i++) {
printf("Running test n°%d: ...\n", i);
test_result r = tests[i]();
if (r.passed) {
sprintf(message, "\t- %s : OK", r.name);
print_in_green(message);
} else {
all_passed = false;
sprintf(message, "\t- %s : FAILED", r.name);
print_in_red(message);
}
printf("\n");
}
if (all_passed)
print_in_green("\nTests suite result : OK\n");
else
print_in_red("\nTests suite result : FAILED\n");
}
......@@ -3,25 +3,20 @@
#include <stdlib.h>
#include <time.h>
#include "CelestialObject.h"
#include "SolarSystem.h"
#include "Vectors/Vector2.h"
#include "gfx/gfx.h"
#include "Vector2.h"
// #include "gfx/gfx.h"
#define SCREEN_WIDTH 1000
#define SCREEN_HEIGHT 1000
const double SUN_MASS = 1.989 * 1E30;
const double EARTH_MASS = 5.972 * 1E24;
int main() {
// srand(time(NULL));
srand(0);
printf("%lf\n", SUN_MASS);
struct gfx_context_t *ctxt = gfx_create("Solar System", SCREEN_WIDTH, SCREEN_HEIGHT);
struct gfx_context_t *context = gfx_create("Solar System", SCREEN_WIDTH, SCREEN_HEIGHT);
if (!ctxt) {
if (!context) {
fprintf(stderr, "Graphics initialization failed!\n");
return EXIT_FAILURE;
}
......@@ -29,16 +24,16 @@ int main() {
SolarSystem *solar_system = solar_system_create(0);
while (true) {
gfx_present(ctxt);
gfx_clear(ctxt, COLOR_BLACK);
gfx_present(context);
gfx_clear(context, COLOR_BLACK);
solar_system->draw(solar_system, ctxt);
solar_system_draw(solar_system, context);
if (gfx_keypressed() == SDLK_ESCAPE) {
break;
}
}
gfx_destroy(ctxt);
gfx_destroy(context);
return EXIT_SUCCESS;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment