diff --git a/src/draw.c b/src/draw.c index 3f592432c7f1a4677dc7b0e46bc00ea61ced160a..41f141701bb1b44157814233204bb88227c4500c 100644 --- a/src/draw.c +++ b/src/draw.c @@ -35,28 +35,28 @@ 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 c, uint32_t r, uint32_t color) { - int x = 0; - int y = r; - int d = r - 1; - while (y >= x) { - gfx_putpixel(ctxt, c.row + x, c.column + y, color); - gfx_putpixel(ctxt, c.row + y, c.column + x, color); - gfx_putpixel(ctxt, c.row - x, c.column + y, color); - gfx_putpixel(ctxt, c.row - y, c.column + x, color); - gfx_putpixel(ctxt, c.row + x, c.column - y, color); - gfx_putpixel(ctxt, c.row + y, c.column - x, color); - gfx_putpixel(ctxt, c.row - x, c.column - y, color); - gfx_putpixel(ctxt, c.row - y, c.column - x, color); - if (d >= 2 * x) { - d = d - 2 * x - 1; - x++; - } else if (d < 2 * (r - y)) { - d = d + 2 * y - 1; - y--; - } else { - d = d + 2 * (y - x - 1); - y--; - x++; - } - } + int x = 0; + int y = r; + int 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(d >= 2*x){ + d = d-2*x-1; + x++; + }else if(d < 2 * (r-y)){ + d = d + 2*y-1; + y--; + }else { + d = d + 2 * (y-x-1); + y--; + x++; + } + } } diff --git a/src/field.c b/src/field.c index 173d618c2d191a069a0c6fd13e3549ee8952dc7d..1e0d717b5f6b77288ccca0286eba3045049990e1 100644 --- a/src/field.c +++ b/src/field.c @@ -3,12 +3,12 @@ #include "draw.h" #include "field.h" - +#include "draw.h" +#include "../utils/utils.h" #define SIGN_SIZE 10 #define CHARGE_R 25 - // Compute E*qP/norm(qP) // Return false if norm(qP) < eps /// qP = vectoriel(P-q) @@ -34,41 +34,98 @@ bool compute_total_normalized_e(charge_t *charges, int num_charges, vec2 p, doub return true; } +double compute_delta_x(){ + double result = pow(WID, 2) + pow(HEI, 2); + result = sqrt(result); + return 1 / result; +} + +bool is_in_screen(coordinates_t pos){ + if(pos.column > WID || pos.column < 0) + return false; + + if(pos.row > HEI || pos.row < 0) + return false; + + return true; +} + +bool draw_field_line_point(struct gfx_context_t *ctxt, charge_t *charges, int num_charges, double x0, double x1, double y0, double y1, vec2 pos, vec2 *pos_next, double delta){ + vec2 e; + compute_total_normalized_e(charges, num_charges, pos, 0.01, &e); + double norm_e = vec2_norm(e); + + pos_next->x = pos.x + delta * (e.x / norm_e); + pos_next->y = pos.y + delta * (e.y / norm_e); + coordinates_t coordinate_pos = position_to_coordinates(WID, HEI, x0, x1, y0, y1, pos); + coordinates_t coordinate_pos_next = position_to_coordinates(WID, HEI, x0, x1, y0, y1, *pos_next); + + gfx_draw_line(ctxt, coordinate_pos, coordinate_pos_next, COLOR_YELLOW); + + return !is_in_screen(coordinate_pos); +} + +bool line_reach_charge(vec2 pos, charge_t * charges, double num_charges, double dx){ + for (int j = 0; j < num_charges; j++){ + if(vec2_norm(vec2_sub(pos, charges[j].pos)) < dx / HEI){ + return true; + } + } + return false; +} + // Compute and then draw all the points belonging to a field line, // starting from pos0. // Returns false if pos0 is not a valid position // (for example if pos0 is too close to a charge). -static bool -draw_field_line(struct gfx_context_t *ctxt, charge_t *charges, int num_charges, double dx, vec2 pos0, double x0, - double x1, double y0, double y1) { - return EXIT_SUCCESS; +static bool draw_field_line(struct gfx_context_t *ctxt, charge_t *charges, int num_charges, double dx, vec2 pos0, double x0, double x1, double y0, double y1) { + vec2 pos_positive = vec2_create(pos0.x, pos0.y); + vec2 pos_negative = vec2_create(pos0.x, pos0.y); + vec2 pos_next_positive; + vec2 pos_next_negative; + bool stop = false; + // * 5 à supprimer lorsque le code est optimisé + double delta = compute_delta_x() * 5; + int max_for = 50; + for (int i = 0; i < max_for && !stop; i++) + { + stop = line_reach_charge(pos_positive, charges, num_charges, dx) || line_reach_charge(pos_negative, charges, num_charges, dx); + if(!stop){ + stop = draw_field_line_point(ctxt, charges, num_charges, x0, x1, y0, y1, pos_positive, &pos_next_positive, delta) || + draw_field_line_point(ctxt, charges, num_charges, x0, x1, y0, y1, pos_negative, &pos_next_negative, -delta); + pos_positive = pos_next_positive; + pos_negative = pos_next_negative; + } + } + + return !stop; } // Draw all the charges // A circle with minus sign for negative charges // A circle with a plus sign for positive charges -static void -draw_charges(struct gfx_context_t *context, charge_t *charges, int num_charges, double x0, double x1, double y0, - double y1) { - for (int i = 0; i < num_charges; i++) { - coordinates_t charge_center = position_to_coordinates(CHARGE_R, CHARGE_R, x0, x1, y0, y1, charges[i].pos); +static void draw_charges(struct gfx_context_t *context, charge_t *charges, int num_charges, double x0, double x1, double y0, double y1) { + for (int i = 0; i < num_charges; i++) + { + coordinates_t charge_center = position_to_coordinates(WID, HEI, x0, x1, y0, y1, charges[i].pos); gfx_draw_circle(context, charge_center, CHARGE_R, COLOR_WHITE); - coordinates_t sign_dst; + coordinates_t sign_src = charge_center; + coordinates_t sign_dst = charge_center; uint32_t sign_color = COLOR_RED; if (charges[i].q > 0) { sign_color = COLOR_BLUE; - sign_dst.row = charge_center.row + SIGN_SIZE; - gfx_draw_line(context, charge_center, sign_dst, sign_color); - sign_dst.row = charge_center.row - SIGN_SIZE; - gfx_draw_line(context, charge_center, sign_dst, sign_color); + sign_src.row -= SIGN_SIZE; + sign_dst.row += SIGN_SIZE; + gfx_draw_line(context, sign_src, sign_dst, sign_color); + sign_src.row = charge_center.row; + sign_dst.row = charge_center.row; } - sign_dst.column = charge_center.column + SIGN_SIZE; - gfx_draw_line(context, charge_center, sign_dst, sign_color); - sign_dst.column = charge_center.column - SIGN_SIZE; - gfx_draw_line(context, charge_center, sign_dst, sign_color); + sign_src.column -= SIGN_SIZE; + sign_dst.column += SIGN_SIZE; + gfx_draw_line(context, sign_src, sign_dst, sign_color); } } @@ -80,9 +137,10 @@ void draw_everything( double dx, double x0, double x1, double y0, double y1) { + srand(time(NULL)); draw_charges(ctxt, charges, num_charges, x0, x1, y0, y1); for (int i = 0; i < num_lines; ++i) { - vec2 pos0 = vec2_normalize(vec2_create(rand(), rand())); + vec2 pos0 = vec2_create(rand_one(), rand_one()); draw_field_line(ctxt, charges, num_charges, dx, pos0, x0, x1, y0, y1); } } diff --git a/src/field.h b/src/field.h index 89f707c84214ff3100248d2d0814abf60528269c..6266ea334e67d0e42473e9f51d03d6aa9302fbdd 100644 --- a/src/field.h +++ b/src/field.h @@ -6,6 +6,10 @@ #include "../utils/utils.h" #include <stdio.h> +#define SIDE_LEN 1000 +#define WID SIDE_LEN +#define HEI WID + // Compute E*qP/norm(qP) // Return false if norm(qP) < eps bool compute_e(charge_t c, vec2 p, double eps, vec2 *e); @@ -18,16 +22,12 @@ bool compute_total_normalized_e(charge_t *charges, int num_charges, vec2 p, doub // starting from pos0. // Returns false if pos0 is not a valid position // (for example if pos0 is too close to a charge). -static bool -draw_field_line(struct gfx_context_t *ctxt, charge_t *charges, int num_charges, double dx, vec2 pos0, double x0, - double x1, double y0, double y1); +static bool draw_field_line(struct gfx_context_t *ctxt, charge_t *charges, int num_charges, double dx, vec2 pos0, double x0, double x1, double y0, double y1); // Draw all the charges // A circle with minus sign for negative charges // A circle with a plus sign for positive charges -static void -draw_charges(struct gfx_context_t *context, charge_t *charges, int num_charges, double x0, double x1, double y0, - double y1); +static void draw_charges(struct gfx_context_t *context, charge_t *charges, int num_charges, double x0, double x1, double y0, double y1); void draw_everything( struct gfx_context_t *ctxt, diff --git a/src/main.c b/src/main.c index 0cbdf1a8a0ee265cba4c5ffd5cf8ae726bf99395..c9d41edbc2f42113f671a8d58d2988a30befb50d 100644 --- a/src/main.c +++ b/src/main.c @@ -4,24 +4,22 @@ #include "draw.h" #include "field.h" #include "../utils/utils.h" +#include "field.h" - -#define SIDE_LEN 1000 -#define WID SIDE_LEN -#define HEI WID #define NCHARGES 2 -#define DX 0.0005 -#define NLINES 32 +#define DX 25 +#define NLINES 5 int main() { - srand(time(NULL)); charge_t charges[NCHARGES] = { - {.q=-0.25, .pos=vec2_create(0.25, 0.5)}, - {.q=0.25, .pos=vec2_create(0.75, 0.5)}, + charge_create(-0.25, vec2_create(0.25, 0.5)), + charge_create(0.25, vec2_create(0.75, 0.5)) }; struct gfx_context_t *ctxt = gfx_create("elec", WID, HEI); + draw_everything(ctxt, charges, NCHARGES, NLINES, DX, 0.0, 1.0, 0.0, 1.0); + while (gfx_keypressed() != SDLK_ESCAPE) gfx_present(ctxt); gfx_destroy(ctxt); return EXIT_SUCCESS;