« Programmation objet et géométrie/Les rectangles de canvas » : différence entre les versions

Un livre de Wikilivres.
Contenu supprimé Contenu ajouté
script de Yohannbec
Aucun résumé des modifications
Ligne 227 : Ligne 227 :
</source>
</source>


{{AutoCat}}
[[Catégorie:Programmation objet et géométrie]]

Version du 15 avril 2017 à 20:55

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

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

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

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:

Variante avec des arcs de cercles

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:

Pixels vus comme rectangles

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

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);
      
      }      
    }    
}