diff --git a/README.md b/README.md index b841ca1027fc5d5ce70e611ce7059af6cb99d83e..2424337bb0583ee5640e0e4af6c109872fd63903 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ make ./program ``` -## Windows +### Sur Windows avec MinGW mingw32-make.exe pacman -S mingw-w64-x86_64-SDL2 diff --git a/src/gfx/gfx.c b/src/Graphics.c similarity index 75% rename from src/gfx/gfx.c rename to src/Graphics.c index 8371719fa89c032761b5a0a84c2b3abe51d9bd58..87d6c99a147080d603666740c33c8534df492e17 100644 --- a/src/gfx/gfx.c +++ b/src/Graphics.c @@ -4,13 +4,13 @@ /// Helper routines to render pixels in fullscreen graphic mode. /// Uses the SDL2 library. -#include "gfx.h" +#include "Graphics.h" #include <assert.h> #include <stdint.h> #include <stdlib.h> -#include "../utils.h" +#include "utils.h" /// Create a fullscreen graphic window. /// @param title Title of the window. @@ -52,7 +52,7 @@ error: /// @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) { + if (column < ctxt->width && row < ctxt->height) { ctxt->pixels[ctxt->width * row + column] = color; } } @@ -103,24 +103,25 @@ SDL_Keycode gfx_keypressed() { return 0; } -#include <stdio.h> -void gfx_draw_line(struct gfx_context_t *ctxt, coordinates_t p0, coordinates_t p1, uint32_t color) { - int32_t dx = abs(p1.column - p0.column); - int32_t sx = p0.column < p1.column ? 1 : -1; +// -------------- - int32_t dy = -abs(p1.row - p0.row); - int32_t sy = p0.row < p1.row ? 1 : -1; +void gfx_draw_line(Graphics *graphics, coordinates_t p0, coordinates_t p1, uint32_t color) { + int dx = abs(p1.column - p0.column); + int sx = p0.column < p1.column ? 1 : -1; - int32_t error = dx + dy; + int dy = -abs(p1.row - p0.row); + int sy = p0.row < p1.row ? 1 : -1; + + int error = dx + dy; while (true) { - gfx_putpixel(ctxt, p0.column, p0.row, color); + gfx_putpixel(graphics, p0.column, p0.row, color); if (p0.column == p1.column && p0.row == p1.row) { break; } - int32_t e2 = 2 * error; + int e2 = 2 * error; if (e2 >= dy) { if (p0.column == p1.column) { @@ -142,35 +143,30 @@ void gfx_draw_line(struct gfx_context_t *ctxt, coordinates_t p0, coordinates_t p } } -void gfx_draw_circle(struct gfx_context_t *ctxt, coordinates_t c, 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) - { +void gfx_draw_circle(Graphics *graphics, coordinates_t c, uint32_t r, uint32_t color) { + int x = 0, y = r, d = r - 1; + + while (y >= x) { + gfx_putpixel(graphics, c.column + x, c.row + y, color); + gfx_putpixel(graphics, c.column + y, c.row + x, color); + gfx_putpixel(graphics, c.column - x, c.row + y, color); + gfx_putpixel(graphics, c.column - y, c.row + x, color); + + gfx_putpixel(graphics, c.column + x, c.row - y, color); + gfx_putpixel(graphics, c.column + y, c.row - x, color); + gfx_putpixel(graphics, c.column - x, c.row - y, color); + gfx_putpixel(graphics, 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))) - { + } else if (d < (2 * (((int)r) - y))) { d += 2 * y - 1; y -= 1; - } - else - { + } else { d -= 2 * (x - y + 1); y -= 1; x += 1; } } -} \ No newline at end of file +} diff --git a/src/gfx/gfx.h b/src/Graphics.h similarity index 95% rename from src/gfx/gfx.h rename to src/Graphics.h index ad39e619da1c44302e7fd513db1f3a68b9d6cfe1..d0cd90fcdeb6652e977040e710f0475e1b84396e 100644 --- a/src/gfx/gfx.h +++ b/src/Graphics.h @@ -5,7 +5,7 @@ #include <stdbool.h> #include <stdint.h> -#include "../utils.h" +#include "utils.h" #define MAKE_COLOR(r, g, b) \ ((uint32_t)b | ((uint32_t)g << 8) | ((uint32_t)r << 16)) @@ -30,6 +30,8 @@ struct gfx_context_t { uint32_t height; }; +typedef struct gfx_context_t Graphics; + 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); diff --git a/src/Makefile b/src/Makefile index 585571d8ebe39a947a7899e0f27884d63fba7457..1a5b1b8f659be16e57a33190a3e6184e26765527 100644 --- a/src/Makefile +++ b/src/Makefile @@ -14,13 +14,13 @@ default: $(TARGET) Charge.o: Charge.c Charge.h $(CC) ${CFLAGS} -c $< -main.o: main.c +Graphics.o: Graphics.c Graphics.h $(CC) ${CFLAGS} -c $< -utils.o: utils.c utils.h +main.o: main.c $(CC) ${CFLAGS} -c $< -vector2.o: vector2.c vector2.h +random_number.o: random_number.c random_number.h $(CC) ${CFLAGS} -c $< Rectangle.o: Rectangle.c Rectangle.h @@ -29,13 +29,13 @@ Rectangle.o: Rectangle.c Rectangle.h Simulation.o: Simulation.c Simulation.h $(CC) ${CFLAGS} -c $< -random_number.o: random_number.c random_number.h +utils.o: utils.c utils.h $(CC) ${CFLAGS} -c $< -gfx.o: ./gfx/gfx.c ./gfx/gfx.h +Vector2.o: Vector2.c Vector2.h $(CC) ${CFLAGS} -c $< -$(TARGET): Charge.o main.o utils.o vector2.o gfx.o Rectangle.o Simulation.o random_number.o +$(TARGET): Charge.o main.o utils.o Vector2.o Graphics.o Rectangle.o Simulation.o random_number.o $(CC) -Wall -o $@ $^ $(LIBS) clean: diff --git a/src/Rectangle.c b/src/Rectangle.c index c7ecc26680297ea214299eb67e83aa7ec6e45081..4ee281d69486515e002344f3edfdff987a688c55 100644 --- a/src/Rectangle.c +++ b/src/Rectangle.c @@ -2,12 +2,12 @@ #include <stdlib.h> -#include "vector2.h" +#include "Vector2.h" Rectangle *rectangle_init(int x0, int y0, int x1, int y1) { Rectangle *rectangle = (Rectangle *)malloc(sizeof(Rectangle)); - rectangle->top_left = vector2_create(x0, y0); - rectangle->bottom_right = vector2_create(x1, y1); + rectangle->top_left = vector2_init(x0, y0); + rectangle->bottom_right = vector2_init(x1, y1); return rectangle; } diff --git a/src/Rectangle.h b/src/Rectangle.h index aacb71d9a6547820102162e2698d9d6ec3f65fa0..26462f983cd36fa4afab50550ccdd4608d66b402 100644 --- a/src/Rectangle.h +++ b/src/Rectangle.h @@ -4,8 +4,8 @@ #include "vector2.h" typedef struct Rectangle { - vector2_t top_left; - vector2_t bottom_right; + Vector2 top_left; + Vector2 bottom_right; } Rectangle; Rectangle *rectangle_init(int x0, int y0, int x1, int y1); diff --git a/src/Simulation.c b/src/Simulation.c index eaa128acd7def04e9a54ff3c6f67ef2b270a7a08..b6f868fd7121b76b1847e17b3cbd87658fd7d695 100644 --- a/src/Simulation.c +++ b/src/Simulation.c @@ -3,19 +3,19 @@ #include <stdlib.h> #include "Charge.h" -#include "gfx/gfx.h" +#include "Vector2.h" +#include "Graphics.h" #include "random_number.h" #include "utils.h" -#include "vector2.h" static const int MIN_CHARGES = 2; static const int MAX_CHARGES = 5; -const int CHARGE_CIRCLE_RADIUS = 20; +// const int CHARGE_CIRCLE_RADIUS = 20; const double K = 8.988e9; const double ELEMENTARY_CHARGE = 1.602e-19; static Charge generate_random_charge() { - vector2_t position = vector2_create(random_number_between_0_and_1(), random_number_between_0_and_1()); + Vector2 position = vector2_init(random_number_between_0_and_1(), random_number_between_0_and_1()); int sign = rand() % 2 == 0 ? 1 : -1; return charge_init(ELEMENTARY_CHARGE * sign, position); } @@ -32,29 +32,14 @@ static Charge *generate_random_charges(int *charges_length) { return charges; } -static void draw_charge(Charge charge, struct gfx_context_t *ctxt, Rectangle *universe) { - coordinates_t c = position_to_coordinates(SCREEN_WIDTH, SCREEN_HEIGHT, universe, charge.pos); - - int radius = CHARGE_CIRCLE_RADIUS; - gfx_draw_circle(ctxt, c, radius, COLOR_WHITE); - - int color = charge.q > 0 ? COLOR_RED : COLOR_BLUE; - int half_length = (int)(radius * .6); - gfx_draw_line(ctxt, coordinates_create(c.row, c.column - half_length), coordinates_create(c.row, c.column + half_length), color); - - if (charge.q > 0) { - gfx_draw_line(ctxt, coordinates_create(c.row - half_length, c.column), coordinates_create(c.row + half_length, c.column), color); - } -} - -static void draw_charges(Simulation *simulation, struct gfx_context_t *ctxt) { +static void draw_charges(Simulation *simulation, Graphics *graphics) { for (int i = 0; i < simulation->charges_length; i++) { - draw_charge(simulation->charges[i], ctxt, simulation->universe); + charge_draw(simulation->charges[i], graphics, simulation->universe); } } -static bool compute_e(Charge charge, vector2_t p, double eps, vector2_t *e) { - vector2_t r = vector2_substract(charge.pos, p); +static bool compute_e(Charge charge, Vector2 point, double eps, Vector2 *e) { + Vector2 r = vector2_substract(charge.position, point); double e_intensity = K * fabs(charge.q) / vector2_norm_sqr(r); *e = vector2_multiply(vector2_normalize(r), e_intensity); @@ -65,12 +50,12 @@ static bool compute_e(Charge charge, vector2_t p, double eps, vector2_t *e) { return vector2_norm(r) >= eps; } -static bool compute_total_normalized_e(int charges_length, Charge *charges, vector2_t p, double eps, vector2_t *e) { - *e = vector2_create_zero(); +static bool compute_total_normalized_e(int charges_length, Charge *charges, Vector2 point, double eps, Vector2 *e) { + *e = vector2_init_zero(); for (int i = 0; i < charges_length; i += 1) { - vector2_t e_i; - if (!compute_e(charges[i], p, eps, &e_i)) { + Vector2 e_i; + if (!compute_e(charges[i], point, eps, &e_i)) { return false; } @@ -81,17 +66,17 @@ static bool compute_total_normalized_e(int charges_length, Charge *charges, vect return true; } -static bool is_out_of_bounds(Rectangle *universe, vector2_t point) { +static bool is_out_of_bounds(Rectangle *universe, Vector2 point) { return point.x < universe->top_left.x || point.x > universe->bottom_right.x || point.y < universe->top_left.y || point.y > universe->bottom_right.y; } -static bool compute_next_point(Rectangle *universe, int charges_length, Charge *charges, vector2_t current_pos, double eps, double dx, int direction, vector2_t *next_point) { - vector2_t electric_field; - if (!compute_total_normalized_e(charges_length, charges, current_pos, eps, &electric_field)) { +static bool compute_next_point(Rectangle *universe, int charges_length, Charge *charges, Vector2 current_point, double eps, double dx, int direction, Vector2 *next_point) { + Vector2 electric_field; + if (!compute_total_normalized_e(charges_length, charges, current_point, eps, &electric_field)) { return false; } - *next_point = vector2_add(current_pos, vector2_multiply(vector2_multiply(electric_field, dx), direction)); + *next_point = vector2_add(current_point, vector2_multiply(vector2_multiply(electric_field, dx), direction)); if (is_out_of_bounds(universe, *next_point)) { return false; @@ -100,28 +85,28 @@ static bool compute_next_point(Rectangle *universe, int charges_length, Charge * return true; } -static void draw_field_line_with_direction(struct gfx_context_t *ctxt, Rectangle *universe, int charges_length, Charge *charges, double dx, vector2_t pos0, int direction) { - vector2_t current_point = pos0; +static void draw_field_line_with_direction(Graphics *graphics, Rectangle *universe, int charges_length, Charge *charges, double dx, Vector2 starting_point, int direction) { + Vector2 current_point = starting_point; while (true) { - vector2_t next_point; + Vector2 next_point; if (!compute_next_point(universe, charges_length, charges, current_point, 0.027, dx, direction, &next_point)) { break; } coordinates_t current_coordinates = position_to_coordinates(SCREEN_WIDTH, SCREEN_HEIGHT, universe, current_point); coordinates_t next_coordinates = position_to_coordinates(SCREEN_WIDTH, SCREEN_HEIGHT, universe, next_point); - gfx_draw_line(ctxt, current_coordinates, next_coordinates, COLOR_WHITE); + gfx_draw_line(graphics, current_coordinates, next_coordinates, COLOR_WHITE); current_point = next_point; } } -static void draw_field_line(struct gfx_context_t *ctxt, Rectangle *universe, int charges_length, Charge *charges, double dx, vector2_t pos0) { - draw_field_line_with_direction(ctxt, universe, charges_length, charges, dx, pos0, -1); - draw_field_line_with_direction(ctxt, universe, charges_length, charges, dx, pos0, 1); +static void draw_field_line(Graphics *graphics, Rectangle *universe, int charges_length, Charge *charges, double dx, Vector2 starting_point) { + draw_field_line_with_direction(graphics, universe, charges_length, charges, dx, starting_point, -1); + draw_field_line_with_direction(graphics, universe, charges_length, charges, dx, starting_point, 1); } -// --- +// Visible functions. Simulation *simulation_init(Rectangle *universe, double delta_x) { Simulation *simulation = (Simulation *)malloc(sizeof(Simulation)); @@ -131,24 +116,24 @@ Simulation *simulation_init(Rectangle *universe, double delta_x) { return simulation; } -void simulation_draw(Simulation *simulation, struct gfx_context_t *ctxt) { - draw_charges(simulation, ctxt); +void simulation_draw(Simulation *simulation, Graphics *graphics) { + draw_charges(simulation, graphics); // // Drawing of field lines from randomly placed points. // int number_random_points = 100; // for (int i = 0; i < number_random_points; i += 1) { - // draw_field_line(canvas, charges, charges_length, delta_x, vector2_create(random_number_between_0_and_1(), random_number_between_0_and_1()), x0, x1, y0, y1); + // draw_field_line(canvas, charges, charges_length, delta_x, vector2_init(random_number_between_0_and_1(), random_number_between_0_and_1()), x0, x1, y0, y1); // } // Drawing of the field lines from points placed around each of the particles (the display is more homogeneous with this technique). for (int32_t i = 0; i < simulation->charges_length; i += 1) { - vector2_t pos = simulation->charges[i].pos; + Vector2 pos = simulation->charges[i].position; double angle = 0; while (angle < 2 * M_PI) { angle += 2 * M_PI / 64; - vector2_t pos0 = vector2_add(pos, vector2_create(cos(angle) * 0.1, sin(angle) * 0.1)); - draw_field_line(ctxt, simulation->universe, simulation->charges_length, simulation->charges, simulation->delta_x, pos0); + Vector2 starting_point = vector2_add(pos, vector2_init(cos(angle) * 0.1, sin(angle) * 0.1)); + draw_field_line(graphics, simulation->universe, simulation->charges_length, simulation->charges, simulation->delta_x, starting_point); } } } diff --git a/src/Simulation.h b/src/Simulation.h index bed10866594efd614f6155c90cd3f0e6a53b44ae..a66de1ce6246c277eeb46f4b1a3f8debec6cefb1 100644 --- a/src/Simulation.h +++ b/src/Simulation.h @@ -2,8 +2,8 @@ #define SIMULATION_H #include "Charge.h" +#include "Graphics.h" #include "Rectangle.h" -#include "gfx/gfx.h" typedef struct Simulation { Rectangle *universe; @@ -14,6 +14,6 @@ typedef struct Simulation { Simulation *simulation_init(Rectangle *universe, double delta_x); void simulation_destroy(Simulation **simulation); -void simulation_draw(Simulation *simulation, struct gfx_context_t *ctxt); +void simulation_draw(Simulation *simulation, Graphics *graphics); #endif diff --git a/src/charge.c b/src/charge.c index 061c76f6c499cadc0841277eac9da3a3b991aa31..20f9e24e28ef49e44c5dbc08e6cf7173689d3580 100644 --- a/src/charge.c +++ b/src/charge.c @@ -1,7 +1,27 @@ #include "Charge.h" -#include "vector2.h" +#include "Rectangle.h" +#include "Vector2.h" +#include "Graphics.h" +#include "utils.h" -Charge charge_init(double q, vector2_t pos) { - return (Charge){.q = q, .pos = pos}; +const int CHARGE_CIRCLE_RADIUS = 20; + +Charge charge_init(double q, Vector2 position) { + return (Charge){.q = q, .position = position}; +} + +void charge_draw(Charge charge, Graphics *graphics, Rectangle *universe) { + coordinates_t c = position_to_coordinates(SCREEN_WIDTH, SCREEN_HEIGHT, universe, charge.position); + + int radius = CHARGE_CIRCLE_RADIUS; + gfx_draw_circle(graphics, c, radius, COLOR_WHITE); + + int color = charge.q > 0 ? COLOR_RED : COLOR_BLUE; + int half_length = (int)(radius * .6); + gfx_draw_line(graphics, coordinates_create(c.row, c.column - half_length), coordinates_create(c.row, c.column + half_length), color); + + if (charge.q > 0) { + gfx_draw_line(graphics, coordinates_create(c.row - half_length, c.column), coordinates_create(c.row + half_length, c.column), color); + } } diff --git a/src/charge.h b/src/charge.h index e2af4bccbc40919d708e8f0a94f4a48bf8f5231d..418ae7be11d2baba13edba0536bf108db094e795 100644 --- a/src/charge.h +++ b/src/charge.h @@ -1,13 +1,18 @@ #ifndef CHARGE_H #define CHARGE_H -#include "vector2.h" +#include "Vector2.h" +#include "Graphics.h" +#include "Rectangle.h" + +extern const int CHARGE_CIRCLE_RADIUS; typedef struct Charge { double q; - vector2_t pos; + Vector2 position; } Charge; -Charge charge_init(double q, vector2_t pos); +Charge charge_init(double q, Vector2 position); +void charge_draw(Charge charge, Graphics *graphics, Rectangle *universe); #endif diff --git a/src/main.c b/src/main.c index cb890c8a0c28d098750fc3751db6122cc43d1762..8a96d3a8e737f9a24b25b25e6ee32bebd4aca658 100644 --- a/src/main.c +++ b/src/main.c @@ -1,38 +1,46 @@ #include <math.h> -// #include <stdio.h> #include <stdlib.h> #include <time.h> +#include "Graphics.h" #include "Rectangle.h" #include "Simulation.h" -#include "gfx/gfx.h" #include "utils.h" +// https://stackoverflow.com/questions/3417837/what-is-the-best-way-to-suppress-a-unused-variable-x-warning +#ifdef UNUSED +#elif defined(__GNUC__) +#define UNUSED(x) UNUSED_##x __attribute__((unused)) +#elif defined(__LCLINT__) +#define UNUSED(x) /*@unused@*/ x +#else +#define UNUSED(x) x +#endif + static const int UNIVERSE_X0 = 0; static const int UNIVERSE_Y0 = 0; static const int UNIVERSE_X1 = 1; static const int UNIVERSE_Y1 = 1; double compute_delta_x(int width, int height) { - return 1.0 / sqrt((width * width) + (height * height)); + return 1 / sqrt((width * width) + (height * height)); } -int main(int argc, char *argv[]) { - srand(time(NULL)); - struct gfx_context_t *canvas = gfx_create("Field Lines Simulation", SCREEN_WIDTH, SCREEN_HEIGHT); +int main(int UNUSED(argc), char *UNUSED(argv[])) { + Graphics *graphics = gfx_create("Field Lines Simulation", SCREEN_WIDTH, SCREEN_HEIGHT); + // srand(time(NULL)); + srand(0); - if (!canvas) { + if (graphics == NULL) { fprintf(stderr, "Graphic initialization failed!\n"); return EXIT_FAILURE; } - gfx_clear(canvas, COLOR_BLACK); - + gfx_clear(graphics, COLOR_BLACK); Rectangle *universe = rectangle_init(UNIVERSE_X0, UNIVERSE_Y0, UNIVERSE_X1, UNIVERSE_Y1); Simulation *simulation = simulation_init(universe, compute_delta_x(SCREEN_WIDTH, SCREEN_HEIGHT)); - simulation_draw(simulation, canvas); - - gfx_present(canvas); + simulation_draw(simulation, graphics); + gfx_present(graphics); while (true) { if (gfx_keypressed() == SDLK_ESCAPE) { @@ -40,6 +48,6 @@ int main(int argc, char *argv[]) { } } - gfx_destroy(canvas); + gfx_destroy(graphics); return EXIT_SUCCESS; } diff --git a/src/utils.c b/src/utils.c index 95e3691f2dde7bd3988d5c1b1d16d56850438f0d..a7ec0d1eab0563585d716cbf1dc4818f027b78a6 100644 --- a/src/utils.c +++ b/src/utils.c @@ -4,7 +4,7 @@ #include <stdlib.h> #include "Rectangle.h" -#include "vector2.h" +#include "Vector2.h" const int SCREEN_WIDTH = 750; const int SCREEN_HEIGHT = 750; @@ -14,7 +14,7 @@ coordinates_t coordinates_create(int row_, int column_) { return c; } -coordinates_t position_to_coordinates(int width, int height, Rectangle *universe, vector2_t pos) { +coordinates_t position_to_coordinates(int width, int height, Rectangle *universe, Vector2 pos) { double dx = universe->bottom_right.x - universe->top_left.x; double dy = universe->bottom_right.y - universe->top_left.y; return coordinates_create((int)round(height * (pos.y - universe->top_left.y) / dy), (int)round(width * (pos.x - universe->top_left.x) / dx)); diff --git a/src/utils.h b/src/utils.h index 25b9acd2d85cb8037d8d1789354b7cf39adbe2ba..0e5a5815e0b3c22933f433ee4b4b7e65ebd5106a 100644 --- a/src/utils.h +++ b/src/utils.h @@ -4,7 +4,7 @@ #include <stdint.h> #include "Rectangle.h" -#include "vector2.h" +#include "Vector2.h" extern const int SCREEN_WIDTH; extern const int SCREEN_HEIGHT; @@ -15,6 +15,6 @@ typedef struct _coordinates_t { } coordinates_t; coordinates_t coordinates_create(int row_, int column_); -coordinates_t position_to_coordinates(int width, int height, Rectangle *universe, vector2_t pos); +coordinates_t position_to_coordinates(int width, int height, Rectangle *universe, Vector2 pos); #endif diff --git a/src/vector2.c b/src/vector2.c index 119e0e9e35edbc588ac3daa5c5affe8a65106f3e..af41282bb0e5ab5dfa250eb2b2bd258ac50c7b3a 100644 --- a/src/vector2.c +++ b/src/vector2.c @@ -1,53 +1,43 @@ -#include "vector2.h" +#include "Vector2.h" #include <math.h> #include <stdbool.h> #include <stdint.h> #include <stdio.h> -vector2_t vector2_create(double x, double y) { - return (vector2_t){.x = x, .y = y}; +Vector2 vector2_init(double x, double y) { + return (Vector2){.x = x, .y = y}; } -vector2_t vector2_create_zero() { - return vector2_create(0, 0); +Vector2 vector2_init_zero() { + return vector2_init(0, 0); } -vector2_t vector2_add(vector2_t a, vector2_t b) { - return vector2_create(a.x + b.x, a.y + b.y); +Vector2 vector2_add(Vector2 a, Vector2 b) { + return vector2_init(a.x + b.x, a.y + b.y); } -vector2_t vector2_substract(vector2_t a, vector2_t b) { - return vector2_create(a.x - b.x, a.y - b.y); +Vector2 vector2_substract(Vector2 a, Vector2 b) { + return vector2_init(a.x - b.x, a.y - b.y); } -vector2_t vector2_multiply(vector2_t v, double scalar) { - return vector2_create(v.x * scalar, v.y * scalar); +Vector2 vector2_multiply(Vector2 v, double scalar) { + return vector2_init(v.x * scalar, v.y * scalar); } -double vector2_dot_product(vector2_t a, vector2_t b) { +double vector2_dot_product(Vector2 a, Vector2 b) { return a.x * b.x + a.y * b.y; } -double vector2_norm_sqr(vector2_t v) { +double vector2_norm_sqr(Vector2 v) { return vector2_dot_product(v, v); } -double vector2_norm(vector2_t v) { +double vector2_norm(Vector2 v) { return sqrt(vector2_norm_sqr(v)); } -vector2_t vector2_normalize(vector2_t v) { +Vector2 vector2_normalize(Vector2 v) { double norm = vector2_norm(v); - return vector2_create(v.x / norm, v.y / norm); -} - -vector2_t vector2_fit_canvas(vector2_t 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); -} - -void vector2_print(vector2_t v) { - printf("(%.40lf, %.40lf)\n", v.x, v.y); + return vector2_init(v.x / norm, v.y / norm); } diff --git a/src/vector2.h b/src/vector2.h index 4cc82d7538a6d27663c3f81c856f1b966c49017c..05eedb51d26b65e98943faba8cdce7779d2b5583 100644 --- a/src/vector2.h +++ b/src/vector2.h @@ -4,102 +4,19 @@ #include <stdbool.h> #include <stdint.h> -typedef struct _vector2_t { +typedef struct Vector2 { double x; double y; -} vector2_t; - -/** - * @brief Creates a new Vector2. - * - * @param x - * @param y - * @return Vector2 - */ -vector2_t vector2_create(double x, double y); - -/** - * @brief Creates a new Vector2 where x=0 and y=0. - * - * @return Vector2 - */ -vector2_t vector2_create_zero(); - -/** - * @brief Sum two vectors and return the result in a new one. - * - * @param a - * @param b - * @return Vector2 - */ -vector2_t vector2_add(vector2_t a, vector2_t b); - -/** - * @brief Subtract two vectors and return the result in a new one. - * - * @param a - * @param b - * @return Vector2 - */ -vector2_t vector2_substract(vector2_t a, vector2_t b); - -/** - * @brief Multiply two vectors and return the result in a new one. - * - * @param v - * @param scalar - * @return Vector2 - */ -vector2_t vector2_multiply(vector2_t v, double scalar); - -/** - * @brief Computes the dot product of two vectors. - * - * @param a - * @param b - * @return double - */ -double vector2_dot_product(vector2_t a, vector2_t b); - -/** - * @brief Calculates the norm of a vector and returns the square of the norm. - * - * @param v - * @return double - */ -double vector2_norm_sqr(vector2_t v); - -/** - * @brief Calculates the norm of a vector. - * - * @param v - * @return double - */ -double vector2_norm(vector2_t v); - -/** - * @brief Normalizes a vector and return the result in a new one. - * - * @param v - * @return Vector2 - */ -vector2_t vector2_normalize(vector2_t v); - -/** - * @brief Convert a vector (-1 to 1) into a width x height rectangle. - * - * @param v - * @param width - * @param height - * @return Vector2 - */ -vector2_t vector2_fit_canvas(vector2_t v, int32_t width, int32_t height); - -/** - * @brief Displays a vector in the console. - * - * @param v - */ -void vector2_print(vector2_t v); +} Vector2; + +Vector2 vector2_init(double x, double y); +Vector2 vector2_init_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); #endif