diff --git a/charge/charge.c b/charge/charge.c index 42e91b6290dcac17b238589c63f75aa87a3087d7..2158dfdc2b20123b2103dcc7b6e462ba151edaf3 100644 --- a/charge/charge.c +++ b/charge/charge.c @@ -72,5 +72,46 @@ charge_t charge_create(double q, vec2 pos) { } double random_charge_q(bool positive) { - return rand_one() * (positive ? 1 : -1); + return (rand() % 100) * (positive ? 1 : -1); +} + +vec2 electristatic_force(charge_t a, charge_t b) { + vec2 rab = vec2_sub(b.pos, a.pos); + vec2 res = vec2_mul( + rab, K * (((a.q * 10e-6) * (b.q * 10e-6)) / pow(vec2_norm(rab), 2))); + + printf("COEF: %.25f\n", (a.q * 10e-6) * (b.q * 10e-6)); + return res; +} + +vec2 resulting_electrostatic_force(charge_t *charges, int num_charges, + charge_t a) { + vec2 resulting = vec2_create_zero(); + + for (int i = 0; i < num_charges; i++) { + // Very unlickly to have two charges with the exact same charge + if (charges[i].q == a.q) + continue; + + vec2 ef = electristatic_force(a, charges[i]); + resulting = vec2_add(resulting, ef); + } + + return resulting; +} + +void update_charge_pos(charge_t *charges, int num_charges, charge_t *a) { + vec2 resulting = resulting_electrostatic_force(charges, num_charges, *a); + a->pos = vec2_add(a->pos, resulting); +} + +void update_simulation(charge_t *charges, int num_charges) { + for (int i = 0; i < num_charges; i++) { + vec2 resulting = + resulting_electrostatic_force(charges, num_charges, charges[i]); + printf("RES: %.19f\n", vec2_norm(resulting)); + charges[i].pos = vec2_add(charges[i].pos, resulting); + } + + printf("%.19f, %.19f\n", charges[0].pos.x, charges[0].pos.x); } \ No newline at end of file diff --git a/charge/charge.h b/charge/charge.h index 097fe21859857c0fa949941563d4d0b62aa85d35..57fc6687f5111c5b5e6d10e1001fcdf9a975666a 100644 --- a/charge/charge.h +++ b/charge/charge.h @@ -20,6 +20,7 @@ #include <stdlib.h> #define K 8.988e9 +#define ELEMENTARY_CHARGE 1.602176634e-19 #define CHARGE_RADIUS 10 #define EPS 0.015 #define UNIV_MIN_X 0 @@ -118,4 +119,42 @@ charge_t charge_create(double q, vec2 pos); */ double random_charge_q(bool positive); +/** + * @brief Compute the electrostatic force between two charges + * + * @param a + * @param b + * @return vec2 + */ +vec2 electristatic_force(charge_t a, charge_t b); + +/** + * @brief Compute the resulting electrostatic force + * + * @param charges + * @param num_charges + * @param a + * @return vec2 + */ +vec2 resulting_electrostatic_force(charge_t *charges, int num_charges, + charge_t a); + +/** + * @brief Update the pos of the given charge based on the resulting + * electrostatic force + * + * @param charges + * @param num_charges + * @param a + */ +void update_charge_pos(charge_t *charges, int num_charges, charge_t *a); + +/** + * @brief Update the whole simulation + * + * @param charges + * @param num_charges + */ +void update_simulation(charge_t *charges, int num_charges); + #endif \ No newline at end of file diff --git a/draw/draw.c b/draw/draw.c index e178166fbee66f348d743a45036523ef11c9e2a3..021825507bdf84498ec63dcfde193fdc065f6ab8 100644 --- a/draw/draw.c +++ b/draw/draw.c @@ -202,7 +202,7 @@ void draw_charges(charge_t *charges, int num_charges, int w, int h) { draw_circle(chCoord, CHARGE_RADIUS); char charge_str[8]; - snprintf(charge_str, 8, "%.4f", charges[i].q); + snprintf(charge_str, 8, "%.0f", charges[i].q); vec2 text_pos = vec2_create(chCoord.x, chCoord.y + CHARGE_RADIUS + 4); draw_textbox(text_pos, charge_str); } diff --git a/main.c b/main.c index ae82fc98583f96190a75a6afb2faae1c5aef18fa..f653e82de46a0ae8f6edd717609faea0f919f9ab 100644 --- a/main.c +++ b/main.c @@ -29,6 +29,9 @@ #define UNUSED(x) x #endif +#define ONE_SECOND_IN_MILLISECONDS 1000 +#define REFRESH_RATE 200 + #define WINDOW_WIDTH 800 #define WINDOW_HEIGHT 800 #define NB_CHARGES 5 @@ -42,11 +45,24 @@ int charge_count = NB_CHARGES; vec2 starting_points[NB_POINTS]; vec2 default_charges_pos[MAXIMUM_CHARGES]; double default_charges[MAXIMUM_CHARGES]; +charge_t *charges; -bool toggle_lines_view = true; +bool toggle_lines_view = false; bool toggle_vector_view = false; bool toggle_heatmap_view = false; +void update() { update_simulation(charges, charge_count); }; + +void update_timer() { + update(); + glutTimerFunc(ONE_SECOND_IN_MILLISECONDS / REFRESH_RATE, update_timer, 0); +} + +void draw_timer() { + glutPostRedisplay(); + glutTimerFunc(ONE_SECOND_IN_MILLISECONDS / REFRESH_RATE, draw_timer, 0); +} + /** * @brief Generate a grid of points * @@ -72,11 +88,6 @@ void display() { glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); - // Generate all the charges - charge_t charges[charge_count]; - for (int i = 0; i < charge_count; i++) - charges[i] = charge_create(default_charges[i], default_charges_pos[i]); - if (toggle_heatmap_view) draw_heatmap(charges, charge_count, WINDOW_WIDTH, WINDOW_HEIGHT); @@ -110,6 +121,7 @@ void handle_mouse_input(int button, int state, int x, int y) { if (state == GLUT_UP) return; + // Define new charges attributes if (button == GLUT_LEFT_BUTTON || button == GLUT_RIGHT_BUTTON) { charge_count += 1; default_charges_pos[charge_count - 1] = @@ -122,6 +134,13 @@ void handle_mouse_input(int button, int state, int x, int y) { if (button == GLUT_RIGHT_BUTTON) default_charges[charge_count - 1] = random_charge_q(false); + // Realloc charge array when a new one is added + charges = realloc(charges, sizeof(charge_t) * charge_count); + + // Redefine all charges infos + for (int i = 0; i < charge_count; i++) + charges[i] = charge_create(default_charges[i], default_charges_pos[i]); + glutPostRedisplay(); } @@ -158,12 +177,18 @@ void keyboard(unsigned char key, int UNUSED(x), int UNUSED(y)) { int main(int argc, char **argv) { srand(time(NULL)); + charges = malloc(sizeof(charge_t) * charge_count); + // Generate all default charges for (int i = 0; i < charge_count; i++) { default_charges[i] = random_charge_q((bool)(rand() % 2 == 0)); default_charges_pos[i] = vec2_create(rand_one(), rand_one()); } + // Init charges + for (int i = 0; i < charge_count; i++) + charges[i] = charge_create(default_charges[i], default_charges_pos[i]); + // Generate all field lines starting points generate_points(starting_points); @@ -184,9 +209,14 @@ int main(int argc, char **argv) { glutMouseFunc(handle_mouse_input); glutKeyboardFunc(keyboard); + // glutTimerFunc(ONE_SECOND_IN_MILLISECONDS / REFRESH_RATE, update_timer, + // 0); glutTimerFunc(ONE_SECOND_IN_MILLISECONDS / REFRESH_RATE, draw_timer, + // 0); + glutMainLoop(); // Object destroy glutDestroyWindow(window); + free(charges); return EXIT_SUCCESS; } \ No newline at end of file