CoCos
De Centre de Ressources Numériques - Labomedia
Révision de 17 avril 2015 à 14:48 par Zedkuesde (discussion | contributions)
CoCos |
---|
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 |
Sommaire
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é.
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]