Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentes Révision précédente
Prochaine révision
Révision précédente
atelier:processing:start [2023/01/25 15:05]
gweltaz
atelier:processing:start [2023/03/02 23:39] (Version actuelle)
gweltaz
Ligne 358: Ligne 358:
  
  
-===== Sketch ​04 : Étoile des neiges... =====+===== Sketch ​05 : Étoile des neiges... =====
  
 Encore un truc de saison, saupoudré de kitshitude, avec cette ode à l'​hiver : nous allons faire tomber de flocons. Une façon d'​aborder les particules et de s'​émerveiller devant son écran. Encore un truc de saison, saupoudré de kitshitude, avec cette ode à l'​hiver : nous allons faire tomber de flocons. Une façon d'​aborder les particules et de s'​émerveiller devant son écran.
Ligne 426: Ligne 426:
 } }
 </​code>​ </​code>​
 +
 +==== Seconde forme : Vitesse et accélération ====
 +
 +Pour le moment l'​animation des flocons est saccadée puisque qu'ils sautent d'une position à une autre (à une distance aléatoire). Ça donne un effet stop-motion assez sympa, mais si on veut avoir des mouvements plus naturels il va falloir procéder d'une autre façon : en utilisant un variable de vitesse.
 +
 +<code java>
 +PImage fl_flou;
 +PImage fl_moyen;
 +PImage fl_petit;
 +
 +ArrayList<​PVector>​ flocons_pos = new ArrayList();​
 +ArrayList<​PImage>​ flocons_img = new ArrayList();​
 +ArrayList<​PVector>​ flocons_vel = new ArrayList(); ​ // Liste qui contiendra la vitesse (linéaire et angulaire) de chaque flocon
 +
 +
 +void setup() {
 +  size(500, 500);
 +  ​
 +  fl_flou = loadImage("​snowflake_flou.png"​);​
 +  fl_moyen = loadImage("​snowflake_400.png"​);​
 +  fl_moyen.resize(100,​ 0);
 +  fl_petit = fl_moyen.copy();​
 +  fl_petit.resize(50,​ 0);
 +  for (int i=0; i<30; i++) {
 +    flocons_img.add(fl_petit);​
 +    flocons_pos.add(new PVector(random(width),​ random(height)));​
 +  }
 +  for (int i=0; i<10; i++) {
 +    flocons_img.add(fl_moyen);​
 +    flocons_pos.add(new PVector(random(width),​ random(height)));​
 +  }
 +  for (int i=0; i<4; i++) {
 +    flocons_img.add(fl_flou);​
 +    flocons_pos.add(new PVector(random(width),​ random(height)));​
 +  }
 +  ​
 +  // Donne une vitesse aléatoire (la troisième valeur étant la vitesse de rotation) à chaque flocon
 +  for (int i=0; i<​flocons_img.size();​ i++) {
 +    flocons_vel.add(new PVector( random(-1, 1) * 0.01, random(-1, 1) * 0.01, random(-1, 1) * 0.1 ));
 +  }
 +}
 +
 +
 +void draw() {
 +  background(255);​
 +  ​
 +  for (int i=0; i<​flocons_img.size();​ i++) {
 +    PImage img = flocons_img.get(i);​
 +    PVector pos = flocons_pos.get(i);​
 +    PVector vel = flocons_vel.get(i); ​ // On récupère la vitesse de ce flocon
 +    ​
 +    // On ajoute une accélération aléatoire à la vitesse
 +    vel.x += random(-1, 1) * 0.004;
 +    vel.y += random(-1, 1) * 0.002;
 +    vel.z += random(-1, 1) * 0.001;
 +    ​
 +    pos.y += img.width * (vel.y + 0.04); ​ // La position augmente en fonction de la vitesse
 +    pos.x += vel.x;
 +    pos.z += vel.z;
 +    if (pos.y > height + img.height/​2) {
 +      pos.y = -img.height/​2;​
 +      pos.x = random(width) - img.width/​2;​
 +      vel.y = 0;
 +    }
 +    // Les instructions suivantes permettent de faire une rotation et une translation du flocon
 +    push();
 +    translate(pos.x,​ pos.y);
 +    rotate(pos.z);​
 +    image(img, -img.width*0.5,​ -img.height*0.5);​
 +    pop();
 +  }
 +}
 +</​code>​
 +
 +{{ :​atelier:​processing:​flocons_processing.gif?​nolink |}}
 +
 +
 +===== Sketch 06 : Pluie =====
 +
 +On continue de suivre le fil des saisons avec une idée proposée par Martin et inspirée par un sketch, [[http://​www.polguezennec.fr/​archive/​12_impluvium/​index.html|Impluvium]] de Pol Guezennec.
 +
 +La particularité de cet exercice (et sa complexité) tient dans le fait qu'il y a deux états à l'​animation : le premier lorsque la goutte tombe verticalement,​ le second lorsque 3 ondes croissent jusqu'​à atteindre chacun leur taille maximale.
 +
 +Puisqu'​il n'y a que ces deux états on pourra utiliser une variable ''​etat''​ de type ''​boolean''​ (valeur binaire ''​true''​ ou ''​false''​) pour définir l'​état actuel de notre euh... élément aqueux.
 +
 +L' ''​etat''​ passera de ''​false''​ (goutte tombante) à ''​true''​ (onde croissante) lorsque la goutte sera tombée d'une hauteur supérieure à la composante ''​y''​ de la variable ''​pg''​. ''​pg''​ est un //vecteur// à deux composantes (''​x''​ et ''​y''​) qui définit à la fois le point de départ (sur l'axe horizontal) et le point d'​arrivée (sur l'axe vertical) de notre goutte. Les valeurs de ''​pg''​ seront réinitialisées au hasard à chaque nouveau cycle pour ajouter un peu de variété à l'​animation.
 +
 +L'​illusion n'est pas parfaite car la goutte disparaît instantanément après impact pour laisser place aux ondes. Si on était soucieux du réalisme on tronquerait progressivement la partie inférieur de la goutte qui est au-delà du point d'​impact mais bon... L'​animation est suffisamment rapide pour qu'on y voit que du feu !
 +
 +{{ :​atelier:​processing:​goutte_01.gif?​nolink |}}
 +
 +<code java>
 +// Variables de l'​état "​goutte"​
 +float vitesse_goutte = 30;  // Vitesse verticale (en pixel/​frame)
 +float taille_goutte = 70;
 +float inclinaison = 20;     // Décallage horizontal (en pixels) entre le haut et le bas de la goutte
 +PVector pg = new PVector(random(500),​ 370);  // Contient la coordonnée horizontale de la goutte (x)
 +                                              // Et la coordonnée verticale du point d'​impact final (y)
 +PVector p1 = new PVector(pg.x,​ -taille_goutte); ​ // Point supérieur de la goutte
 +PVector p2 = new PVector(pg.x + inclinaison,​ 0); // Point inférieur de la goutte
 +
 +// Variables de l'​état "​onde"​
 +float vitesse_onde = 3;     // Vitesse de croissance des ondes (en pixel/​frame)
 +float decalage_onde = 40;   // Décallage entre chaque onde (en pixels)
 +float taille = 0.0;         // Taille de la première onde, à chaque instant
 +float taille2 = -1 * decalage_onde; ​ // Taille de la deuxième onde, à chaque instant
 +float taille3 = -2 * decalage_onde; ​ // Taille de la troisième onde, à chaque instant
 +float taille_max = 150;
 +float ratio = 2.5;          // Ratio entre la largeur et la hauteur de l'onde
 +
 +boolean etat = false; ​     // État goutte si "true, état onde si "​false"​
 +
 +
 +void setup() {
 +  size(500, 500);
 +  stroke(#​9D62FF);​
 +  strokeWeight(2);​
 +  noFill();
 +}
 +
 +void draw() {
 +  background(255);​
 +
 +  if (etat == false) {
 +    // Goutte d'eau
 +    p1.y += vitesse_goutte; ​     // La goutte descend (verticalement)
 +    p2.y += vitesse_goutte;​
 +    p1.x += vitesse_goutte * inclinaison / taille_goutte; ​ // La goutte se décalle en fct de son inclinaison
 +    p2.x += vitesse_goutte * inclinaison / taille_goutte;​
 +    line(p1.x, p1.y, p2.x, p2.y);
 +
 +    if (p2.y > pg.y) {
 +      etat = true;
 +      pg.x = p2.x;
 +    }
 +  } else {
 +    // Ondes
 +    taille = taille + vitesse_onde;​
 +    taille2 = taille2 + vitesse_onde;​
 +    taille3 = taille3 + vitesse_onde;​
 +
 +    if (taille > 0 && taille < taille_max)
 +      ellipse(pg.x,​ pg.y, ratio * taille, taille);
 +    if (taille2 > 0  && taille2 < taille_max)
 +      ellipse(pg.x,​ pg.y, ratio * taille2, taille2);
 +    if (taille3 > 0)
 +      ellipse(pg.x,​ pg.y, ratio * taille3, taille3);
 +
 +    if (taille3 > taille_max) {
 +      taille = 0.0;
 +      taille2 = -1 * decalage_onde;​
 +      taille3 = -2 * decalage_onde;​
 +      etat = false;
 +      pg = new PVector(random(0,​ 500), random(200, 400));
 +      p1 = new PVector(pg.x,​ -taille_goutte);​
 +      p2 = new PVector(pg.x + inclinaison,​ 0);
 +    }
 +  }
 +}
 +</​code>​
 +
 +
  • atelier/processing/start.1674655513.txt.gz
  • Dernière modification: 2023/01/25 15:05
  • par gweltaz