CoCos

De Centre de Ressources Numériques - Labomedia
Aller à : navigation, rechercher
CoCos
Cocos.png


Pour modifier la page utiliser l'onglet Modifier avec formulaire.

Résumé Travail autour de la fonction Cosinus
Auteur(s) 01ivier
Licence CC-BY-SA 3
Date de création 01 décembre 2014


Intentions / Contexte

Écrire un sketch qui exploite la fonction cosinus pour obtenir des motifs graphiques à par cher pour un Bit de Dieu.

Principe de fonctionnement

Chaque petit carré se déplace selon la fonction cosinus mais sont tous décalé d'un nombre fixe de degré.

Besoins / Compétences

Processing

Documentation

Mode d'emploi

  • Le slider du haut gère un coef1 tel que l'ordonnée d'un petit carré = cos(angle)*coef1
  • Le slider du milieu gère un coef2 tel que l’abscisse d'un petit carré = cos(angle)*coef2
  • Le slider du bas gère l'écart entre les angles respectifs de chaque carré, sachant que tous les angles s'incrémentent de 1 à chaque frame.
  • La barre d'espace vous permets de passer d'une ligne à un carré.

Cocos1.gif Cocos2.gif

Code

Il existe 3 versions différentes :

Version en Processing JS

Cette version est visible en ligne ici.

ControlP5 n'étant pas porté en JS, j'ai utilisé la class HScrollbar

import controlP5.*;

HScrollbar hs1, hs2, hs3, hs4;  // Two scrollbars

Ronde[] groupe;

int nbPart, versCentre;
boolean oneOrAll;

void setup() {

  size(500, 500);
  noStroke();
  frameRate(60);

  hs1 = new HScrollbar(70, 20, 360, 8, 1, 280);
  hs2 = new HScrollbar(70, 40, 360, 8, 1, 370);
  hs3 = new HScrollbar(70, 60, 360, 8, 1, 79);

  oneOrAll = false;
  nbPart = 51;
  versCentre = height/4;

  groupe =  new Ronde[2601];
  for (int i = 0; i < groupe.length; i++) {

    groupe[i] = new Ronde(i);
  }
}

void draw() {

  background(255);

  for (int i = 0; i < nbPart; i++) {
    groupe[i].affiche(hs1.getPos()-180, hs2.getPos()-180, hs3.getPos(), versCentre);
  }

  hs1.update();
  hs2.update();
  hs3.update();

  hs1.display();
  hs2.display();
  hs3.display();

}

void keyPressed () {

  if (key == ' ') {

    oneOrAll = !oneOrAll;

    if (oneOrAll) {
      nbPart = 2601;
      versCentre = 0;
    } else {
      nbPart = 51;
      versCentre = height/4;
    }

    for (int i = 0; i < nbPart; i++) {
      groupe[i].reset();
    }
  }
}

class Ronde {

  float angle = 0;
  float decalage = 0;
  int ID;
  float X, Y;
  int xInit, yInit, compteur;
  int taille, nbParLigne;
  int fromSlider;

  Ronde(int num) {   

    ID = num;
    taille = 5;
    nbParLigne = 51;
    xInit = num%nbParLigne * taille;
    yInit = (int) (num/nbParLigne) * taille;

    compteur = 0;
    angle = 0;
  }

  void affiche(int val1, int val2, int val3, int versCentre) {


    angle = ID*val3 + frameCount%360;
    decalage = cos(radians(angle));

    X = width/4 + xInit + decalage*val1;
    Y = height/4 + yInit + decalage*val2 + versCentre;    

    fill(255, 50, 100, 180);
    rect(X, Y, taille, taille);
  }

  void reset() { 

    compteur = 0;
  }
}

class HScrollbar {
  int swidth, sheight;    // width and height of bar
  float xpos, ypos;       // x and y position of bar
  float spos, newspos;    // x position of slider
  float sposMin, sposMax; // max and min values of slider
  int loose;              // how loose/heavy
  boolean over;           // is the mouse over the slider?
  boolean locked;
  float ratio;

  HScrollbar (float xp, float yp, int sw, int sh, int l, int init) {
    swidth = sw;
    sheight = sh;
    int widthtoheight = sw - sh;
    ratio = (float)sw / (float)widthtoheight;
    xpos = xp;
    ypos = yp-sheight/2;
    spos = init;
    newspos = spos;
    sposMin = xpos;
    sposMax = xpos + swidth - sheight;
    loose = l;
  }

  void update() {
    if (overEvent()) {
      over = true;
    } else {
      over = false;
    }
    if (mousePressed && over) {
      locked = true;
    }
    if (!mousePressed) {
      locked = false;
    }
    if (locked) {
      newspos = constrain(mouseX-sheight/2, sposMin, sposMax);
    }
    if (abs(newspos - spos) > 1) {
      spos = spos + (newspos-spos)/loose;
    }
  }

  float constrain(float val, float minv, float maxv) {
    return min(max(val, minv), maxv);
  }

  boolean overEvent() {
    if (mouseX > xpos && mouseX < xpos+swidth &&
       mouseY > ypos && mouseY < ypos+sheight) {
      return true;
    } else {
      return false;
    }
  }

  void display() {
    noStroke();
    fill(255, 200, 200);
    rect(xpos, ypos, swidth, sheight);
    if (over || locked) {
      fill(160, 0, 80);
    } else {
      fill(255, 50, 100);
    }
    rect(spos, ypos, sheight, sheight);
  }

  int getPos() {
    // Convert spos to be values between
    // 0 and the total width of the scrollbar
    return int(spos - 70);
  }
}

Version en Processing

Cette version présente en plus la possibilité de sauvegarder les trois valeurs des sliders "sous" chaque touche alpha du clavier.

  • Une pression sur l'une des 26 lettres de l'alphabet, recharge le preset.
  • Maj+Touche pour sauvegarder le preset sur cette touche.
 
import controlP5.*;

Ronde[] groupe;
ControlP5 cp5;
int coef1, coef2, coef3, banque;
int nbPart, versCentre;
boolean oneOrAll;

String[] contenu_sauvegarde; 

void setup() {

  size(600, 600);
  noStroke();
  frameRate(60);

  oneOrAll = false;
  nbPart = 61;
  versCentre = height/4;

  banque = 32;

  contenu_sauvegarde = loadStrings("sauvegarde.txt");

  cp5 = new ControlP5(this);
  cp5.addSlider("coef1")
    .setPosition(5, 10)
      .setColorBackground(0)
        .setColorActive(color(255, 0, 0))
          .setColorForeground(color(150, 150, 150))
            .setColorCaptionLabel(color(150, 150, 150))
              .showTickMarks(true)
                .setRange(-100, 100)
                  .setWidth(width-40)
                    .setValue(50)
                      ;

  cp5.addSlider("coef2")
    .setPosition(5, 20)
      .setColorBackground(0)
        .setColorActive(color(255, 0, 0))
          .setColorForeground(color(150, 150, 150))
            .setColorCaptionLabel(color(150, 150, 150))
              .showTickMarks(true)
                .setRange(-100, 100)
                  .setWidth(width-40)
                    .setValue(100)                  
                      ;

  cp5.addSlider("coef3")
    .setPosition(5, 30)
      .setColorBackground(0)
        .setColorActive(color(255, 0, 0))
          .setColorForeground(color(150, 150, 150))
            .setColorCaptionLabel(color(150, 150, 150))
              .showTickMarks(true)
                .setRange(0, 360)
                  .setWidth(width-40)
                    .setValue(6)
                      ;

  groupe =  new Ronde[3721];
  for (int i = 0; i < groupe.length; i++) {

    groupe[i] = new Ronde(i);
  }
}

void draw() {

  background(0);

  for (int i = 0; i < nbPart; i++) {
    groupe[i].affiche(coef1, coef2, coef3, versCentre);
  }

  fill(255);
  text(char(banque), 10, 590);
  
}

void keyPressed() {

  if (key == ' ') {

    oneOrAll = !oneOrAll;

    if (oneOrAll) {
      nbPart = 3721;
      versCentre = 0;
    } else {
      nbPart = 61;
      versCentre = height/4;
    }

    for (int i = 0; i < nbPart; i++) {
      groupe[i].reset();
    }
  }

  //// Gestion du chargement et de la sauvegarde
  for (int i=0; i < 27; i++) {
    if (key == i+65) {
      sauvegarde(i);
      banque = i+65;
    }
    if (key == i+97) {
      chargement(i);
      banque = i+97;
    }
  }
  ////
}

void chargement(int place) {
  int rang = place * 3;
  contenu_sauvegarde = loadStrings("sauvegarde.txt");
  cp5.getController("coef1").setValue(int(contenu_sauvegarde[rang]));
  cp5.getController("coef2").setValue(int(contenu_sauvegarde[rang+1]));
  cp5.getController("coef3").setValue(int(contenu_sauvegarde[rang+2]));
}

void sauvegarde(int place) {
  int rang = place * 3;
  contenu_sauvegarde[rang] = String.valueOf(cp5.getController("coef1").getValue());
  contenu_sauvegarde[rang+1] = String.valueOf(cp5.getController("coef2").getValue());
  contenu_sauvegarde[rang+2] = String.valueOf(cp5.getController("coef3").getValue());
  saveStrings("sauvegarde.txt", contenu_sauvegarde);
}

class Ronde {

  float angle = 0;
  float decalage = 0;
  int ID;
  float X, Y;
  int xInit, yInit, compteur;
  int taille, nbParLigne;
  int fromSlider;

  Ronde(int num) {   

    ID = num;
    taille = 5;
    nbParLigne = 61;
    xInit = num%nbParLigne * taille;
    yInit = num/nbParLigne * taille;

    compteur = 0;
    angle = 0;
  }

  void affiche(int val1, int val2, int val3, int versCentre) {


    angle = ID*val3 + frameCount%360;
    decalage = cos(radians(angle));

    X = width/4 + xInit + decalage*val1;
    Y = height/4 + yInit + decalage*val2 + versCentre;    

    fill(255, 255, 0, 126);
    rect(X, Y, taille, taille);
  }

  void reset() {
    compteur = 0;
  }
}

Version en Processing avec de la vidéo

 
import controlP5.*;
import processing.video.*;  


Ronde[] groupe;
ControlP5 cp5;
int coef1, coef2, coef3;
int nbPart, versCentre;
boolean oneOrAll;

Capture cam;
int Longg = 320;  
int Largg = 240;
int nbPix = Longg*Largg;

void setup() {

  size(600, 600);
  noStroke();
  frameRate(60);

  oneOrAll = false;
  nbPart = Longg;
  versCentre = height/4;

  cp5 = new ControlP5(this);
  cp5.addSlider("coef1")
    .setPosition(5, 10)
      .setColorBackground(0)
        .setColorActive(color(255, 0, 0))
          .setColorForeground(color(150, 150, 150))
            .setColorCaptionLabel(color(150, 150, 150))
              .showTickMarks(true)
                .setRange(-100, 100)
                  .setWidth(width-40)
                    //.setValue(0)
                    ;

  cp5.addSlider("coef2")
    .setPosition(5, 20)
      .setColorBackground(0)
        .setColorActive(color(255, 0, 0))
          .setColorForeground(color(150, 150, 150))
            .setColorCaptionLabel(color(150, 150, 150))
              .showTickMarks(true)
                .setRange(-100, 100)
                  .setWidth(width-40)
                    .setValue(50)                  
                      ;

  cp5.addSlider("coef3")
    .setPosition(5, 30)
      .setColorBackground(0)
        .setColorActive(color(255, 0, 0))
          .setColorForeground(color(150, 150, 150))
            .setColorCaptionLabel(color(150, 150, 150))
              .showTickMarks(true)
                .setRange(0, 360)
                  .setWidth(width-40)
                    .setValue(9)
                      ;

  groupe =  new Ronde[nbPix];
  for (int i = 0; i < groupe.length; i++) {

    groupe[i] = new Ronde(i);
  }

  cam = new Capture(this, Longg, Largg, "/dev/video0", 20);
  cam.start();
}

void draw() {

  if (cam.available() == true) { 
    cam.read();
  } 

  background(255);

  for (int i = 0; i < nbPart; i++) {

    color couleur = cam.pixels[i];
    groupe[i].affiche(coef1, coef2, coef3, versCentre, couleur);
  }
}

void keyPressed () {

  if (key == ' ') {

    oneOrAll = !oneOrAll;

    if (oneOrAll) {
      nbPart = nbPix;
      versCentre = 0;
    } else {
      nbPart = Longg;
      versCentre = height/4;
    }

    for (int i = 0; i < nbPart; i++) {
      groupe[i].reset();
    }
  }
}

class Ronde {

  float angle = 0;
  float decalage = 0;
  int ID;
  float X, Y;
  int xInit, yInit, compteur;
  int taille, nbParLigne;
  int fromSlider;

  Ronde(int num) {   

    ID = num;
    taille = 1;
    nbParLigne = 320;
    xInit = num%nbParLigne * taille;
    yInit = num/nbParLigne * taille;

    compteur = 0;
    angle = 0;
  }

  void affiche(int val1, int val2, int val3, int versCentre, color couleur) {


    angle = ID*val3 + frameCount%360;
    decalage = cos(radians(angle));

    X = width/4 + xInit + decalage*val1;
    Y = height/4 + yInit + decalage*val2 + versCentre;    

    fill(couleur);
    rect(X, Y, taille, taille);
  }

  void reset() { 

    compteur = 0;
  }
}

[Mon projet | test]