installez la base de code
minimaliste
gKit3
sans dépendances
.
lisez le readme sur la forge et compilez tp1.
si vous souhaitez un aperçu des fonctions nécessaires pour
réaliser le tp, vous pouvez consulter la
doc
sur les points et les vecteurs. ainsi que celle sur les
images
+ les
couleurs.
Partie 1 : et en 2D, comment ça marche ?
on sait changer la couleur d'un pixel d'une image :
Image image(512, 512);
image(10, 10)= Red(); // le
pixel (10, 10) est rouge
image(20, 20)= Color(rouge, vert,
bleu); // avec rouge, vert et bleu des
reels entre 0 et 1
exercice 1 :
comment dessiner une forme géométrique ? un disque de centre c
et de rayon r, par exemple.
on va s'interesser à une solution très simple : pour chaque
pixel de l'image, on le colorie s'il est à l'intérieur du
disque.
étape 1 : parcourir tous les
pixels de l'image :
Image image(512, 512)
;
for(int y= 0; y < image.height(); y++)
for(int x= 0; x < image.width(); x++)
{
Color color= White();
pixel(x, y)= color;
}
étape 2 : comment déterminer que
le pixel p est à l'intérieur du disque ?
il suffit de se rappeler qu'un point p fait partie d'un disque
(ou d'une sphère en 3d) s'il se trouve à une distance du
centre inférieure au rayon du disque.
faites le test et coloriez le disque. quelques couleurs sont
prédéfinies dans
color.h
remarques : vous pouvez utiliser la structure
Point
pour manipuler les coordonnées d'un pixel, il faudra juste z= 0.
la fonction distance(p, q) renvoie la distance entre 2 points p
et q.
Point p= { x, y, 0 };
Point p= Point( x, y, 0 ); // les 2
syntaxes sont possibles...
float d= distance(p, q); //
distance entre p et q
exercice 2 :
si on souhaite maintenant dessiner un anneau ?
exercice 3 :
et si l'épaisseur de l'anneau est 1 ou 2 pixels, que se
passe-t-il ?
et si on testait plusieurs points, à l'intérieur du pixel, au
lieu de ne tester que le centre ? peut-on dessiner une forme
aussi "fine" ?
rappel : on peut aussi calculer une image plus grande, la
filtrer et la sous-échantilloner, c'est équivalent mais plus
long à faire.
et sur le disque ou un anneau classique, l'image change-t-elle ?
exercice 4 :
et pour un triangle de sommets a, b et c ? comment peut-on
vérifier qu'un pixel p se trouve à l'intérieur du triangle ? on
va suivre le même principle, pour chaque pixel de l'image, on
vérifie s'il appartient ou pas au triangle.
on peut décomposer ce test en 3 parties : si le pixel se trouve
du "bon" coté de chaque arete du triangle, il est à l'intérieur.
comment formuler le test sur une arete ?
on peut utiliser un produit scalaire.
on veut savoir de quel cote de
l'arete ab se trouve le vecteur ap. il suffit de calculer le
produit scalaire entre le vecteur ap et un vecteur
perpendiculaire à l'arete ab.
on recommence le test pour les autres aretes du triangle : ab,
bc, ca (oui c'est orienté, et c'est important !)
rappel : produit scalaire en 2D de 2 vecteurs u et v : dot(u,
v) = u.x * v.x + u.y * v.y
rappel : vecteur perpendiculaire du vecteur u = (-u.y, u.x)
on peut aussi calculer l'aire signée d'un triangle.
c'est le même test mais formulé
avec une autre propriété. quelle est l'aire algébrique
(signée) du triangle abp ? du triangle bcp ? et cap ? du
triangle abc ? si les 4 aires ont le même signe, le pixel p
est à l'intérieur du triange.
l'aire signée d'un triangle est le déterminant de la matrice
construite avec les coordonnées des sommets.
rappel : calculer le
determinant
d'une matrice 2x2 et 3x3, cf wikipedia
rappel : comment construire la matrice 2x2 ? c'est le
paragraphe suivante dans wikipedia. ah et l'aire d'un
parallelograme est le double de celle d'un triangle... (et de
même signe...)
pour les curieux : vérifiez
que les 2 formulations sont très exactement identiques !!
pour les curieux : on
peut écrire le test très facilement, mais en 3d (la composante z
sera nulle) en vérifiant que le produit vectoriel de ab et ap
est orienté dans le même sens que la normale du triangle abc...
il faut bien sur tester aussi les aretes bc, et ca.