La_bibliothèque

Réalisations Artistiques, Visuels Génératifs

J’ai eu l’occasion de travailler pour « La_Bibliothèque » (http://www.la-bibliotheque.com/) dans le cadre de leur « carte blanche numérique ».

Ce projet a donc été l’opportunité de travailler sur leurs données d’emprunts. Comme tout projet de représentation de données, nous avons choisis de travailler de manière systémique et donc de s’assurer de la pérennité de l’alimentation en données du projet. La collecte de données commence donc en janvier 2017 et est mise à jour tous les mois depuis cette date par le service numérique de La_Bibliothèque.

D’un point de vue représentation de données quatre tableaux ont été crées, ils représentent tous le même jeu de données mais ces données sont traitées différemment selon l’angle de représentation choisi :

 

Le premier tableau reprend et décline la charte graphique existante, transformant ainsi le logo en outil de visualisation de données :

https://labibliotheque.github.io/CBN_2017/lb_enluminures-functions/index.html

 

Le deuxième tableau prend une approche plus technique bien que fortement esthétisée et fournit donc des données par lieux mais aussi par emplacement documentaires concernés ainsi que quelques données statistiques plus génériques

https://labibliotheque.github.io/CBN_2017/lb_etoiles_quotidiennes/index.html

 

Le troisième tableau reprend un thème qui m’est cher : la sonification de données. Au lieu de représenter les données par le visuel, j’aime expérimenter avec leur représentation sonore. Chacun de nos sens a ses propres caractéristiques et nos oreilles sont particulièrement adaptées à reconnaitre des motifs rythmiques et mélodique qui ne seraient pas forcément captés par discrimination visuelle. Ce tableau propose donc une représentation mixte des données et permettra d’explorer auditivement les rythmes d’emprunts sur plusieurs mois / années.

https://labibliotheque.github.io/CBN_2017/lb_landscape_audio/index.html

 

Le quatrième et dernier tableau permet de resituer les données dans leur territoire. La_Bibliothèque étant composée de différents lieux elle propose une occupation du territoire particulière en fonction de la géographie, mais aussi du temps avec les horaires d’ouvertures. Ce tableau essaie donc de rendre compte de cela en rendant visible la « diffusion » des documents dans l’espace géographique.

https://labibliotheque.github.io/CBN_2017/lb_geopacking/

 

D’un point de vue technique, l’ensemble du projet a été réalisé via l’hébergement gratuit de pages statiques fournit par github. Une part du projet a d’ailleurs consisté en le fait de créer une page « backend », permettant à La_Bibliothèque de s’authentifier avec ses identifiants github pour pouvoir soumettre un export de leur base de donnée en le « pushant » directement sur le « repository ». Cette petite astuce m’a permis d’éviter de louer un serveur et d’avoir recours à une base de donnée dynamique pour mettre à jour les données.

L’intégralité du code est disponible à cette adresse :

https://github.com/labibliotheque/CBN_2017

Publicités

Plante #1

Visuels Génératifs

bigorneaux-1139

bigorneaux-1031


color [] colors = {
#C5E0DC, #DAF5F0, #F9E9CC, #FAF6D6,#FFD0C1
};

Circles[] cir = new Circles [5];
boolean update = true;
void setup() {
size(800, 600);
background(0);
frameRate(60);
ellipseMode(CENTER);
noStroke();
//strokeWeight(0.5);
smooth();

//stroke(0, 180);
// colorMode(HSB, 360, 100, 100);

for (int i = 0 ; i < cir.length ; i++) {
int size = int(random(25, 50));
cir[i] = new Circles (colors[0], width/2, height, size);
}
}

void draw() {

for (int i = 0 ; i < cir.length ; i++) {

cir[i].update();
cir[i].draw();

if (frameCount%20==0 && update) {

if (cir[i].circle_size == 1 ) {
int size = int(random(25, 125));
cir[i] = new Circles (colors[0], width/2,random(height-50,height), size);
}
}
}
}

void keyReleased(){
if (key == 'u' || key =='U'){
update = !update;
}

if (key == 's' || key =='S'){
saveFrame("/images/bigorneaux-####.jpg");
}
}
class Circles {

int circle_size = 1200;
color c;

float xpos, ypos;

float noiseF;

int steps = 0;
int max_step=5;

Circles(color c, float xpos, float ypos, int circle_size) {
this.c = c;
this.xpos = xpos;
this.ypos = ypos;
// circle_size = int( random(50, 250));
noiseF = random(500);
this.circle_size = circle_size;
max_step =int(random(2,10));
//steps = int(random(15));
}

void update() {
if (circle_size > 1) {
circle_size--;
}

noiseF += 0.005;
xpos += map(noise(noiseF, ypos/100, 25), 0, 1, -8,8);
ypos += map(noise(noiseF, xpos/100, 56), 0, 1, -6, 0);

steps +=1;
//noStroke();
if (steps == max_step) {
int index = int(random(colors.length));
c = colors[index];
steps = 0;
max_step =int(random(2,15));
// stroke(0.15);
}
}

void draw() {
fill(c);
ellipse(xpos, ypos, circle_size, circle_size);
}

void setColor (color c) {
this.c =c;
}
}

Grid #1

Visuels Génératifs

70s-2014-6-11-17h12m30s 70s-2014-6-11-17h12m42s 70s-2014-6-11-17h14m24s 70s-2014-6-11-17h14m25s

 


int size = 80;

float seed;

float rect_round ;

float steps;

color [] colors = {
#F5E0A7, #CFA678, #BBD7AF, #56AA9B, #026376
};
//color [] colors = { #92EDF0, #12223D, #DE1818, #040505};

void setup() {
size(800, 600, P2D);
smooth();

rectMode(CENTER);
colorMode(HSB, 360, 100, 100, 255);
noStroke();

frameRate(30);
}

void draw() {

steps+=0.035;
background(0, 0, 100);
randomSeed(floor(seed));

for (int i = size/2 ; i < 1200 ; i+=size*39/50) {
for (int j = size/2 ; j < 600 ; j+=size*36/50) {

float p = random(100);
for (int k = 1 ; k <= colors.length ; k++) {
if (p< k*100/colors.length && p>(k-1)*100/colors.length) {
fill(colors[k-1], 100);
}
}

rect_round = map(sin(steps), -1, 1, -145, 40);
pushMatrix();
translate(i, j);
rotate(PI/4);
rect(0, 0, size, size, rect_round);
popMatrix();
}
}

// saveFrame("/frames/70s-####.tiff");
}
void mousePressed() {
seed = floor(random(5000));
println("seed : " +seed);
}

void keyPressed() {
if (key == 's' || key == 'S') {
saveFrame("70s-"+year()+"-"+month()+"-"+day()+"-"+hour()+"h"+minute()+"m"+second()+"s.png");
}
}

 

Spirales

Visuels Génératifs

 


float r=0;
float rand=0;

void setup(){
size(1680,945);
background(0);
smooth();
noStroke();

}

void draw(){

translate(250,150);
rand= random(100);

if (rand<35){
fill(200,random(40,80));
} else {

fill(255,random(90,150));
}

rotate(r);
float circle_size = random(17,25);
ellipse(r+0.1,10,circle_size, circle_size);
r = r+0.021;

}

void keyPressed(){
save("####.png");
println("Image sauvegardée");
}

&nbsp;

Noisy Works

Visuels Génératifs

Those visuals are based on experiments with perlin noise and polar coordinates with processing , you’ll need to add your own font to make it work.


float edgeX, edgeY;
float radius =325;
float noiseF;
int startTime ;

PFont title, seed, time;
void setup() {
size(700, 700);

smooth();

colorMode(HSB, 255, 100, 100, 100);
//textMode(CENTER);

title = createFont("Candara-Bold-16.vlw", 18);
seed = createFont("Consolas-16.vlw", 12);
time = createFont("Corbel-16.vlw", 12);
textAlign(CENTER, CENTER);
//textFont(seed);
generate();
}

void draw() {
if (mousePressed) {
startTime = millis();
noiseF = random(5000);
println("noiseSeed : " + noiseF);
generate();
}
}

void generate() {
background(255);
translate(width/2, height/2);
for (int j = 0 ; j < 320 ; j ++ ) {
stroke(0, 255);
noFill();
beginShape();
for (float i = 0 ; i <= TWO_PI + PI/24 ; i += PI/24) {
randomSeed(floor(i*100*noiseF));
edgeX = (radius-j + map(noise(noiseF, i, 20), 0, 1, -150, 150)) * cos (i);
edgeY = (radius-j + map(noise(noiseF, 25, i), 0, 1, -150, 150)) * sin (i);
curveVertex(edgeX, edgeY);
noiseF += 0.00005;
}
endShape(CLOSE);
}
noStroke();
fill(0, 210);
ellipse(0/2, 0/2, 190, 190);
fill(map(noiseF, 0, 5000, 0, 255), 100, 100);
ellipse(0/2, 0/2, 170, 170);
fill(255);
ellipse(0/2, 0/2, 8, 8);
fill(255, 0, 100);
String s ="-- Noisy Works --";
String s1 = " seed :"+noiseF;
int endTime = millis();
int gentime = endTime - startTime;
println(gentime);
textFont(title);
text(s, 0, -35);
textFont(seed);
text(s1, 0, 15);
textFont(seed);
String s2 = " gen. time : 0."+gentime+" s";
text(s2, 0, 30);
}
void keyPressed() {
if (key == 's' || key == 'S') {
saveFrame("lps-"+year()+"-"+month()+"-"+day()+"-"+hour()+"h"+minute()+"m"+second()+"s.png");
}
}



 

Snowflakes

Visuels Génératifs

 

The code is based on a l-system implementation (http://en.wikipedia.org/wiki/L-system), here is the Processing code to generate the bigger ones, you can press the right arrow to generate a new one, any other key will save the image :


int maxLevel =10;
int numChildren =1;
float angle = PI/4;

Branch trunk;

void keyPressed() {
if (key == CODED && keyCode == RIGHT) {
maxLevel = int(random(5, 25));
angle = PI/(int(random(1, 15))*2);
newTree();
trunk.siz = random(50, 500);
} else {
saveFrame("snowFlake-######.png");
}
}

void setup() {
size(1280, 766);
noFill();
smooth();
newTree();
background(0);
stroke(255);
}

void newTree() {
pushMatrix();
translate(width/2, height/2);
trunk = new Branch(1, 0, 0, 0);
trunk.drawMe();
popMatrix();
}

void draw() {
noStroke();
fill(0, 150);
rect(0, 0, width, height);
//background(0);

stroke(255);
pushMatrix();
translate(width/2, height/2);
trunk.updateMe(0, 0);
trunk.drawMe();
popMatrix();
}

class Branch {
float level, index;
float x, y;
float endx, endy;
float noiseF2;

float siz =100;

Branch[] children = new Branch[0]; //

Branch (float lev, float ind, float ex, float wy) {
level =lev;
index =ind;
updateMe(ex, wy);

if (level<maxLevel) { // avoid infinite loop
children = new Branch[numChildren];
for (int i = 0; i<numChildren;i++) {
children[i] = new Branch(level+1, i, endx, endy);
}
}
}

void updateMe(float ex, float wy) {
x =ex;
y =wy;

float newsiz =map (maxLevel-level, 0, maxLevel, 1, siz);
endx = x;
endy = y-newsiz/3;
//siz -=10;

for (int i =0; i<children.length; i++) {
children[i].updateMe(endx, endy);
}
}

void drawMe() {
//siz-=1;
float newsiz =map (maxLevel-level+1, 0, maxLevel, 2, siz);
for (float i = 0 ; i < TWO_PI ; i+=angle) {
rotate(i);
strokeWeight(map(maxLevel-level+1, 0, maxLevel, 0.005, 0.5));
pushMatrix();
beginShape();
vertex(x-newsiz, y);
vertex(x, y+newsiz*2/3);
vertex(x+newsiz, y);
vertex(x, y+newsiz*1/3);
vertex(x-newsiz, y);
endShape();
popMatrix();
}

for (int i = 0 ; i<children.length;i++) {
//children[i].updateMe();
children[i].drawMe();
}
}
}