Skip to content
Snippets Groups Projects
Verified Commit f41d693a authored by orestis.malaspin's avatar orestis.malaspin
Browse files
parents d9c79fe3 c8320a34
Branches
No related tags found
No related merge requests found
......@@ -623,7 +623,7 @@ width=80%}
Pour visualiser un champs électrique, on utilise en général une série de lignes
pour indiquer la direction du champs électrique (on s'intéresse plus à sont amplitude
dans ce cas). On parle alors des **lignes de champs électrique** et sont dessinées
pour indiquer la direction de la force dûe à des carges électriques sur une charge test
pour indiquer la direction de la force dûe à des charges électriques sur une charge test
*positive*. Cette convention implique que les lignes de champs sont **sortantes** pour une
charge *positive* et *entrantes* pour une charge négative (voir @fig:plus_minus_field)
......@@ -895,4 +895,3 @@ $$
\Phi_E=E_\perp\cdot \Delta S.
$$
* La **loi de Gauss** nous dit que le flux total au travers d'une **surface fermée** est proportionnel à la charge se trouvant à l'intérieur de la surface.
......@@ -68,6 +68,8 @@ deploy: all
mkdir -p phys/practical_work
cp practical_work/*.html phys/practical_work
cp practical_work/*.pdf phys/practical_work
ls -ltr
cd practical_work/ && tar cvf tp_vec2.tar.gz tp_vec2/ && cp tp_vec2.tar.gz ../phys/practical_work
clean:
rm -f *.html *.pdf $(MARKDOWN) $(PDF) $(TEX) $(HTML)
......
---
# author:
# - Orestis Malaspinas
# - Michaël El Kharroubi (correction)
title: Exercices électrostatique
subtitle: Loi de Coulomb et champs électrique
autoSectionLabels: true
......@@ -57,4 +58,178 @@ uniforme $E=10^3\mathrm{N}/\mathrm{C}$ avec une face perpendiculaire au champs
1. Que vaut le flux total à travers la surface du cube?
2. Que vaut le flux à travers chaque surface du cube?
# Correction {.unnumbered}
## Ex 1: {.unnumbered}
\begin{align*}
e&= 1.6022\cdot10^{-19}C\qquad m_e = 9\cdot 10^{-31}kg\\
m&= 10g = 10^{-2}kg\\
Q&= 1\mu C= 10^{-6}C
\end{align*}
Pour gagner une charge de $1\mu C$, il faut perdre un certain nombre d'électrons $n$. On sait que la charge de l'électron est de $-e$. Il suffit donc de calculer le poids des électrons perdus. On commence par calculer $n$ :
\begin{align*}
n = \frac{Q}{e}
\end{align*}
On sait que la masse perdue $m_{perdue}$ vaut :
\begin{align*}
m_{perdue}=m_e\cdot n
\end{align*}
Pour savoir le pourcentage de masse perdu, il suffit de faire :
\begin{align*}
100\cdot(1-\frac{m-m_{perdue}}{m}) = 100\cdot(1-\frac{m-n\cdot m_e}{m}) = 100\cdot(1-\frac{m-\frac{m_e\cdot Q}{e}}{m})
\end{align*}
Ce qui nous donne :
\begin{align*}
&100\cdot(1-\frac{10^{-2}-\frac{9\cdot10^{-31}\cdot10^{-6}}{1.6022\cdot10^{-19}}}{10^{-2}}) = 100\cdot(1-\frac{10^{-2}-\frac{9\cdot10^{-37}}{1.6022\cdot10^{-19}}}{10^{-2}})\\=100\cdot(1-\frac{10^{-2}-\frac{9}{1.6022}\cdot10^{-18}}{10^{-2}})=100\cdot (1-1+\frac{9}{1.6022}\cdot10^{-16})\\
&= 100\cdot \frac{9}{1.6022}\cdot10^{-16}=\frac{9}{1.6022}\cdot10^{-14}\approx5.62\cdot10^{-14}\%
\end{align*}
Notre objet a donc perdu environ $5.62\cdot10^{-14}\%$ de sa masse.
## Ex 2: {.unnumbered}
\begin{align*}
E&=\frac{1}{4\pi\epsilon_0}\frac{Q}{r^2}\\
Q_1&=-5\mu C=-5\cdot10^{-6}C\qquad Q_2=7\mu C=7\cdot10^{-6}C\\
d&=10cm=10^{-1}m
\end{align*}
Pour calculer le champs électrique résultant entre deux charges, on se sert du principe de superposition :
\begin{align*}
E&=\sum_{i} E_i\\
E&= E_1+E_2
\end{align*}
On a donc :
\begin{align*}
E_1&= \frac{1}{4\pi\epsilon_0}\frac{Q_1}{(\frac{d}{2})^2}=\frac{1}{4\pi\epsilon_0}\frac{Q_1}{\frac{d^2}{4}}\\
E_2&= \frac{1}{4\pi\epsilon_0}\frac{Q_2}{(\frac{d}{2})^2}=\frac{1}{4\pi\epsilon_0}\frac{Q_2}{\frac{d^2}{4}}\\
\end{align*}
Ce qui nous donne :
\begin{align*}
E&=\frac{1}{4\pi\epsilon_0}\frac{Q_1}{\frac{d^2}{4}}+\frac{1}{4\pi\epsilon_0}\frac{Q_2}{\frac{d^2}{4}}\\
E&=\frac{1}{4\pi\epsilon_0\cdot\frac{d^2}{4}}\cdot(Q_1 + Q_2)\\
E&=\frac{1}{4\pi\epsilon_0\cdot\frac{(10^{-1})^2}{4}}\cdot(-5\cdot10^{-6} + 7\cdot10^{-6})\\
E&=\frac{1}{\pi\epsilon_0\cdot10^{-2}}\cdot2\cdot10^{-6}\\
E&=\frac{1}{\pi\epsilon_0}\cdot2\cdot10^{-4}\approx {7.19\cdot10^{6}}\frac{N}{C}
\end{align*}
La valeur de notre champs électrique entre nos deux charges est donc environ de ${7.19\cdot10^{6}}\frac{N}{C}$.
## Ex 3: {.unnumbered}
\begin{align*}
q_e&=-e=-1.6022\cdot10^{-19}C\qquad m_e = 9\cdot 10^{-31}kg\\
a&=100\frac{m}{s^2}\\
F&=Eq=m\cdot a
\end{align*}
Pour trouver la valeur de notre champs électrique, on doit déterminer la force subie par notre électron :
\begin{align*}
F=m_e\cdot a
\end{align*}
On connaît également la relation entre la force subie et le champs électrique :
\begin{align*}
F&=E\cdot q_e \and F=m_e\cdot a \Leftrightarrow E\cdot q_e=m_e\cdot a\\
E&=\frac{m_e\cdot a}{q_e}
\end{align*}
Ce qui nous donne :
\begin{align*}
E&=\frac{9\cdot 10^{-31}\cdot 100}{-1.6022\cdot10^{-19}}=\frac{9\cdot 10^{-29}}{-1.6022\cdot10^{-19}}\\
E&=\frac{9}{-1.6022}\cdot 10^{-10}\approx -5.62\cdot10^{-10}\frac{N}{C}
\end{align*}
## Ex 4: {.unnumbered}
\begin{align*}
E&=\sum_{i} \frac{1}{4\pi\epsilon_0}\frac{Q_i}{r_i^2}=\sum_{i} k\frac{Q_i}{r_i^2}\\
E&= E_1+E_2 = 0 \frac{N}{C}\\
r_1&= \frac{r}{3}\qquad r_2 = \frac{2}{3}\cdot r
\end{align*}
On souhaite connaître le rapport entre $Q_1$ et $Q_2$, on commence donc par poser l'équation suivante :
\begin{align*}
E = E_1 + E_2 = k\cdot \frac{Q_1}{\frac{r}{3}^2}+k\cdot \frac{Q_2}{(\frac{2}{3}\cdot r)^2}\\
E=k\cdot(\frac{Q_1}{\frac{r}{3}^2}+\frac{Q_2}{(\frac{2}{3}\cdot r)^2})
\end{align*}
On va donc isoler le rapport $\frac{Q_1}{Q_2}$, en sachant que $E=0$, ce qui nous donne :
\begin{align*}
E&=k\cdot(\frac{Q_1}{\frac{r}{3}^2}+\frac{Q_2}{(\frac{2}{3}\cdot r)^2})=0\\
0&=\frac{Q_1}{\frac{r^2}{3^2}}+\frac{Q_2}{\frac{2}{3}^2\cdot r^2}\\
0&=\frac{Q_1}{\frac{1}{3^2}\cdot r^2}+\frac{Q_2}{\frac{2}{3}^2\cdot r^2}\\
0&=\frac{Q_1}{\frac{1}{3^2}}+\frac{Q_2}{(\frac{2}{3})^2}\\
0&=3^2\cdot Q_1+(\frac{3}{2})^2\cdot Q_2\\
0&=36\cdot Q_1+9\cdot Q_2\\
-36\cdot Q_1&=9\cdot Q_2\\
\frac{Q_1}{Q_2}&=-\frac{9}{36}=-\frac{1}{4}
\end{align*}
Le rapport entre nos deux charges est donc $\frac{Q_1}{Q_2}=-\frac{1}{4}$.
## Ex 5: {.unnumbered}
\begin{align*}
S_{face} &= 10cm \cdot 10cm = 10^{-2}m^2\\
E &= 10^3\frac{N}{C}\\
\Phi_E&=\sum_{i=1}^{6} \Phi_{E_i}=\sum_{i=1}^{6} ES_{face}\cos{\theta_i}
\end{align*}
Pour calculer le flux passant à travers la surface de notre cube, il nous faut déterminer les différents angles $\theta_i$. On sait que l'une des faces (que l'on appellera face n°1) est perpendiculaire au champs, par conséquent, on sait que le vecteur normal de cette surface forme un angle nul avec le champs. On peut donc déduire les autres angles :
\begin{align*}
\theta_1 &= 0\\
\theta_2 &= \frac{\pi}{2}\\
\theta_3 &= \pi\\
\theta_4 &= \frac{\pi}{2}\\
\theta_5 &= \frac{\pi}{2}\\
\theta_6 &= \frac{\pi}{2}
\end{align*}
Ce qui nous donne les flux suivants pour chacune des faces :
\begin{align*}
\Phi_{E_1} &= ES_{face}\cos\theta_1 = 10^3\cdot10^{-2} \cos 0 = 10 \frac{N\cdot m^2}{C}\\
\Phi_{E_2} &= ES_{face}\cos\theta_2 = 10^3\cdot10^{-2} \cos \frac{\pi}{2} = 0 \frac{N\cdot m^2}{C}\\
\Phi_{E_3} &= ES_{face}\cos\theta_3 = 10^3\cdot10^{-2} \cos \pi = -10 \frac{N\cdot m^2}{C}\\
\Phi_{E_4} &= ES_{face}\cos\theta_4 = 10^3\cdot10^{-2} \cos \frac{\pi}{2} = 0 \frac{N\cdot m^2}{C}\\
\Phi_{E_5} &= ES_{face}\cos\theta_5 = 10^3\cdot10^{-2} \cos \frac{\pi}{2} = 0 \frac{N\cdot m^2}{C}\\
\Phi_{E_6} &= ES_{face}\cos\theta_6 = 10^3\cdot10^{-2} \cos \frac{\pi}{2} = 0 \frac{N\cdot m^2}{C}
\end{align*}
En sommant on obtient, le flux total suivant :
\begin{align*}
\Phi_E&=\sum_{i=1}^{6} \Phi_{E_i}=\sum_{i=1}^{6} ES_{face}\cos{\theta_i}\\
\Phi_E&=10 + 0 - 10 + 0 + 0 + 0 = 0 \frac{N\cdot m^2}{C}
\end{align*}
OPTIONS = --filter=pandoc-numbering
OPTIONS += --filter=pandoc-crossref
PDFOPTIONS = --highlight-style kate
PDFOPTIONS += --pdf-engine pdflatex
PDFOPTIONS += --number-sections
PDFOPTIONS += --template=./default.latex
HTMLOPTIONS += -t html5
HTMLOPTIONS += -c ../../css/tufte-css/tufte.css
HTMLOPTIONS += --self-contained
HTMLOPTIONS += --mathjax=MathJax.js
MD=$(wildcard *.md)
HTML=$(MD:%.md=%.html)
PDF=$(MD:%.md=%.pdf)
all: $(HTML) $(PDF)
%.pdf: %.md Makefile
pandoc -s $(OPTIONS) $(PDFOPTIONS) -o $@ $<
%.html: %.md Makefile
pandoc -s $(OPTIONS) $(HTMLOPTIONS) -o $@ $<
clean:
rm -rf *.html *.pdf
var fileref=document.createElement('script')
fileref.setAttribute("type","text/javascript")
fileref.setAttribute("src", "https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML")
document.getElementsByTagName("head")[0].appendChild(fileref)
---
# author:
# - El Kharroubi Michaël
title: Travail pratique
subtitle: Lignes de champs électriques
autoSectionLabels: true
autoEqnLabels: true
eqnPrefix:
- "éq."
- "éqs."
chapters: true
numberSections: false
chaptersDepth: 1
sectionsDepth: 3
lang: fr
documentclass: article
papersize: A4
cref: false
pandoc-numbering:
- category: TP
urlcolor: blue
---
# But
- Simuler un phénomène physique vu en cours à l'aide du langage C
- Visualiser les lignes de champs électriques générées par N particules
# 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 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 à une distance $r$ de la particule est donné par la formule suivante :
$$
E = k\frac{Q}{r^2} \qquad \mbox{avec}\ k=\frac{1}{4\pi\epsilon_0}
$$
En ce qui concerne sa direction, si $Q>0$ alors le vecteur va chercher à s'éloigner de la particule, et si $Q<0$ alors le vecteur est dirigé vers la particule.
![Champs de vecteurs représentant de champs électrique d'une charge positive. Source: Wikipédia, <https://bit.ly/3bTIJDx>.](https://upload.wikimedia.org/wikipedia/commons/thumb/f/f0/E_FieldOnePointCharge.svg/langfr-1024px-E_FieldOnePointCharge.svg.png){#fig:champ_e width=50%}
En réalité, on rencontre souvent (très souvent) plus d'une particule chargée, dans ce cas, on se sert du principe de superposition des champs électriques. Le vecteur en un point représente alors la résultante des actions induites par 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.
![Lignes de champs électrique reliant en présence de deux charges positives (gauche) et une charge négative et une positive (droite). Les lignes de champs sont sortantes de la charge positive, et entrantes dans la charge négative. Source: Wikipédia, <https://bit.ly/3dPsUk2>.](https://upload.wikimedia.org/wikipedia/commons/8/8f/Camposcargas.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]$.
Chaque particule possède une position appartenant à notre univers, ainsi qu'une charge (multiple de la charge élementaire).
Pour dessiner numériquement une courbe, une méthode consiste à l'approximer à l'aide d'un ensemble de segments de droites reliant des points appartenant à cette courbe. Pour dessiner notre ligne de champs, nous devons donc trouver un ensemble de points appartenant à cette ligne. Pour cela on travaille ainsi :
1. On tire aléatoirement un point dans notre univers $P_0$.
2. On assigne $P=P_0$
3. On calcule $P_{suivant}$ à partir de l'intensité et la direction du champs en $P$, ce qui nous donne $P_{suivant}=P+\sum_{i}^{N}E_i\cdot\frac{\vec{q_iP}}{||\vec{q_iP}||}$ avec $\vec{q_iP}$ le vecteur allant de la particule chargée $q_i$ au point $P$. Dans notre cas, on souhaite avancer d'une même distance à chaque fois, et qui ne soit pas trop grande. On va donc commencer par normaliser le champs, puis on va ajouter une constante $\delta x$ qui est fixe pour notre programme et qui est définie en fonction de la taille de notre fenêtre. Ce qui nous donne $P_{suivant}=P+\delta x\cdot\frac{\vec{E}}{||\vec{E}||}$ avec $\delta x = \frac{1}{\sqrt{\mbox{largeur}^2+\mbox{hauteur}^2}}$ et $\vec{E} = \sum_{i}^{N}E_i\cdot\frac{\vec{q_iP}}{||\vec{q_iP}||}$.
4. Si $P$ et $P_{suivant}$ sont à une distance des particules, supérieure à un seuil choisit et qu'ils sont toujours dans notre univers, on trace un segment entre $P$ et $P_{suivant}$. Sinon, on quitte notre boucle.
5. On assigne $P=P_{suivant}$ et on revient à l'étape 3
Cette méthode nous permet de dessiner partiellement notre ligne de champs. Comme nous partons d'un point aléatoire, il faut également dessiner le reste de la ligne en allant dans le sens opposé. Il faudra donc réitérer notre processus, en partant à nouveau de la deuxième étape, mais en calculant $P_{suivant}=P-\delta x\cdot\frac{\vec{E}}{||\vec{E}||}$.
# Énoncé
Vous allez développer une simulation de lignes de champs générée par un ensemble de particules en C, et visualiser le résultat à l'aide de la librairie SDL. Vous devez réutiliser la librairie de vecteurs en deux dimensions réalisée au premier semestre. Deux fichiers utils.h et utils.c vous seront fournis avec l'énoncé. Le fichier utils.c contient des méthodes afin de vous faciliter la réalisation de ce TP.
Ce travail va se diviser en deux parties.
## Dessin
Pour pouvoir representer ce que vous allez calculer dans la deuxième partie, vous allez devoir dessiner des droites et des cercles à l'aide des méthodes présentées en cours. Pour cela vous implémenterez les fonctions suivantes :
```c
typedef struct
{
uint32_t row;
uint32_t column;
} coordinates_t;
void gfx_draw_line(struct gfx_context_t *ctxt, coordinates_t p0,
coordinates_t p1, uint32_t color);
void gfx_draw_circle(struct gfx_context_t *ctxt, coordinates_t c,
uint32_t r, uint32_t color);
```
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 (50,75)$, $(50,50) \rightarrow (38,72)$, $(50,50) \rightarrow (28,62)$
- $(50,50) \rightarrow (25,50)$, $(50,50) \rightarrow (28,38)$, $(50,50) \rightarrow (37,28)$
- $(50,50) \rightarrow (50,25)$, $(50,50) \rightarrow (62,28)$, $(50,50) \rightarrow (72,37)$
## Physique
Comme nous l'avons vu durant la partie théorique, vous allez devoir calculer différents points appartenants à différentes lignes de champs. Pour cela vous implémenterez les fonctions suivantes :
```c
typedef struct
{
double q;
vec2 pos;
} charge_t;
// Compute E*qP/norm(qP)
// Return false if norm(qP) < eps
bool compute_e(charge_t c, vec2 p, double eps, vec2 *e);
// Compute the normalized sum of Ei*qiP/norm(qiP)
// Return false if for some qiP, norm(qiP) < eps
bool compute_total_normalized_e(charge_t *charges, int num_charges, vec2 p,
double eps, vec2 *e);
// 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);
// 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);
```
# Travail à rendre (par groupe de deux)
- Un rapport succint (moins de 6 pages) présentant le travail réalisé, avec des images de ce dernier
- Le repos git contenant le code réalisé
#include "vec2/vec2.h"
#include "utils.h"
#include <math.h>
#include <stdlib.h>
coordinates_t coordinates_create(int row_, int column_)
{
coordinates_t c = {.row = row_, .column = column_};
return c;
}
// Transform a position in the univers [x0,y0]x[x1,y1] to a screen position
coordinates_t position_to_coordinates(int width, int height, double x0, double x1, double y0, double y1, vec2 pos)
{
double dx = x1 - x0;
double dy = y1 - y0;
return coordinates_create((int)round(height * (pos.y - y0) / dy), (int)round(width * (pos.x - x0) / dx));
}
double rand_one()
{
return (double)rand() / (double)RAND_MAX;
}
charge_t charge_create(double q, vec2 pos)
{
charge_t c = {.q = q, .pos = pos};
return c;
}
\ No newline at end of file
#ifndef _UTILS_H_
#define _UTILS_H_
#include <stdint.h>
const double K = 8.988e9;
const double E = 1.602e-19;
typedef struct
{
uint32_t row;
uint32_t column;
} coordinates_t;
typedef struct
{
double q;
vec2 pos;
} charge_t;
coordinates_t coordinates_create(int row_, int column_);
// Transform a position in the univers [x0,y0]x[x1,y1] to a screen position
coordinates_t position_to_coordinates(int width, int height, double x0, double x1, double y0, double y1, vec2 pos);
double rand_one();
charge_t charge_create(double q, vec2 pos);
#endif
\ No newline at end of file
......@@ -20,6 +20,9 @@ pandoc-numbering:
urlcolor: blue
---
# Prérequis
- Installer la librairie SDL2 (`libsdl2-dev` sur ubuntu)
# But
- Rappel sur les opérations vectorielles de base en deux dimensions.
......@@ -48,7 +51,7 @@ Le fichier `vec2.c` contient 12 fonctions à compléter. Deux d'entre elles le s
Le travail pratique est terminé, lorsque que l'ensemble des tests passent. Vous pouvez exécuter les tests à tout moment en effectuant la commande `make run_tests` dans le répertoire `tp_vec2`.
Une fois que tous les tests passent avec succès, vous pouvez parcourir le fichier `main.c`. Essayez de comprendre ce qui y est fait. Dans un second temps, commencez par installer la librairie SDL2 (`libsdl2-dev` sur ubuntu). Puis, exécutez la commande `make main`, suivie de `./main` afin d'afficher le résultat.
Une fois que tous les tests passent avec succès, vous pouvez parcourir le fichier `main.c`. Essayez de comprendre ce qui y est fait. Dans un second temps, exécutez la commande `make main`, suivie de `./main` afin d'afficher le résultat.
# Travail à rendre
......@@ -60,4 +63,3 @@ répertoire au nom des deux auteurs·trices du code, qui lui-même contiendra to
votre code.
Le code doit être rendu au plus tard le 1.11.2021.
......@@ -3,7 +3,7 @@ CC:=gcc
#The flags passed to the compiler
CFLAGS:=-g -O3 -Wall -Wextra -fsanitize=address -fsanitize=leak -std=gnu11
#The flags passed to the linker
LDFLAGS:=-lm -lSDL2
LDFLAGS:=-lm
#Path to the lib Vec2
VPATH:=vec2 gfx
......@@ -11,7 +11,7 @@ run_tests: tests
./$<
main: main.o vec2.o gfx.o
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -lSDL2
tests: vec_tests.o vec2.o
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
......
......@@ -7,34 +7,30 @@
#define SCREEN_WIDTH 1280
#define SCREEN_HEIGHT 720
double rand_dbl()
{
return ((double)rand()) / RAND_MAX;
double rand_dbl() {
return 2.0 * ((double)rand()) / RAND_MAX - 0.5;
}
int main()
{
int main() {
srand(time(NULL));
struct gfx_context_t *ctxt =
gfx_create("Vec2 demo", SCREEN_WIDTH, SCREEN_HEIGHT);
if (!ctxt)
{
if (!ctxt) {
fprintf(stderr, "Graphics initialization failed!\n");
return EXIT_FAILURE;
}
vec2 center = vec2_create(0.5, 0.5);
vec2 center = vec2_create(0.0, 0.0);
double radius = 0.5;
for (int i = 0; i < 250000; i++)
{
for (int i = 0; i < 250000; i++) {
vec2 r = vec2_create(rand_dbl(), rand_dbl());
//Draw pixel if in circle
if (vec2_norm(vec2_sub(r, center)) < radius)
{
coordinates pixel = vec2_to_coordinates(r, SCREEN_WIDTH, SCREEN_HEIGHT);
//Random color (not black)
// Draw pixel if in circle
if (vec2_norm(vec2_sub(r, center)) < radius) {
coordinates pixel =
vec2_to_coordinates(r, SCREEN_WIDTH, SCREEN_HEIGHT);
// Random color (not black)
uint32_t color = rand() % 0xFFFFFF;
gfx_putpixel(ctxt, pixel.column, pixel.row, color);
......@@ -42,13 +38,11 @@ int main()
}
gfx_present(ctxt);
while (true)
{
if (gfx_keypressed() == SDLK_ESCAPE)
{
while (true) {
if (gfx_keypressed() == SDLK_ESCAPE) {
break;
}
}
gfx_destroy(ctxt);
return EXIT_SUCCESS;
}
\ No newline at end of file
}
......@@ -6,57 +6,68 @@
/// @param x_ The first component.
/// @param y_ The second component.
/// @return The newly created vector.
vec2 vec2_create(double x_, double y_) {}
vec2 vec2_create(double x_, double y_) {
}
/// Create a zero 2d vector.
/// @return The newly created zero vector.
vec2 vec2_create_zero() { vec2_create(0.0, 0.0); }
vec2 vec2_create_zero() {
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 vec2_add(vec2 lhs, vec2 rhs) {
}
/// 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 vec2_sub(vec2 lhs, vec2 rhs) {
}
/// 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 vec2_mul(double scalar, vec2 rhs) {
}
/// 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) {}
double vec2_dot(vec2 lhs, vec2 rhs) {
}
/// 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 vec2_norm_sqr(vec2 v) {
}
/// Compute the euclidean norm of a given vector.
/// @param v The vector.
/// @return The norm.
double vec2_norm(vec2 v) {}
double vec2_norm(vec2 v) {
}
/// Compute the normalization of a given vector.
/// @param v The vector.
/// @return The new normalized vector.
vec2 vec2_normalize(vec2 v) {}
vec2 vec2_normalize(vec2 v) {
}
/// 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 The dot product.
bool vec2_is_approx_equal(vec2 lhs, vec2 rhs, double eps) {}
/// @return true if vector are approximately equal, false otherwise.
bool vec2_is_approx_equal(vec2 lhs, vec2 rhs, double eps) {
}
/// Compute the coordinates of a 2d vector (with components between 0 and 1)
/// in a given screen matrix.
......@@ -64,11 +75,11 @@ bool vec2_is_approx_equal(vec2 lhs, vec2 rhs, double eps) {}
/// @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) {}
coordinates vec2_to_coordinates(vec2 v, uint32_t width, uint32_t height) {
}
/// Print a vector in the standard output.
/// @param v The vector.
void vec2_print(vec2 v)
{
void vec2_print(vec2 v) {
printf("x = %g, y = %g\n", v.x, v.y);
}
\ No newline at end of file
}
#include "vec2.h"
#include <stdio.h>
#include <stdbool.h>
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
typedef struct _test_result
{
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)
{
void print_in_color(char *color, char *text) {
printf("\033%s", color);
printf("%s", text);
printf("\033[0m");
}
void print_in_red(char *text)
{
void print_in_red(char *text) {
print_in_color("[0;31m", text);
}
void print_in_green(char *text)
{
void print_in_green(char *text) {
print_in_color("[0;32m", text);
}
bool dbl_eq(double a, double b)
{
bool dbl_eq(double a, double b) {
return fabs(a - b) < 1e-6;
}
/*
*
* Write your tests here
*
*/
*
* Write your tests here
*
*/
/* TODO
vec2 vec2_create(double x_, double y_); -- Ok
vec2 vec2_create_zero(); -- Ok
......@@ -49,253 +44,201 @@ 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 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()
{
test_result t_vec2_create_0() {
bool passed = true;
for (uint32_t i = 0; i < nb_tests; i++)
{
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)
{
if (u_x[i] != v.x || u_y[i] != v.y) {
passed = false;
break;
}
}
return (test_result){.passed = passed,
.name = "Test vec2_create 0"};
return (test_result){.passed = passed, .name = "Test vec2_create 0"};
}
test_result t_vec2_create_zero_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"};
.name = "Test vec2_create_zero 0"};
}
test_result t_vec2_add_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++)
{
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])))
{
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"};
return (test_result){.passed = passed, .name = "Test vec2_add 0"};
}
test_result t_vec2_sub_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++)
{
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])))
{
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"};
return (test_result){.passed = passed, .name = "Test vec2_sub 0"};
}
test_result t_vec2_mul_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++)
{
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])))
{
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"};
return (test_result){.passed = passed, .name = "Test vec2_mul 0"};
}
test_result t_vec2_dot_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]);
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]))
{
if (!dbl_eq(res, r[i])) {
passed = false;
break;
}
}
return (test_result){.passed = passed,
.name = "Test vec2_dot 0"};
return (test_result){.passed = passed, .name = "Test vec2_dot 0"};
}
test_result t_vec2_norm_sqr_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]);
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]))
{
if (!dbl_eq(res, r[i])) {
passed = false;
break;
}
}
return (test_result){.passed = passed,
.name = "Test vec2_norm_sqr 0"};
return (test_result){.passed = passed, .name = "Test vec2_norm_sqr 0"};
}
test_result t_vec2_norm_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]);
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]))
{
if (!dbl_eq(res, r[i])) {
passed = false;
break;
}
}
return (test_result){.passed = passed,
.name = "Test vec2_norm 0"};
return (test_result){.passed = passed, .name = "Test vec2_norm 0"};
}
test_result t_vec2_normalize_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++)
{
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])))
{
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"};
return (test_result){.passed = passed, .name = "Test vec2_normalize 0"};
}
test_result t_vec2_is_approx_equal_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++)
{
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])
{
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"};
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[] = {25, 50, 74, 99};
uint32_t r_row[] = {0, 100, 199, 299};
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[] = {61, 74, 86, 99};
uint32_t r_row[] = {149, 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]);
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])
{
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"};
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,
// 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()
{
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++)
{
for (uint32_t i = 0; i < nb_tests; i++) {
printf("Running test n°%d: ...\n", i);
test_result r = tests[i]();
if (r.passed)
{
if (r.passed) {
sprintf(message, "\t- %s : OK", r.name);
print_in_green(message);
}
else
{
} else {
all_passed = false;
sprintf(message, "\t- %s : FAILED", r.name);
print_in_red(message);
......@@ -306,4 +249,4 @@ int main()
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