Cet article décrit comment on peut tracer un cercle avec Processing sans utiliser ellipse(). C’est utile si l’on veut tracer un cercle vide (transparent) à l’intérieur d’un objet, rectangle (pour faire un cache comme un microscope) ou cercle (un doughnut!).

Les notions de PShape, vertex, Contour

Pour comprendre les bases, il faut se référer à l’aide de Processing, et en particulier le tutoriel en anglais sur PShape qui utilise PShape, des vertex, ainsi que beginContour() et endContour() pour « percer » des trous dans des formes.

Le principe général

Au départ, lorsque je me suis intéressée au tracé de cercle avec des vertices, c’était pour mettre un cache en forme de microscope sur un travail collectif utilisant Processing. Je voulais faire un rectangle qui fasse la taille de l’écran, et à l’intérieur un cercle transparent de diamètre 90% de la hauteur de l’écran. L’écran était variable et je ne voulais donc pas créer une forme fixe.

C’est ainsi que j’ai compris comment faire un « trou » dans un objet :

  1. commencer la forme, avec beginShape() ;
  2. dessiner un rectangle en le traçant dans le sens des aiguilles d’une montre : aller d’un sommet à l’autre dans ce sens ;
  3. Démarrer un « contour » (un trou en fait) avec beginContour();
  4. tracer un cercle en le traçant dans le sens inverse des aiguilles d’une montre ;
  5. Arrêter le « contour » avec endContour();
  6. finir la forme avec endShape(CLOSE);

L’exemple que j’ai créé pour comprendre

Dans l’exemple qui suit, la fonction drawCircle() trace un cercle :

  • un cercle de centre Vcentre (un vecteur qui contient les coordonnées de ce point)
  • un cercle de rayon r
  • un cercle qui ressemble à un kaléidoscope si sides a une valeur faible, à un vrai cercle sinon
  • un cercle qui est tracé dans le sens des aiguilles d’une montre (cas « false » ou non (cas « true »)
Processing : vertices, PShape, Contour...

Processing : vertices, PShape, Contour…

Le fonctionnement

dans le setup(), on définit principalement les couleurs des différents éléments. colBkgnd utilisé pour le fond de l’écran est défini comme blanc #FFFFFF.

Dans draw() – on aurait tout pu mettre dans setup si on avait voulu – , on dessine le contenu de 4 quadrants différents.

Dans les 4 quadrants on trace un cercle en utilisant la fonction  drawCircle(PVector Centre, int sides, float r, boolean aclockw), définie à la fin du sketch.

Dans le premier quadrant (Nord Ouest), on trace un rectangle classique – avec rect() – puis on y trace un cercle qui est un PShape. Le cercle n’est pas vide. C’est un cercle plein. Le rectangle prend une couleur semi-transparente qui est diluée par le blanc du fond de l’écran. Le cercle est plus foncé, de la couleur de remplissage du rectangle mais sans la transparence pour une raison incompréhensible (et qui serait un bug de processing).

Dans le deuxième quadrant (Sud Ouest), on trace un rectangle puis un cercle selon le principe général décrit plus haut. On a bien un rectangle percé d’un cercle (on voit le fond blanc qui est le background.

Dans le troisième quadrant (Nord Est), on trace un premier cercle dans le sens des aiguilles d’une montre puis un deuxième cercle plus petit dans le sens inverse des aiguilles d’une montre. On obtient un doughnut (un cercle évidé) bleu sur le fond blanc.

Dans le quatrième quadrant (Sud Est), on trace un rectangle puis un cercle, comme dans le deuxième quadrant. Ensuite, une fois que l’on a refermé la forme avec endShape(), on trace une nouvelle forme avec un cercle plus petit. On obtient un rectangle évidé d’une forme de doughnut.

La fonction drawCircle( PVector Centre, int sides, float r, boolean aclockw )

Elle exécute un cercle comme on le ferait à la main si on disposait de l’équation d’un cercle, en traçant une succession de points de coordonnées x,y conformes à l’équation. Le tracé se fait dans le sens des aiguilles d’une montre si aclockw est vraie, dans le sens contraire sinon.

On trace autant de points que de « sides » : notre cercle est vraiment rond si on a défini une valeur élevée pour sides (plus de 30) et plus proche d’un quadrilatère ou d’un kaéliodoscope si l’on définit sides à une valeur faible.

Le code complet

Le code complet est disponible dans ce fichier texte téléchargeable : tracer cercles et autres PShapes

Le code complet est :

/* 
* tracer des cercles et autres objets avec des vertices

*
*/

PVector VCentre ; // centre du microscope
float r ;         // Rayon du microscope
int sides ;       // forme du cercle (sides faible = kaleidoscope plutôt)

color colBkgnd, colQ1, colQ2, colQ3, colQ4 ;

void setup() {

  size(600, 400) ;
  colorMode(HSB, 360, 100, 100, 100); 

  VCentre = new PVector( 0, 0) ;
  r = 70 ;
  sides = 30 ; // avec 30 on a un cercle très bien déjà

  colBkgnd = #FFFFFF  ;

  colQ1 = color(  random(100, 250) , random(50,100), random(60,90), random(60,80) ) ;
  colQ2 = color(  random(100, 250) , random(50,100), random(60,90), random(60,80) ) ; 
  colQ3 = color(  random(100, 250) , random(50,100), random(60,90), random(60,80) ) ;
  colQ4 = color(  random(100, 250) , random(50,100), random(60,90), random(60,80) ) ;
    
}

void draw() {
  
  background( colBkgnd ) ;
  
  // Quadrant 1 (Nord Ouest) on trace un cercle dans un rect()
  VCentre = new PVector( width/4,height/4) ;
  stroke(#FFFFFF) ;
  strokeWeight(2);
  fill( colQ1 ) ;

  rect(0,0,width/2,height/2) ;

  beginShape();
  drawCircle( VCentre, sides, r, true ) ; // true draws anticlockwise, false clockwise
  endShape(CLOSE);

  // Quadrant 2 (Sud Ouest) on trace  un trou circulaire dans un rectangle
  noStroke() ;
  fill( colQ2 );
  beginShape();
  vertex( 0, height/2 );
  vertex( width/2, height/2 );
  vertex( width/2, height );
  vertex( 0, height );
  VCentre = new PVector( width/4,3*height/4) ;
  stroke(#FFFFFF) ;
  strokeWeight(2);
  beginContour();
    // http://doc.gold.ac.uk/CreativeComputing/creativecomputation/?page_id=1142  
    // must be counterclockwise for a contour !!!!  
    drawCircle( VCentre, sides, r, true ) ; // true draws anticlockwise, false clockwise
  endContour();
  endShape(CLOSE);

  // Quadrant 3 (Nord Est) on trace  un doughnut 
  noStroke() ;
  fill( colQ3 );
  beginShape();

  VCentre = new PVector( 3*width/4,height/4) ;
  stroke(colQ3) ;
  strokeWeight(2);
  // on trace un cercle par dessus le rectangle
  drawCircle( VCentre, sides, 1.2*r, false ) ;  
  beginContour();
    // http://doc.gold.ac.uk/CreativeComputing/creativecomputation/?page_id=1142  
    // must be counterclockwise for a contour !!!!  
    drawCircle( VCentre, sides, 0.8*r, true ) ; // true draws anticlockwise, false clockwise
  endContour();
  endShape(CLOSE);  

  // Quadrant 4 (Sud Est) on trace  un doughnut dans un rectangle
  noStroke() ;
  fill( colQ4 );
  beginShape();
  vertex( width/2, height/2 );
  vertex( width, height/2 );
  vertex( width, height );
  vertex( width/2, height );
  VCentre = new PVector( 3*width/4,3*height/4) ;
  stroke(colQ4) ;
  strokeWeight(2);
  beginContour();
    drawCircle( VCentre, sides, 1.2*r, true ) ;  
  endContour();
  endShape(CLOSE);    
  beginShape() ;
  fill( colQ4 );

  drawCircle( VCentre, sides, 0.8*r, false ) ; // true draws anticlockwise, false clockwise

  endShape(CLOSE);    

}

void drawCircle(PVector Centre, int sides, float r, boolean aclockw) {
    
  // http://vormplus.be/blog/article/drawing-a-cylinder-with-processing
  float angle = 360 / sides;

    

  if ( aclockw ) {
    for (int i = sides; i >0 ; i--) {
        float x = Centre.x + cos( radians( i * angle ) ) * r; 
        float y = Centre.y + sin( radians( i * angle ) ) * r;
        vertex( x, y );        
        // println( i, " - ", i * angle ) ;
    }  
  }   else if ( !aclockw ) {
    for ( int i = 0 ; i < sides  ; i++) {
        float x = Centre.x + cos( radians( i * angle ) ) * r; 
        float y = Centre.y + sin( radians( i * angle ) ) * r;
        vertex( x, y ); 
        // println( i, " - ", i * angle ) ;
    }
  } 
  
}

Et maintenant ?

On sait tracer des cercles, faire des trous dans des objets. On peut explorer d’autres sujets !

Print Friendly, PDF & Email
0 0 votes
Évaluation de l'article
0
Nous aimerions avoir votre avis, veuillez laisser un commentaire.x