Skip to content
Snippets Groups Projects
Commit e7ef9065 authored by navid.elmi's avatar navid.elmi
Browse files

tp

parent 0cb39834
No related branches found
No related tags found
No related merge requests found
#The compiler
CC:=gcc
#The flags passed to the compiler
CFLAGS:=-g -Wall -Wextra -fsanitize=address -fsanitize=leak -std=gnu11
#The flags passed to the linker
LDFLAGS:=-lm -lSDL2
#Path to the lib Vec2
VPATH:=vec2 gfx planet force
main: main.o vec2.o gfx.o planet.o
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
run_tests: tests
./$<
tests: vec_tests.o vec2.o
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
planet.o: planet.h
vec2.o: vec2.h
gfx.o: gfx.h
force.o: force.c
$(CC) $(CFLAGS) -c $^ $(LDFLAGS)
clean:
rm -f *.o main tests
File added
/// @file gfx.c
/// @author Florent Gluck
/// @date November 6, 2016
/// Helper routines to render pixels in fullscreen graphic mode.
/// Uses the SDL2 library.
/// Update : Add full circle
/// @author Michaël El Kharroubi
/// @date 19 November 2021
#include "gfx.h"
#include <assert.h>
#include <SDL2/SDL.h>
/// Create a fullscreen graphic window.
/// @param title Title of the window.
/// @param width Width of the window in pixels.
/// @param height Height of the window in pixels.
/// @return a pointer to the graphic context or NULL if it failed.
struct gfx_context_t *gfx_create(char *title, uint32_t width, uint32_t height)
{
if (SDL_Init(SDL_INIT_VIDEO) != 0)
goto error;
SDL_Window *window = SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_RESIZABLE);
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STREAMING, width, height);
uint32_t *pixels = malloc(width * height * sizeof(uint32_t));
struct gfx_context_t *ctxt = malloc(sizeof(struct gfx_context_t));
if (!window || !renderer || !texture || !pixels || !ctxt)
goto error;
ctxt->renderer = renderer;
ctxt->texture = texture;
ctxt->window = window;
ctxt->width = width;
ctxt->height = height;
ctxt->pixels = pixels;
SDL_ShowCursor(SDL_DISABLE);
gfx_clear(ctxt, COLOR_BLACK);
return ctxt;
error:
return NULL;
}
/// Draw a pixel in the specified graphic context.
/// @param ctxt Graphic context where the pixel is to be drawn.
/// @param column X coordinate of the pixel.
/// @param row Y coordinate of the pixel.
/// @param color Color of the pixel.
void gfx_putpixel(struct gfx_context_t *ctxt, uint32_t column, uint32_t row, uint32_t color)
{
if (column < ctxt->width && row < ctxt->height)
ctxt->pixels[ctxt->width * row + column] = color;
}
/// Clear the specified graphic context.
/// @param ctxt Graphic context to clear.
/// @param color Color to use.
void gfx_clear(struct gfx_context_t *ctxt, uint32_t color)
{
int n = ctxt->width * ctxt->height;
while (n)
ctxt->pixels[--n] = color;
}
/// Display the graphic context.
/// @param ctxt Graphic context to clear.
void gfx_present(struct gfx_context_t *ctxt)
{
SDL_UpdateTexture(
ctxt->texture, NULL, ctxt->pixels, ctxt->width * sizeof(uint32_t));
SDL_RenderCopy(ctxt->renderer, ctxt->texture, NULL, NULL);
SDL_RenderPresent(ctxt->renderer);
}
/// Destroy a graphic window.
/// @param ctxt Graphic context of the window to close.
void gfx_destroy(struct gfx_context_t *ctxt)
{
SDL_ShowCursor(SDL_ENABLE);
SDL_DestroyTexture(ctxt->texture);
SDL_DestroyRenderer(ctxt->renderer);
SDL_DestroyWindow(ctxt->window);
free(ctxt->pixels);
ctxt->texture = NULL;
ctxt->renderer = NULL;
ctxt->window = NULL;
ctxt->pixels = NULL;
SDL_Quit();
free(ctxt);
}
/// If a key was pressed, returns its key code (non blocking call).
/// List of key codes: https://wiki.libsdl.org/SDL_Keycode
/// @return the key that was pressed or 0 if none was pressed.
SDL_Keycode gfx_keypressed()
{
SDL_Event event;
if (SDL_PollEvent(&event))
{
if (event.type == SDL_KEYDOWN)
return event.key.keysym.sym;
}
return 0;
}
/// Draw a full circle using Andres's discrete circle algorithm.
/// @param ctxt Graphic context to clear.
/// @param c_column X coordinate of the circle center.
/// @param c_row Y coordinate of the circle center.
/// @param r The radius of circle (in pixels).
/// @param color Color to use.
void draw_full_circle(struct gfx_context_t *ctxt, uint32_t c_column, uint32_t c_row, uint32_t r, uint32_t color)
{
int32_t x = 0, y = r, d = r - 1;
while (y >= x)
{
gfx_putpixel(ctxt, c_column + x, c_row + y, color);
gfx_putpixel(ctxt, c_column + y, c_row + x, color);
gfx_putpixel(ctxt, c_column - x, c_row + y, color);
gfx_putpixel(ctxt, c_column - y, c_row + x, color);
gfx_putpixel(ctxt, c_column + x, c_row - y, color);
gfx_putpixel(ctxt, c_column + y, c_row - x, color);
gfx_putpixel(ctxt, c_column - x, c_row - y, color);
gfx_putpixel(ctxt, c_column - y, c_row - x, color);
if ((2 * x) <= d)
{
d -= 2 * x + 1;
x += 1;
}
else if (d < (2 * (((int32_t)r) - y)))
{
d += 2 * y - 1;
y -= 1;
}
else
{
d -= 2 * (x - y + 1);
y -= 1;
x += 1;
}
}
if (r > 0)
draw_full_circle(ctxt, c_column, c_row, r - 1, color);
}
\ No newline at end of file
#ifndef _GFX_H_
#define _GFX_H_
#include <SDL2/SDL.h>
#include <stdbool.h>
#include <stdint.h>
#define MAKE_COLOR(r, g, b) \
((uint32_t)b | ((uint32_t)g << 8) | ((uint32_t)r << 16))
#define COLOR_GET_B(color) (color & 0xff)
#define COLOR_GET_G(color) ((color >> 8) & 0xff)
#define COLOR_GET_R(color) ((color >> 16) & 0xff)
#define COLOR_TURQUOISE 0x33FFFF
#define COLOR_BLACK 0x00000000
#define COLOR_ORANGE 0xFF8000
#define COLOR_RED 0xFF0000
#define COLOR_GREEN 0x00FF00
#define COLOR_BLUE 0x0066CC
#define COLOR_WHITE 0x00FFFFFF
#define COLOR_YELLOW 0x00FFFF00
struct gfx_context_t
{
SDL_Window *window;
SDL_Renderer *renderer;
SDL_Texture *texture;
uint32_t *pixels;
uint32_t width;
uint32_t height;
};
extern void gfx_putpixel(
struct gfx_context_t *ctxt, uint32_t column, uint32_t row, uint32_t color);
extern void gfx_clear(struct gfx_context_t *ctxt, uint32_t color);
extern struct gfx_context_t *gfx_create(char *text, uint32_t width, uint32_t height);
extern void gfx_destroy(struct gfx_context_t *ctxt);
extern void gfx_present(struct gfx_context_t *ctxt);
extern SDL_Keycode gfx_keypressed();
extern void draw_full_circle(struct gfx_context_t *ctxt, uint32_t c_column, uint32_t c_row, uint32_t r, uint32_t color);
#endif
File added
#include "gfx/gfx.h"
#include "vec2/vec2.h"
#include "planet/planet.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <SDL2/SDL.h>
#define SCREEN_WIDTH 1000
#define SCREEN_HEIGHT 1000
int main()
{
srand(time(NULL));
struct gfx_context_t *ctxt =
gfx_create("Planetary system", SCREEN_WIDTH, SCREEN_HEIGHT);
if (!ctxt)
{
fprintf(stderr, "Graphics initialization failed!\n");
return EXIT_FAILURE;
}
// TODO : create your system
system_t s = create_system(0);
while (true)
{
gfx_present(ctxt);
// TODO : draw the current state of your system
show_system(ctxt, &s);
// TODO : update your system
//gfx_clear(ctxt, COLOR_BLACK);
if (gfx_keypressed() == SDLK_ESCAPE)
{
break;
}
}
// TODO : Free your system
free(s.planets);
gfx_destroy(ctxt);
return EXIT_SUCCESS;
}
\ No newline at end of file
File added
File added
#include "planet.h"
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
//Masse (kg)
#define G 6.67e-11
#define M_SOLEIL 1.989e30
#define M_NAMEK 1.40e25
#define M_MERCURE 3.285e23
#define M_VENUS 4.867e24
#define M_TERRE 5.972e24
#define M_MARS 6.39e23
#define M_AZEROTH 7.20e25
// e = excentricité ; DG = demi-grand axe ; peri = périhelie
planet_t create_planet(double mass, vec2 pos, double e, double DG, double peri){
planet_t p;
p.mass = mass;
p.pos = pos;
p.e = e;
p.DG = DG;
p.peri = peri;
return p;
}
//distances en échelle 1/1 000 000 000(m)
system_t create_system(double delta_t){
system_t s;
s.star = create_planet(M_SOLEIL , vec2_create_zero(), 0, 0, 0);
s.nb_planets = 6;
s.planets = malloc(sizeof(planet_t) * s.nb_planets);
s.planets[4] = create_planet(M_NAMEK , vec2_create(474.1 , 0), 0.01, 34.2, 25.9);
s.planets[0] = create_planet(M_MERCURE , vec2_create(454 , 0), 0.20563069, 58, 46);
s.planets[1] = create_planet(M_VENUS , vec2_create(392.5 , 0), 0.0067733, 108.2, 107.5);
s.planets[2] = create_planet(M_TERRE, vec2_create(352.9 , 0), 0.01671022, 149.6, 147.1);
s.planets[3] = create_planet(M_MARS , vec2_create(293.3 , 0), 0.09341233, 228, 206.7);
s.planets[5] = create_planet(M_AZEROTH , vec2_create(230.2 , 0), 0.01, 280.7, 269.8);
return s;
}
//affichage des planetes rayon 1/ 1 000 000 (m)
void show_system(struct gfx_context_t *ctxt, system_t *system){
planet_t soleil = system->star;
draw_full_circle(ctxt, 500, 500, 5, COLOR_YELLOW);
int posx[system->nb_planets];
int rayon[system->nb_planets];
int couleur[system->nb_planets];
for(int i = 0; i < system->nb_planets ; i++){
double mass = system->planets[i].mass;
if(mass == M_NAMEK){
posx[i] = 474.1;
rayon[i] = 3;
couleur[i] = COLOR_GREEN;
}
else if(mass == M_MERCURE){
posx[i] = 454;
rayon[i] = 2.439;
couleur[i] = COLOR_WHITE;
}
else if(mass == M_VENUS){
posx[i] = 392.5;
rayon[i]= 6.051;
couleur[i] = COLOR_ORANGE;
}
else if(mass == M_TERRE){
posx[i] = 352.9;
rayon[i] = 6.371;
couleur[i] = COLOR_BLUE;
}
else if(mass == M_MARS){
posx[i] = 293.3;
rayon[i] = 6.991;
couleur[i] = COLOR_RED;
}
else{
posx[i] = 230.2;
rayon[i] = 10.45;
couleur[i] = COLOR_TURQUOISE;
}
}
for(int i = 0 ; i < system->nb_planets ; i++){
draw_full_circle(ctxt, posx[i], 500, rayon[i], couleur[i]);
}
}
bool is_equal(planet_t a, planet_t b){
return a.mass == b.mass;
}
vec2 gravite(double massA, double massB, vec2 AB){
vec2 fBA;
fBA.x = G * ((massA * massB) / pow(vec2_norm(AB), 3)) * AB.x;
fBA.y = G * ((massA * massB) / pow(vec2_norm(AB), 3)) * AB.y;
return fBA;
}
vec2 somme_force(system_t system, planet_t p){
vec2 s;
for(int i = 0 ; i < system.nb_planets ; i++){
if(is_equal(p , system.planets[i])){
vec2 g = gravite(system.planets[i].mass, p.mass, vec2_sub(system.planets[i].pos, p.pos));
s.x += g.x;
s.y += g.y;
}
}
return s;
}
vec2 accel(system_t system, planet_t p){
vec2 a = somme_force(system , p);
return vec2_create(a.x / p.mass, a.y / p.mass);
}
vec2 vitesse_i(planet_t p){
vec2 per = vec2_create(-p.pos.y , p.pos.x);
vec2 vi;
vi.x = sqrt((G * M_SOLEIL * (1 + p.e)) / p.DG * (1-p.e)) * per.x / vec2_norm(per);
vi.y = sqrt((G * M_SOLEIL * (1 + p.e)) / p.DG * (1-p.e)) * per.y / vec2_norm(per);
return vi;
}
vec2 pos_init(system_t system, planet_t p, double delta_t){
vec2 v = vitesse_i(p);
vec2 a = accel(system , p);
return vec2_create(p.pos.x + delta_t * v.x + (pow(delta_t, 2) / 2) * a.x, p.pos.y + delta_t * v.y + (pow(delta_t, 2) / 2) * a.y);
}
vec2 pos_update(system_t system, planet_t p, double delta_t){
vec2 a = accel(system , p);
vec2 b = pos_update(system , p, delta_t - 2 * delta_t)
return vec2_create(2 * p.pos.x - b.x + pow(delta_t, 2) * a.x , 2 * p.pos.y - b.y + pow(delta_t, 2) * a.y)
}
\ No newline at end of file
#ifndef _PLANET_H_
#define _PLANET_H_
#include "../vec2/vec2.h"
#include "../gfx/gfx.h"
typedef struct _planet
{
double mass;
vec2 pos; // x(t)
vec2 prec_pos; // x(t - dt)
double e;
double DG;
double peri;
} planet_t;
typedef struct _system
{
planet_t star; // ex. The sun
int nb_planets; // The number of orbiting planets
planet_t *planets; // An array of orbiting planets
} system_t;
// Those function are not mandatory to implement,
// it's rather a hint of what you should have.
planet_t create_planet(double mass, vec2 pos, double e, double DG, double peri);
system_t create_system(double delta_t);
void show_system(struct gfx_context_t *ctxt, system_t *system);
void update_system(system_t *system, double delta_t);
void free_system(system_t *system);
vec2 gravite(double massA, double massB, vec2 AB);
vec2 somme_force(system_t system, planet_t P);
vec2 accel(system_t system, planet_t p);
vec2 vitesse_i(planet_t p);
bool is_equal(planet_t a, planet_t b);
vec2 pos_init(system_t system, planet_t p, double delta_t);
vec2 pos_update(double delta_t);
#endif
\ No newline at end of file
tphpysique @ 0cb39834
Subproject commit 0cb398344bf0f0c108920985e29c14932a7650b6
File added
// TODO : Replace this file by your vec2.c from last tp.
#include "vec2.h"
#include <math.h>
#include <stdio.h>
#define G 6.67e-11
/// Create a 2d vector.
/// @param x_ The first component.
/// @param y_ The second component.
/// @return The newly created vector.
vec2 vec2_create(double x_, double y_) {
vec2 v;
v.x = x_;
v.y = y_;
return v;
}
/// Create a zero 2d vector.
/// @return The newly created zero vector.
vec2 vec2_create_zero() {
return vec2_create(0.0, 0.0);
}
/// Add two vectors.
/// @param lhs The left operand.
/// @param rhs The right operand.
/// @return The sum in a new vector.
vec2 vec2_add(vec2 lhs, vec2 rhs) {
vec2 mhs;
mhs.x = lhs.x+rhs.x;
mhs.y = lhs.y+rhs.y;
return mhs;
}
/// Substract two vectors.
/// @param lhs The left operand.
/// @param rhs The right operand.
/// @return The difference in a new vector.
vec2 vec2_sub(vec2 lhs, vec2 rhs) {
vec2 mhs;
mhs.x = lhs.x-rhs.x;
mhs.y = lhs.y-rhs.y;
return mhs;
}
/// Multiply a vector by a scalar.
/// @param scalar The left operand, a scalar.
/// @param rhs The right operand, a vector.
/// @return The product in a new vector.
vec2 vec2_mul(double scalar, vec2 rhs) {
vec2 vec_mul;
vec_mul.x = scalar*rhs.x;
vec_mul.y = scalar*rhs.y;
return vec_mul;
}
/// Compute the dot product (scalar product) between two vectors.
/// @param lhs The left operand.
/// @param rhs The right operand.
/// @return The dot product.
double vec2_dot(vec2 lhs, vec2 rhs) {
return lhs.x*rhs.x+lhs.y*rhs.y;
}
/// Compute the square of the euclidean norm of a given vector.
/// @param v The vector.
/// @return The square of the norm.
double vec2_norm_sqr(vec2 v) {
double a = pow(v.x,3);
double b = pow(v.y,3);
return a+b;
}
/// Compute the euclidean norm of a given vector.
/// @param v The vector.
/// @return The norm.
double vec2_norm(vec2 v) {
double a = pow(v.x,2);
double b = pow(v.y,2);
return sqrt(a+b);
}
/// Compute the normalization of a given vector.
/// @param v The vector.
/// @return The new normalized vector.
vec2 vec2_normalize(vec2 v) {
double a = pow(v.x,2);
double b = pow(v.y,2);
double norme = sqrt(a+b);
vec2 normalization;
normalization.x = v.x/norme;
normalization.y = v.y/norme;
return normalization;
}
/// Check whether two vectors are approximately equals within a given tolerance.
/// @param lhs The left operand.
/// @param rhs The right operand.
/// @param eps The tolerance.
/// @return true if vector are approximately equal, false otherwise.
bool vec2_is_approx_equal(vec2 lhs, vec2 rhs, double eps) {
// square(pow(lhs.x-rhs.x,2)+pow(lhs.y-rhs.y,2)) <= eps
if(sqrt(pow(lhs.x-rhs.x,2)+pow(lhs.y-rhs.y,2)) <= eps){
return true;
}
return false;
}
/// Compute the coordinates of a 2d vector (with components between 0 and 1)
/// in a given screen matrix.
/// @param v The 2d vector.
/// @param width The screen width.
/// @param height The screen height.
/// @return The coordinates (rwo, column).
coordinates vec2_to_coordinates(vec2 v, uint32_t width, uint32_t height) {
width -= 1;
height -= 1;
double coordinates_x = v.x*width/2 + width/2;
double coordinates_y = v.y*height/2 + height/2;
coordinates new_cor;
new_cor.row = round(coordinates_y);
new_cor.column = round(coordinates_x);
return new_cor;
}
/// Print a vector in the standard output.
/// @param v The vector.
void vec2_print(vec2 v) {
printf("x = %g, y = %g\n", v.x, v.y);
}
#ifndef _VEC2_H_
#define _VEC2_H_
#include <stdbool.h>
#include <stdint.h>
typedef struct _vec2
{
double x, y;
} vec2;
typedef struct _coordinates
{
uint32_t row, column;
} coordinates;
vec2 vec2_create(double x_, double y_);
vec2 vec2_create_zero();
vec2 vec2_add(vec2 lhs, vec2 rhs);
vec2 vec2_sub(vec2 lhs, vec2 rhs);
vec2 vec2_mul(double scalar, vec2 rhs);
double vec2_dot(vec2 lhs, vec2 rhs);
double vec2_norm_sqr(vec2 v);
double vec2_norm(vec2 v);
vec2 vec2_normalize(vec2 v);
bool vec2_is_approx_equal(vec2 lhs, vec2 rhs, double eps);
coordinates vec2_to_coordinates(vec2 v, uint32_t width, uint32_t height);
void vec2_print(vec2 v);
#endif
#include "vec2.h"
#include <stdio.h>
#include <stdbool.h>
#include <math.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++)
{
vec2 v = vec2_create(u_x[i], u_y[i]);
if (u_x[i] != v.x || u_y[i] != v.y)
{
passed = false;
break;
}
}
return (test_result){.passed = passed,
.name = "Test vec2_create 0"};
}
test_result t_vec2_create_zero_0()
{
vec2 v = vec2_create_zero();
return (test_result){.passed = v.x == 0.0 && v.y == 0.0,
.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++)
{
vec2 u = vec2_create(u_x[i], u_y[i]);
vec2 v = vec2_create(v_x[i], v_y[i]);
vec2 r = vec2_add(u, v);
if (!(dbl_eq(r.x, r_x[i]) && dbl_eq(r.y, r_y[i])))
{
passed = false;
break;
}
}
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++)
{
vec2 u = vec2_create(u_x[i], u_y[i]);
vec2 v = vec2_create(v_x[i], v_y[i]);
vec2 r = vec2_sub(u, v);
if (!(dbl_eq(r.x, r_x[i]) && dbl_eq(r.y, r_y[i])))
{
passed = false;
break;
}
}
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];
vec2 u = vec2_create(u_x[i], u_y[i]);
vec2 r = vec2_mul(alpha, u);
if (!(dbl_eq(r.x, r_x[i]) && dbl_eq(r.y, r_y[i])))
{
passed = false;
break;
}
}
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++)
{
vec2 u = vec2_create(u_x[i], u_y[i]);
vec2 v = vec2_create(v_x[i], v_y[i]);
double res = vec2_dot(u, v);
if (!dbl_eq(res, r[i]))
{
passed = false;
break;
}
}
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++)
{
vec2 u = vec2_create(u_x[i], u_y[i]);
double res = vec2_norm_sqr(u);
if (!dbl_eq(res, r[i]))
{
passed = false;
break;
}
}
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++)
{
vec2 u = vec2_create(u_x[i], u_y[i]);
double res = vec2_norm(u);
if (!dbl_eq(res, r[i]))
{
passed = false;
break;
}
}
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++)
{
vec2 u = vec2_create(u_x[i], u_y[i]);
vec2 r = vec2_normalize(u);
if (!(dbl_eq(r.x, r_x[i]) && dbl_eq(r.y, r_y[i])))
{
passed = false;
break;
}
}
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++)
{
vec2 u = vec2_create(u_x[i], u_y[i]);
vec2 t = vec2_create(t_x[i], t_y[i]);
if (vec2_is_approx_equal(u, t, 1e-3) != r[i])
{
passed = false;
break;
}
}
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");
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment