Programmation objet et géométrie/Les rectangles de canvas

Un livre de Wikilivres.
Sauter à la navigation Sauter à la recherche

C'est plus facile de tracer un rectangle qu'un segment avec canvas: Pas besoin de beginPath(), de moveTo() ni de stroke() pour avoir le rectangle complet. En fait il y a deux méthodes permettant de dessiner un rectangle: strokeRect() qui dessine juste le cadre du rectangle, et fillRect() qui dessine un rectangle rempli. Les deux méthodes acceptent 4 arguments chacune:

  1. L'abscisse du coin supérieur gauche
  2. L'ordonnée du coin supérieur gauche
  3. La largeur du rectangle
  4. La hauteur du rectangle

Les rectangles peuvent servir à restreindre le tracé (par intersection avec le rectangle); ils peuvent être dessinés en semi-transparence; on peut leur affecter un dégradé. Ils peuvent servir à effacer la figure (en la recouvrant d'un rectangle blanc) ou à tracer des histogrammes. Dans ce chapitre, on va dessiner des rectangles de Fibonacci, qui sont en fait des assemblages de carrés (comme ça on donne le même paramètre à la largeur et la hauteur).

Rectangles de Fibonacci[modifier | modifier le wikicode]

Pour que les carrés dont les côtés sont des nombres de Fibonacci s'assemblent bien, il faut les coller tantôt à droite, tantôt en haut, tantôt à gauche et tantôt en bas de l'assemblage. Le choix se fera selon la valeur de n (l'indice de la boucle) modulo 4, et c'est une bonne occasion d'utiliser le fameux switch..case de JavaScript:

Comment spiraler en JavaScript[modifier | modifier le wikicode]

Pour garder une trace de la valeur de n modulo 4, on peut également changer de couleur de remplissage selon sa valeur (a et b sont les nombres de Fibonacci qu'on est en train de calculer):

	switch(n%4){
		case 0: {
			x+=a; y-=b-a;
			pinceau.fillStyle="Red";
			break;
		}
		case 1: {
			x-=b-a; y-=b;
			pinceau.fillStyle="Green";
			break;
		}
		case 2: {
			x-=b;
			pinceau.fillStyle="Blue";
			break;
		}
		case 3: {
			y+=a;
			pinceau.fillStyle="Magenta";
			break;
		}

À chaque fois, l'instruction break sert à éviter d'effectuer les autres déplacements après celui dont on a besoin.

Dessin des rectangles[modifier | modifier le wikicode]

Le script complet n'est pas beaucoup plus long: Il s'agit de rajouter les deux premiers carrés autour desquels la construction va se faire, et les deux instructions de dessin des rectangles (fillRect pour le rectangle de couleur variable, et strokeRect() pour le bord):

<html>
<head>
<script>
</script>
</head>
<style type="text/css">
      canvas { border: 4px solid brown; background: #FFFFFF }
</style>
<body>
<canvas id="cadre" width="480" height="300">
<script>
var chevalet=document.getElementById('cadre');
var pinceau=chevalet.getContext('2d');
pinceau.strokestyle="Blue";
pinceau.fillStyle="Cyan";
a=1;
b=1;
x=150;
y=100;
pinceau.strokeRect(x,y,1,1);
y-=1;
pinceau.strokeRect(x,y,1,1);

for(n=2;n<=12;n++){
	c=a+b;
	a=b;
	b=c;
	switch(n%4){
		case 0: {
			x+=a; y-=b-a;
			pinceau.fillStyle="Red";
			break;
		}
		case 1: {
			x-=b-a; y-=b;
			pinceau.fillStyle="Green";
			break;
		}
		case 2: {
			x-=b;
			pinceau.fillStyle="Blue";
			break;
		}
		case 3: {
			y+=a;
			pinceau.fillStyle="Magenta";
			break;
		}
	}
	pinceau.fillRect(x,y,b,b);
	pinceau.strokeRect(x,y,b,b);
}

</script>
</canvas>
<br/>
</body>
</html>

Voilà le résultat avec 12 carrés:

Figurecanvas4.svg

Variante avec des arcs de cercles[modifier | modifier le wikicode]

On peut aussi, au lieu des carrés, mettre des quarts de cercles qui se joignent:

<html>
<head>
<script>
</script>
</head>
<style type="text/css">
      canvas { border: 4px solid brown; background: #FFFFFF }
</style>
<body>
<canvas id="cadre" width="480" height="300">
<script>
var chevalet=document.getElementById('cadre');
var pinceau=chevalet.getContext('2d');
pinceau.strokeStyle="Red";
pinceau.lineWidth="4";
pinceau.beginPath();
a=1;
b=1;
x=150;
y=100;
for(n=2;n<=12;n++){
	c=a+b;
	a=b;
	b=c;
	switch(n%4){
		case 0: {
			x+=a; y-=b-a;
			pinceau.arc(x,y,b,Math.PI/2,0,true);
			break;
		}
		case 1: {
			x-=b-a; y-=b;
			pinceau.arc(x,y+b,b,0,-Math.PI/2,true);
			break;
		}
		case 2: {
			x-=b;
			pinceau.arc(x+b,y+b,b,-Math.PI/2,Math.PI,true);
			break;
		}
		case 3: {
			y+=a;
			pinceau.arc(x+b,y,b,Math.PI,Math.PI/2,true);
			break;
		}
	}
}
pinceau.stroke();

</script>
</canvas>
<br/>
</body>
</html>

Ça donne cette spirale:

Figurecanvas6.svg

Pixels vus comme rectangles[modifier | modifier le wikicode]

Si la longueur et la largeur d'un rectangle font 1 pixel chacun, on peut remplir ce pixel seul avec un rectangle de dimensions 1 et 1.

Ensemble de Mandelbrot[modifier | modifier le wikicode]

Voici un code informatique pour dessiner l'ensemble de Mandelbrot en Javascript dans le canvas, cette méthode va dessiner la fractale en entier :

var b = document.body;
var c = document.getElementsByTagName('theCanvas')[0];
var a = c.getContext('2d');

var w = c.width; // longueur du canvas
var h = c.height; // largeur du canvas

// Zoom pour dessiner la fractale dans tout le canvas 
x1 = ((-2.1*w)/500);
x2 = ((0.6*w)/500);
y1 = ((-1.2*h)/250);
y2 = ((1.2*h)/250);
zm = 100; // valeur du zoom
im = 50; // nombre d'itération maximum

ix = (x2-x1)*zm;
iy = (y2-y1)*zm;

for(x=0;x<ix;x++){
    for(y=0;y<iy;y++){
        cr=x/zm+x1; //partie réelle du nombre complexe c
        ci=y/zm+y1; // partie imaginaire du nombre complexe c
        zr=0;
        zi=0;
        i=0;

        do{
            tmp = zr;
            zr=zr*zr-zi*zi+cr; // partie réelle de Zn
            zi= 2*tmp*zi+ci; // partie imaginaire de Zn
            i++;
                    
        } while(zr*zr+zi*zi<4 && i<im);
      
      if (i==im){
  a.fillRect(x,y,1,1);
      
      }      
    }    
}