diff --git a/Makefile b/Makefile index f41c0962e0c22b9375f2eacb25e272444fb31ada..e02faf1570b6b74d44e37de52a1a44b2ef903e02 100644 --- a/Makefile +++ b/Makefile @@ -59,6 +59,7 @@ $(MARKDOWN): %.markdown: 00_macros.md %.md 10_footer.md deploy: all mkdir -p phys mkdir -p phys/planets + mkdir -p phys/field_lines cp cours.html phys/index.html cp cours.pdf phys/cours.pdf make -C exercices @@ -75,6 +76,11 @@ deploy: all cp practical_work/planets/*.pdf phys/planets/ cp practical_work/planets/*.html phys/planets/ cd practical_work/planets && tar czvf skeleton.tar.gz skeleton && cp *.gz ../../phys/planets + cd .. + make -C practical_work/electric_fl + cp practical_work/electric_fl/*.pdf phys/field_lines/ + cp practical_work/electric_fl/*.html phys/field_lines/ + cd practical_work/electric_fl && tar czvf utils.tar.gz utils && cp *.gz ../../phys/field_lines clean: diff --git a/practical_work/electric_fl/.gitignore b/practical_work/electric_fl/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..1eaef2cb14a56a92ab516ecd669e47dcd92178d6 --- /dev/null +++ b/practical_work/electric_fl/.gitignore @@ -0,0 +1 @@ +!electric_field.pdf \ No newline at end of file diff --git a/practical_work/electric_fl/enonce.md b/practical_work/electric_fl/enonce.md index 008d0005a971dead27c9e140966fd96036c5db5b..6d09cec54e6871f4736274e49331619e5c174ad6 100644 --- a/practical_work/electric_fl/enonce.md +++ b/practical_work/electric_fl/enonce.md @@ -29,7 +29,7 @@ urlcolor: blue # Rappel théorique Comme nous l'avons vu en classe, chaque particule possédant une charge $Q$ -induit un champs $E$ qui modifie l'espace autour d'elle. Il est possible de +induit un champs $E$ qui influe sur l'espace autour d'elle. Il est possible de représenter ce champs électrique à l'aide d'un champs de vecteur. Lorsque que l'on a une seule particule chargée, chaque vecteur décrit en un point l'action induite par la particule chargée à cette distance. L'intensité de ce champs à @@ -43,7 +43,7 @@ particule. {#fig:champ_e +<https://bit.ly/3kUEcGu>.](figs/electric_field.pdf){#fig:champ_e width=50%} En réalité, on rencontre souvent (très souvent) plus d'une particule chargée, @@ -54,16 +54,16 @@ chacune de nos particules chargées. Une autre représentation du champs électrique peut se faire à l'aide de courbes appelées lignes de champs. -{#fig:plus_minus_field +<https://bit.ly/3dPsUk2>.](figs/two_particles_field.png){#fig:plus_minus_field width=80%} Pour réaliser cette simulation numérique, nous devons commencer par définir notre univers discret. Dans le cadre de ce travail, notre univers est un -rectangle $[0,1]\times[0,1]$. +rectangle $[0;1]\times[0;1]$. Chaque particule possède une position appartenant à notre univers, ainsi qu'une charge (multiple de la charge élementaire). @@ -132,8 +132,8 @@ void gfx_draw_circle(struct gfx_context_t *ctxt, coordinates_t c, Pour tester votre fonction de dessin de droites, vous dessinerez dans une fenêtre de 100x100 les droites suivantes : -- $(50,50) \rightarrow (75,50)$, $(50,50) \rightarrow (72,62)$, $(50,50) - \rightarrow (62,72)$ +- $(50,50) \rightarrow (75,50)$^[Le segment reliant le point $(x_0,y_0)$ au +point $(x_1,y_1)$], $(50,50) \rightarrow (72,62)$, $(50,50) \rightarrow (62,72)$ - $(50,50) \rightarrow (50,75)$, $(50,50) \rightarrow (38,72)$, $(50,50) \rightarrow (28,62)$ - $(50,50) \rightarrow (25,50)$, $(50,50) \rightarrow (28,38)$, $(50,50) diff --git a/practical_work/electric_fl/figs/electric_field.pdf b/practical_work/electric_fl/figs/electric_field.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b21029c8e5c304df2a9e5c2b1bb34d62425ec6cf Binary files /dev/null and b/practical_work/electric_fl/figs/electric_field.pdf differ diff --git a/practical_work/electric_fl/figs/two_particles_field.png b/practical_work/electric_fl/figs/two_particles_field.png new file mode 100644 index 0000000000000000000000000000000000000000..2a5dd0b3fb7b5caff2f025e9df2c079069765e6f Binary files /dev/null and b/practical_work/electric_fl/figs/two_particles_field.png differ diff --git a/practical_work/electric_fl/utils/gfx/gfx.c b/practical_work/electric_fl/utils/gfx/gfx.c new file mode 100644 index 0000000000000000000000000000000000000000..cd6662f178c2bc3eb8326efae92ca7fa7436c1c6 --- /dev/null +++ b/practical_work/electric_fl/utils/gfx/gfx.c @@ -0,0 +1,105 @@ +/// @file gfx.c +/// @author Florent Gluck +/// @date November 6, 2016 +/// Helper routines to render pixels in fullscreen graphic mode. +/// Uses the SDL2 library. + +#include "gfx.h" +#include <assert.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; +} \ No newline at end of file diff --git a/practical_work/electric_fl/utils/gfx/gfx.h b/practical_work/electric_fl/utils/gfx/gfx.h new file mode 100644 index 0000000000000000000000000000000000000000..4d9d13a965b264265a47243d650b7a5965a92b81 --- /dev/null +++ b/practical_work/electric_fl/utils/gfx/gfx.h @@ -0,0 +1,40 @@ +#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_BLACK 0x00000000 +#define COLOR_RED 0x00FF0000 +#define COLOR_GREEN 0x0000FF00 +#define COLOR_BLUE 0x000000FF +#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(); + +#endif diff --git a/practical_work/electric_fl/utils.c b/practical_work/electric_fl/utils/utils.c similarity index 100% rename from practical_work/electric_fl/utils.c rename to practical_work/electric_fl/utils/utils.c diff --git a/practical_work/electric_fl/utils.h b/practical_work/electric_fl/utils/utils.h similarity index 100% rename from practical_work/electric_fl/utils.h rename to practical_work/electric_fl/utils/utils.h