Nous proposons dans ce supplément d'étendre les fonctionalités
de dessins dans un quad-tree en utilisant maintenant une
interface Fenetre
déclarant des méthodes pour
tracer des lignes et peindre des triangles :
interface Fenetre { /* Peint un rectangle de coin sup'erieur gauche (xa, ya) inclus * et de coin inf'erieur droit (xb, yb) exclus * avec la couleur coul. */ void rectangle (int xa, int ya, int xb, int yb, int coul) ; /* Trace une ligne de (xa, ya) `a (xb, yb). */ void ligne (int xa, int ya, int xb, int yb, int coul) ; /* Peint un triangle (xa, ya), (xb, yb), (xc, yc). */ void triangle (int xa, int ya, int xb, int yb, int xc, int yc, int coul) ; }
Ainsi ExEvts2.java contient
des définitions d'évènements Pyramide
qui produit une pyramide tournante et Sierpinski
qui produit un empilement de triangles inspiré de la
fractale de Sierpinski.
Le dessin en haut de cette page s'obtient en insérant deux pyramides et un sierpinski par :
fp.ajouter (new Pyramide (1, 100, 10, new Point (160, 160), new Point (40, 40), 2., .8, 2, 6)) ; fp.ajouter (new Pyramide (2, 100, 10, new Point (200, 180), new Point (120, 40), 2., .8, 85, 6)) ; fp.ajouter (new Sierpinski (0, 70, 10, new Point(40,0), new Point (120,400), new Point (400,80), 2, 255)) ;
La difficulté en traçant une ligne consiste à n'allumer qu'un pixel par ligne et par colonne. Ainsi, pour un segment de pente entre -1 et 1, on affichera pour chaque x possible le point de la colonne d'abscisse x le plus proche du segment (en considérant qu'un pixel (i,j) est centré sur le point (i,j)). Dans le cas où la pente est plus forte, on se ramène au cas précédent en échangeant x et y. Ainsi, pour tracer un segment (xa,ya) (xb,yb), on se ramènera dans tous les cas à une boucle du type :
for (int x = Math.max (0, xa) ; x < Math.min (xb, l) ; x++) { float y = ya + ((float)(yb-ya))/(xb-xa)*(x-xa) ; ... // Allumer le pixel (x, Math.round (y)) }
Savoir peindre des triangles est utile pour pouvoir peindre
n'importe quel polygone. Pour peindre un triangle, il
suffit d'allumer les pixels de centre intérieur au triangle et
d'allumer les pixel des bords par trois traçages de lignes.
Pour cela une classe Geom est fournie
avec des méthodes rectInclusTrig()
pour
tester si un rectangle est inclus dans un triangle et
interTrigRect()
pour tester si un triangle
intersecte un rectangle. (Ces méthodes reposent sur
d'autres plus élémentaires comme tester l'intersection de deux
segments par exemple qui est déjà un cas d'école de la
géométrie algorithmique.)