Trigo générative

trigLines

Voici le sketch animé

Le cours

Le cours applique des connaissances en trigonométrie du cours précédent dans un algorithme générative.

Dessin générative avec des lignes et des fonctions trigonométrique

Le principe de ce dessin est très simple: il y a un ligne qui avance de gauche à droit, une fois arrivé à droit elle recommence. Les extrémités de la ligne n'avancent pas régulièrement, leurs vélocité suivent un fonctions géométrique.

Alors, d'abord on va se construire une class "Ligne" qui a ces propriétés: des coordonnées x, y pour le haut et le bas et en plus ces vélocité's. Jusqu'à la c'est simple. On rajoute encore une "Lifetime" à notre ligne, c-à-d, au bout d'un certain temps, elle s'arrete.

Voici la class:

// creer un array de width et enregistrer des lignes dedans
class Ligne {
  float x_h;// position haut
  float y_h;
  float x_b;// position bas
  float y_b;
  float x_h_vel;// velocite haut
  float y_h_vel;
  float x_b_vel;// velocite bas
  float y_b_vel;
  int life;

  Ligne(float x,  int _life) {
    x_h =x;
    y_h=height/2-20;
    x_b = x; 
    y_b = height/2+20;
    x_h_vel = .5;
    y_h_vel = 0;
    x_b_vel = .5;  
    y_b_vel = 0;
    life = _life;
    addVel();
  }

  void draw() {  
    addVel();
    stroke(50, 20, 50, 40);
    line(x_h, y_h, x_b, y_b);
  }
void addVel(){
   x_h+=x_h_vel;
    y_h+=y_h_vel;
    x_b+=x_b_vel;
    y_b+=y_b_vel;
}
  boolean finished() {
    life--;
    if (life < 0) {
      return true;
    } 
    else {
      return false;
    }
  }
}

et voici le code principale:

 

Ligne ligne;
void setup() {
  size(1200,400, P2D);
  colorMode(HSB, 360,100,100,100);
  smooth();
  noCursor();
  ligne = new Ligne(0.0, 200);
}

void draw() {  
background(255);
if (!ligne.finished()) ligne.draw();

}

Maintenant, il y a un étape plus compliqué, on veut dessiner 500 ligne au même temps et pouvoir enlever les lignes quand son lifeTime est terminé. Pour cela on utilise un ArrayList, qui fonctionne presque de la même manière qu'un array (tableau) simplement elle a une fonction pour rajouter et enlever des éléments. La class ne change pas, le code principale est commenté:

// on dessine 500 ligne l'un après l'autre
avec un distance 1px et ils bouge d'un 1/2 px (x_vel 0.5)  
float x_glob; ArrayList lines; // on crée une liste avce un longueur variable void setup() {   size(1200,400, P2D);   colorMode(HSB, 360,100,100,100);   smooth();   lines = new ArrayList(); //on instancie la liste   noCursor(); } void draw() { background(255);   x_glob++;// un variable qui avance régulièrement   x_glob = x_glob%width;// en boucle avec le modulo
// pour rajouter des éléments, il y a la fonction ad: lines.add(new Ligne(x_glob, 500));
// on commence par derrière, pour pouvoir enlever des élément
for (int i = lines.size()-1; i >= 0; i--) {
// il faut dire à la liste quel type d'éléments je veux prendre (Ligne)
    Ligne laLine = (Ligne) lines.get(i);
    laLine.draw();
// remove pour enlever l'élement de la liste     if (laLine.finished()) lines.remove(i);
  } } void bg() {   fill(255, 0,100,8);   rect(0,0, width,height); }

Ok, maintenant on a 500 ligne qui se dessine l'un après l'autre, ce n'est pas encore très beau, mais le principale travail est fait!

Maintenant on rajoute dans la class des fonctions trigonométrique un peu tordu (peut être pas pour un mathématicien, mais au moins pour moi) et on le multiplie (multiplicateur) avec un valeur interactive, la position X de la souris. Comme ce valeur peut devenir trop grand, on l'ajuste avec map(). On le rajoute un paramètre dans le constructeur de la class (multiplicateur) pour pouvoir passer la valeur de la souris à l'objet.
On rajoute également un paramètre dans le constructeur qui augmente l'angle.

Voilà la parti qui change:

  Ligne(float x, float angle, float multiplicateur, int _life) {
    multiplicateur=map(multiplicateur, 0, width, 0, 20);
    x_h =x;
    y_h=height/2-20;

    x_b = x; 
    y_b = height/2+20;

    x_h_vel = multiplicateur*cos(.1*angle);
    y_h_vel = multiplicateur*sin(.6*angle);

    x_b_vel = multiplicateur*cos(1.4*angle);  
    y_b_vel = multiplicateur*sin(1.5*angle);

    life = _life;

    addVel();
  }

Dans le code principale, on rajoute quelques petits détails, un background presque transparent, un curseur pour la position de la position x de la souris, et on rajoute l'angle dans l'instanciation de la ligne.

float angle;
float x_glob;
ArrayList lines;

boolean statLine = true; 

void setup() {
  size(1200,400, P2D);
  colorMode(HSB, 360,100,100,100);
  smooth();
  lines = new ArrayList();
  noCursor();// enlever le curseur
}

void draw() {  
  bg();
  x_glob++;
  x_glob = x_glob%width;
  angle +=0.04; // un angle incrémental qui modifie la ligne
  control();
lines.add(new Ligne(x_glob, angle, mouseX, 240));
  for (int i = lines.size()-1; i >= 0; i--) {
    Ligne laLine = (Ligne) lines.get(i);
    laLine.draw(); 
    if (laLine.finished()) lines.remove(i);
  }
}

void bg() { // background presque transparent
  fill(255, 0,100,8);
  rect(0,0, width,height);
}
void control() {// donne la position de la position x de la souris
  pushStyle(); 
  stroke(360, 0, 50, 100);
  line(mouseX, height-20, mouseX, height);
  popStyle();
}

Et voilà la tour est joué. Et ici les trois étapes en zip

Ce qu'il faut connaître:
 

 

Exercice