Tous les articles par Alexandre Rivaux

Interactive & Visual Designer, co-fondateur du Studio Bonjour, interactive lab. Assistant filière design interactif à e-art sup et enseignant de l'option Digital Lab à e-art sup Paris

Liste des Sujets 2016-2017 [IxD] (1er Semestre)

Retrouvez la liste complètes des sujets travaillés en cours de design interactif (3e. année) sur le premier semestre de l’année 2016-2017.

Sujets et cours

 

Liste des cours Processing + P5JS 2016-2017 [Digital Lab]

Retrouvez la liste complètes des cours de digital lab — processing/P5js (3e. année, option) sur l’année 2016-2017

Semestre 1

Liste des Sujets 2015-2016 [IxD]

Retrouvez la liste complètes des sujets travaillés en cours de design interactif (3e. année) sur l’année 2015-2016.

Liste des sujets de design interactif :

Sujet + liste des cours Processing 2015-2016 [Digital Lab]

Retrouvez la liste complètes des cours et le sujet travaillés en cours de digital lab — processing (3e. année, option) sur l’année 2015-2016

Sujet 2015-2016

Cours 2015-2016

 

Documenter son travail de creative coding

La documentation d’un travail est une partie indispensable à tout projet. D’une part parce que la documentation d’un projet permet d’en retracer la genèse mais également parce qu’elle permet d’en retrouver les sources. Cela est d’autant plus utile dans le cadre d’un projet de creative coding.

Qui ne s’est jamais replongé dans un projet une semaine, un mois ou un an après en se posant l’une des questions suivantes :

  1. « Pourquoi avais-je fais ces choix graphiques ? »
  2. « Quelle était la problématique de départ? Quels étaient mes conclusions ? »
  3. « Que peut bien faire cette fonction ? Comment fonctionne-t-elle ? »

Autant de questions qui montrent l’importance d’un travail documenté.

Commenter son code

L’une des premières méthodes de documentation est sans aucun doute l’ajout de commentaires au code source du projet. Évidemment il est inutile de documenter la moindre ligne de code. Ainsi il est plus judicieux de documenter les algorithmes dont il sera important se de rappeler du fonctionnement.

L’exemple suivant montre une méthode commentée permettant de calculer la position d’un point sur un cercle.

Dans le cas de certaines fonctions nous utiliserons des commentaires plus détaillés permettant de retrouver le détail de l’algorithme. L’exemple suivant montre une fonction documentée permettant d’appliquer une rotation à un vecteur en 3 dimensions autour d’un vecteur servant d’axe.

Codes et attribution

Réutiliser des codes (entier ou par portions) trouvés sur internet est un bon exercice pratique cependant la réutilisation de code sans en avoir citer la source peut être considérée comme de la copie et du plagiat.

Le developpement a toujours impliqué l’utilisation de code provenant d’autres sources et nous avons la chance de profiter d’une communauté open source. Sans le partage de savoir de cette communauté celle-ci ne grandirait pas et votre travail ne verrait sans doute pas le jour. C’est la raison pour laquelle il est éthique de citer ses sources.

Tout comme vous citez les sources original dans vos travaux graphiques et écrits, vous devez citer l’ensemble des sources techniques afférant à votre projet tel que les auteurs des algorithmes ou outils incorporés à vos projets ou les documents de recherches et cours utilisés dans la création de votre projet.

Texte original de Scott Murray, Assistant Professor, Design Department of Art + Architecture, University of San Francisco.

Lorsque que vous utilisez une fonction ou un code réalisé par un autre développeur il est donc important d’en citer la source. Tout comme le commentaire de fonction, citer la source vous permet à vous et aux autres personnes qui auront accès à votre code de retrouver l’origine de l’algorithme, du programme et de sa documentation. Lorsque nous citons la provenance d’une méthode nous utiliserons la méthode suivante :

edit (26/11/2015) : Jonathan, collègue enseignant et co-créateur du site disruptions.fr, m’a fait remonter un commentaire en ce qui concerne l’importance de la citation du code d’autrui :

En ce qui concerne les citations du code d’autrui, en plus de l’aspect morale, il y a un côté bassement pragmatique – parfois le code ne fonctionne pas dans telle ou telle condition. D’avoir le lien accessible permet de vérifier s’il y a une mise à jour [tenant compte de votre problème] ou de dialoguer avec l’auteur pour déceler le problème.

Jonathan Munn

Documenter l’ensemble de son travail

ixd-documentation
Extrait de la documentation d’un projet d’installation interactive — Bonjour, interactive lab 2015

Si l’utilisation des commentaires permet à la fois de documenter son code et d’en citer les sources et références, ils ne permettent pas d’incorporer des images ou vidéos. Lors de la réalisation d’un projet il est important de tenir à jour une documentation complète permettant à tout instant de revenir en arrière sur la phase d’un projet. Cette documentation est destinée avant tout à nous même et aux collaborateurs du projet. Elle ne requiert donc pas de mise en forme particulière et peut tout à fait prendre la forme d’un document texte. Pour ma part mes documentations prennent la forme d’un document texte reprenant les points suivants :

  1. Concept
  2. Références
  3. Détail de l’idée
  4. Parcours utilisateur
  5. Questionnement :
    remise en cause ou points à explorer durant le projet
  6. Pour aller plus loin :
    Déclinaisons et évolutions possibles du projet
  7. Scénographie / format d’exploitation
  8. Cahier des charges techniques :
    Technologies envisagées, langages, librairies…
  9. Notes de développement :
    Note au jour le jour du développement effectué indiquant les problèmes rencontrés, les solutions envisagées, les sources et les références.

Une fois le projet terminé, le document pourra alors être remise en forme afin de réaliser le making of ou servir aux évolutions futur du projet.

Introduction à Processing [3.0]

Processing est un langage de programmation open source basé sur JAVA et un IDE (integrated development environment) créé par Ben Fry et Casey Reas en 2001. Leur projet était de créer un langage simple, destiné aux graphistes et artistes, afin de répondre à certains de leur besoins tel que la visualisation de données ou la production de visuels génératifs. Processing est le prolongement « multimédia » de Design by Numbers, l’environnement de programmation graphique développé par John Maeda au MIT Media Lab.

Processing a bien évolué depuis sa création en 2001. S’il est toujours un véritable outils de production pour les artistes et designers interactifs il est également une plateforme d’apprentissage de la programmation à destination de l’éducation. Lors de sa conférence à Eyeo 2015, Casey Reas présenta notamment l’évolution de Processing mais également le developpement de la Fondation Processing autour de nouveaux outils tel que P5.js et Processing.py.

Processing est basé sur JAVA, rendant ainsi le langage plus facile d’accès par le biais d’une syntaxe simple sans pour autant simplifier JAVA, cela permet notamment d’accéder à l’ensemble de possibilités offertes par JAVA. Il intègre également OpenGL permettant ainsi d’accéder à de plus grandes capacités graphiques dans le traitement d’éléments 2D et 3D.

Si nous devions faire un rapide état des lieux des principaux langages utilisés dans le design génératif ou l’art numérique en règle générale nous aurions :

  • C/C++ avec des librairies tel que OpenFramework, Cinder…
  • Java en natif ou via Processing
  • Javascript en natif ou via des frameworks tel que Angular.js, Tree.js, Backbone.js…
  • Les langages de type nodal avec VVVV, Max MSP/Jitter ou Pure Data

Il existe évidement de nombreux autres langages utilisés dans l’expérimentation interactive et visuelle tel que Flash (même si son utilisation se fait rare de nos jours) ou encore Touch Designer.

Les cours de l’option «Digital Lab» à e-art sup Paris porteront sur les expérimentations visuelles et interactives, qu’elles soient sur écran ou hors écran et ce à travers l’utilisation de Processing. Cette option a pour but d’expérimenter de nouvelles techniques de design apportées par le design par le code et de sortir des techniques habituelles de conception. Il sera une initiation à l’expérimentation interactive et aux cours de développement interactif apportés par la filière Design Interactif d’e-art sup.

Cette année (2015-2016) l’enseignement portera essentiellement sur Processing 3.0, la dernière version stable de Processing.

Introduction et nouveautés

Septembre 2015 a vu la sortie de la version 3.0 de Processing. Cette nouvelle version offre sans doute l’un des plus grands changements de Processing, son IDE devient plus développé et sa base a été repensé. Cet article s’adresse aussi bien aux néophytes qu’aux personnes utilisant déjà Processing. Nous couvrirons aussi bien les bases du langage que ses nouveautés. Afin d’être plus accessible à tout le monde, les paragraphes traitant des nouveautés et d’informations nécessitant une plus grande connaissance du langage seront marqués du signe § orange.

§ Parmi les grands changements de Processing 3.0 nous noterons :

  • La reconstruction du moteur de rendu OpenGL (2D et 3D) aujourd’hui plus rapide et sans saccade. On note également l’apparition d’un nouveau moteur de rendu, le Java FX2D.
  • La création d’un nouvel éditeur comportant :
    • Une numérotation des lignes
    • La possibilité d’utiliser de l’autocomplétion
    • L’ajout d’un debugger simple (temps réel) et avancé
    • L’ajout du TweakMode en natif (souffre encore de quelques bugs sous windows 7, 8, 8.1 et 10)
  • Le support des résolutions retina via les méthodes pixelDensity() et displayDensity()
  • Le retrait de l’utilisation de variables avec la méthode size(). Il est toujours possible de changer la taille du programme via la méthode surface.setSize(w, h)
  • L’objet frame devient l’objet surface
  • La réécriture de l’objet PApplet. De part ce changement de nombreux sketch et librairies risquent de ne pas être compatible de processing 2.0 à processing 3.0. Beaucoup ont déjà été mis à jour pour Processing 3.0
  • L’ajout d’une méthode fullScreen() simplifiant la création d’un programme plein écran et offrant la possibilité d’explorer le multi-screen.
  • L’objet PVector supporte désormais la désignation chaînée
  • L’ajout de l’export SVG

Pour plus d’informations sur les changements de Processing 3.0 je vous invite à explorer la liste présente sur le GitHub du projet ou à regarder la vidéo de présentation de Daniel Shiffman.

L’environnement

En tant que Graphiste, l’interface de Processing peut paraitre un peu “aride” lors de son premier lancement. En effet nous sommes tous des habitués de Photoshop et ce qui se rapproche le plus du code pour nous reste Flash avec son interface proche du tableau de bord d’une formule 1. Et comme pour Photoshop ou la formule 1 il va nous falloir comprendre l’interface avant de se lancer dans la production.

L’interface de Processing peut se découper en trois zones :

  • La zone d’outils permettant d’exécuter ou stopper le programme et donnant accès au menu.
  • L’éditeur de texte où sera écrit le code.
  • La zone de console affichant les messages et les erreurs.

processing_interface_00

Trois autre fenêtres vont également nous être utile régulièrement à savoir :

  • La fenêtre Exemple regroupant les exemples fournis avec Processing ou importés avec les librairies
  • La fenêtre Sketchbook regroupant l’ensemble de nos créations et pouvant être paramétrée dans la fenêtre Préférences
  • La fenêtre Préférences regroupant l’ensemble des préférences du logiciel à savoir
    • L’emplacement du dossier sketchbook
    • La langue
    • Police utilisée dans l’éditeur et la console ainsi que leurs tailles respectives
    • La couleur d’arrière plan du mode présentation
    • Le lissage des polices
    • La saisie des caractères non latin
    • La détection des erreurs et affichage des avertissements
    • Utilisation de l’auto-complétion
    • Suggestion des imports
    • L’augmentation de la mémoire vive allouée (par défaut 256Mb)
    • Effacer le dossier précédent lors de l’export (évitant ainsi les nombreux fichiers issus de multiples exports)
    • Vérification des mises à jour au démarrage
    • Taille par défaut du fullscreen
    • Ouvrir tout les fichiers .pde avec processing

processing_interface_01

Dans la fenêtre préférences nous vérifierons que les éléments suivant sont actif :

  • Détecter les erreurs en continu
  • Afficher les avertissements
  • Autocomplétion du code ctrl+espace
  • Augmenter la mémoire vive disponible (augmenter la mémoire en fonction de la quantité de RAM dont vous disposez)

L’espace cartésien

Une fois l’interface appréhendée il est important de connaître la manière dont un programme gère son espace afin de pouvoir y dessiner. Si nous devions faire un rapprochement avec des logiciels que nous connaissons en graphisme cela serait les logiciels de la suite Adobe. Tout comme illustrator, par exemple, Processing possède un système de cordonnées cartésiennes qui nous permet de situer un point dans l’espace (x, y, z). Enfin, tout comme les logiciels que nous connaissons en design, l’origine de ce repère cartésien se trouvera en haut à gauche de notre fenêtre d’exécution.

processing_interface_02

Ainsi pour un programme d’une taille de 800 × 600 pixels, si je dessine un point rouge à la position 750 × 550, un point vert à la position 50 × 50 et un point bleu à la position 400 × 300; ces derniers seront respectivement en bas à droite, en haut à gauche et au centre du programme.

processing_interface_03

La structure du code

Tous programme se base sur un code écrit qui sera ensuite lu/exécuté ligne par ligne. Créer un programme est donc un acte d’écriture, il est donc important de connaître la manière dont le programme lit le code ainsi que la structure de celui-ci.

Les commentaires

Les commentaires sont des lignes de textes ignorées par le programme lors de son exécution. Ils sont à destination du ou des créateurs du programme et permettent de le commenter ou de laisser des notes souvent utiles afin de s’y retrouver. Ils sont notamment utiles lorsque l’on reprend un programme datant de quelques mois ou créé par un autre créateur et dont certaines fonctionnalités sont relativement complexes. Ils sont la syntaxe suivante :

Les déclarations

Les déclarations sont les lignes lues par le programme. Elles composent le programme et ses fonctionnalités. Elles peuvent être assimilées à une phrase dans le langage. Comme pour une phrase dans la langue française, il est important d’indiquer à une déclaration qu’elle se termine pour laisser place à une nouvelle déclaration. Si nous utilisons des points pour clôturer nos phrases, dans Processing — comme dans de nombreux autres langages — une déclaration devra se terminer par un point virgule ;. Cela s’explique par l’utilisation du point qui en mathématique permet d’indiquer la présence d’une décimale. Ainsi pour écrire la phrase suivant x est égale à un plus un cela se traduira par :

Les fonctions

Les fonctions — ou méthodes— sont des regroupements de déclarations. Elle permettent notamment d’exécuter une suite de déclarations et sont donc des raccourcis extrêmement pratique. Elles sont reconnaissable par leur forme utilisant un nom — en bas de casse généralement — suivi de parenthèses de la manière suivante :

Les parenthèses d’une fonctions permettent de passer à celle-ci différents paramètres qui seront utilisés par la suite de déclarations présente dans la fonction. Processing possède un grand nombre de fonctions. L’exemple suivant montre la fonction permettant de définir la taille d’un programme de 250 × 500 pixels :

§ Il existe également des fonctions dites de retour. Il s’agit de fonctions dont les déclarations contenues ont pour objectif de renvoyer un résultat sous la forme d’une variable ou d’un objet. Par défaut toute fonction est une fonction de retour, cependant les fonctions de donnant pas résultat mais effectuant une action sont des fonctions dite void, ou ne renvoyant aucun élément. Dans l’exemple suivant, la fonction calcul() permet d’obtenir le résultat du calcul suivant : 1+1. Elle renverra donc une variable et s’utilisera de la manière suivante :

§ Comme vu précédent il est également possible de passer à une fonction de retour des paramètres afin que ceux-ci soit utilisés dans la suite de déclarations contenue dans la fonction. Dans l’exemple suivant, la fonction calcul(int x, int y) permet d’obtenir le résultat du calcul suivant : x+y ou x et y sont des entiers.

§ La création d’une fonction se fait de la manière suivante :

§ Le type présent en début de phrase correspond au type de résultat renvoyé par la fonction. Il peut être de type :

  • void
  • boolean
  • int
  • float
  • char
  • String
  • color
  • Objet

§ Le type void est un type de fonction spécial ne renvoyant rien et effectuant uniquement la suite d’instructions. Sa création se passera donc de la déclaration return.

§ À la suite du type de la fonction se trouve le nom de celle-ci suivi de parenthèses permettant d’accueillir des paramètres si nécessaire. Le nombre de paramètres n’est pas limité, il est également possible de ne pas en mettre si la fonction n’en a pas l’utilité. Afin de marquer le début et la fin de la fonction, sa suite de déclarations devra être précédée par une  accolade ouverte { et suivi d’une accolade fermée }. Enfin, toute méthode renvoyant un résultat devra se terminer par la déclaration suivante return leResultat avant l’accolade fermée marquant la fin de la fonction. Ainsi la fonction permettant de calculer le résultat de x*y, où x et y sont des nombre décimaux, s’écrira de la manière suivante :

Utilisation de la casse

Lorsque nous écrivons une phrase nous utilisons des bas de casse, des capitales et des espaces. Cela nous permet d’identifier certains mots ou nom mais également de se repérer à l’intérieur de la phrase. Dans de nombreux langages de programmation nous retrouvons également l’utilisation de la capitale et de la bas de casse.

Ainsi dans Processing les noms de variables, leurs types et les fonctions utilisent des bas de casse. Nous aurons donc :

L’utilisation des capitales se fait dans la déclaration d’un objet (ou classe). Par exemple, lorsque je déclare un objet de type String, le type de l’objet prendra une capitale à sa première lettre, son nom de variable quant à lui restera en bas de casse. Nous noterons ici que l’objet String est un objet réunissant des variables de type char une chaîne de caractères étant composée de caractères.

La capitale peut également être utilisée dans les noms des variables ou fonctions afin d’indiquer un espace à la lecture du nom. Cela est notamment utile lorsque nous créons des variables aux noms très descriptif. En effet il sera plus facile de lire angleDeRotationSurAxeX que anglederotationsuraxex. Nous noterons cependant que la première lettre de la variable ou de la fonction restera en bas de casse, l’utilisation de la capitale pour la première lettre étant réservée à la déclaration d’un objet comme vu plus haut.

La structure d’un programme

Un programme se compose généralement de deux fonctions globales nécessaire à son fonctionnement. La première est la fonction permettant d’initialiser le programme. Il s’agit de la première fonction que lira le programme et qui ne sera exécutée qu’une seule fois. Celle-ci permet notamment de définir la taille du programme, son moteur de rendu — 2D ou 3D — ou de définir des variables.
La seconde fonction est la boucle. Il s’agit d’une fonction qui s’exécute en boucle, permettant ainsi de rafraichir l’affichage du programme et d’exécuter les opérations successivement.

Dans Processing la fonction permettant d’initialiser le programme est la fonction setup(). La fonction permettant d’exécuter le programme en boucle est la fonction draw(). Par défaut, cette dernière s’exécute 60 fois par seconde. Ainsi si je souhaite réaliser un programme affichant le nombre de frames écoulées et de taille 250 × 250 j’écrirai :

La grammaire du code

Les variables

La variable est un concept de base de la programmation, il s’agit d’un mot-clef associé à une valeur. Les variables permettent ainsi de nommer des valeurs. Nous utilisons également des variables dans la vie de tout les jours, par exemple chaque personne possède un nom et prénom qui permet de l’identifier. Il en est de même en programmation où nous pouvons nommer la coordonnée x d’une ellipse ellipseCoordX. Il sera alors plus facile d’appeler cette variable par son nom.

Processing possède plusieurs type de variables permettant ainsi de reconnaitre rapidement s’il s’agit d’un nombre entier, d’un nombre décimal ou d’un caractère. Nous pouvons compter parmi ces variables :

  • boolean etat = true; Variable de type boolean (ou binaire), il s’agit d’une variable ne pouvant renvoyer que deux valeurs : Vrai/Faux. Elle permet de faire des comparaisons. Par exemple la réponse à la question “Cette robe est-elle rouge?” est une booléenne car elle ne peut être que vrai ou faux : “Oui elle est rouge” “non elle ne l’est pas”
  • int x = 10; est une variable de type nombre entier (0, 1, 2,  3…)
  • float x = 3.141592; est une variable de type nombre décimal (0.001, 0.002, 0.003…)
  • String nom = “moi”; est un objet renvoyant une chaine de caractères, elle permet de stocker des mots. Il ne s’agit pas à proprement parler d’une variable cependant nous la considérerons comme telle.
  • char nom = “a”; est une variable de type caractère
  • color couleur = color(255, 255, 255); est une variable de type couleur

Les opérateurs (opérations, assignations, relationnels et logiques)

La seconde notion importante en programmation est la notion d’opérateurs. Ils permettent d’effectuer divers calculs ou comparaisons. Nous sommes ici dans des notions de bases des mathématiques. Nous avons différents types d’opérateurs.

Les opérateurs arithmétiques  :

  • +, , *, / qui permettent d’addition, soustraire, multiplier ou diviser des valeurs.
  • % le modulo qui permet de connaitre la valeur d’un reste d’une division (valeur résiduelle) par exemple 17%3 = 2 car 2 est le reste de la division de 17/3

Les opérateurs d’assignation :

  • = permet d’attribuer une valeur à une variable
  • +=, -=, *=, /= permettent d’incrémenter, soustraire, multiplier ou diviser des valeurs par exemple x = x+1 est la même chose que x +=1;

Les opérateurs relationnels (s’utilisant dans le cadre des structures itératives et conditionnelles)

  • >, <, <=, =>, == , != permettent de comparer deux valeurs afin de savoir si celles-ci sont supérieur, inférieur, supérieur ou égale, inférieur ou égale, égale ou différentes. Ces opérateurs ne renvoient que des valeurs booléennes, c’est à dire vrai ou faux. Par exemple 1 == 2 renverra la valeur “false” car 1 n’est pas égale à 2;

Les opérateurs logiques (s’utilisant dans le cadre des structures itératives et conditionnelles)

  • &&, || permettent d’effectuer des opérations booléennes de type ET et OU.

Des variables spécifiques à Processing

Processing possède également différentes variables pré-écrites permettant d’accéder à différentes valeurs numérales ou booléennes tel que :

  • width; Variable renvoyant la largeur du programme déclarée dans la fonction size() lors de l’initialisation du programme.
  • height; Variable renvoyant la hauteur du programme déclarée dans la fonction size() lors de l’initialisation du programme.
  • mouseX; Variable renvoyant la position actuelle sur l’axe X de la souris.
  • mouseY; Variable renvoyant la position actuelle sur l’axe Y de la souris.
  • pmouseX; Variable renvoyant la position précédente — à la frame précédente — sur l’axe X de la souris.
  • pmouseY; Variable renvoyant la position précédente — à la frame précédente — sur l’axe Y de la souris.
  • mousePressed; Variable de type booléenne indiquant si la souris est cliquée (true) ou non cliquée (false).
  • mouseReleased; Variable de type booléenne indiquant si le clique de la souris a été relâché (true) ou non (false).
  • keyPressed; Variable de type booléenne indiquant si une touche du clavier est appuyée (true) ou non (false).
  • keyReleased; Variable de type booléenne indiquant si une touche du clavier appuyée a été relâché (true) ou non (false).
  • frameCount; Variable renvoyant le nombre de frames écoulées.
  • frameRate; Variable renvoyant le nombre de frames par seconde à laquelles s’exécute le programme.

Des méthodes spécifiques à Processing (création, dessin, définition des couleur…)

Nous l’avons vu précédemment, Processing est un langage simplifié de JAVA permettant notamment d’accéder à de nombreuses fonctions de dessins pré-écrites plus rapidement. C’est cette approche qui en fait un langage d’apprentissage et de prototypage idéal pour les artistes, créateurs et graphistes. Parmi ces fonctions nous pouvons compter :

Les fonctions de création, celles-ci sont appelées dans la fonction setup() lors de l’initialisation du programme :

  • size(int largeur, int hauteur); Fonction permettant de définir la largeur et hauteur du programme.
  • size(int largeur, int hauteur, moteur); Fonction permettant de définir la largeur, hauteur et moteur de rendu du programme (P2D, P3D, PDF, FX2D).
  • smooth(int niveau); Fonction permettant de définir le niveau antialiasing. Par défaut l’antialiasing est activé. Le niveau de l’antialiasing peut être 2, 3, 4 ou 8 en fonction du moteur de rendu.
  • fullScreen(); Fonction permettant de définir la taille du programme en fullscreen.
  • fullScreen(int ecran); Fonction permettant de définir la taille du programme en fullscreen et de choisir l’écran sur lequel l’exécuter lorsqu’on possède plusieurs écrans (1, 2, 3 ou plus en fonction de son nombre d’écran). Nous noterons que l’utilisation de SPAN à la place du numéro de l’écran permet d’exécuter le programme réparti sur l’ensemble des écrans disponibles.
  • fullScreen(moteur); Fonction permettant de définir la taille du programme en fullscreen et de choisir le moteur de rendu (P2D, P3D, PDF, FX2D).
  • fullScreen(int ecran, moteur); Fonction permettant de définir la taille du programme en fullscreen, de définir son moteur de rendu (P2D, P3D, PDF, FX2D) et de choisir l’écran sur lequel l’exécuter lorsqu’on possède plusieurs écrans (1, 2, 3 ou plus en fonction de son nombre d’écran). Nous noterons que l’utilisation de SPAN à la place du numéro de l’écran permet d’exécuter le programme réparti sur l’ensemble des écrans disponibles.

Les fonctions de dessin permettant de dessiner des formes géométriques prédéfinies en 2D ou 3D :

  • point(float x, float y); Fonction permettant de dessiner un point dans un espace 2D.
  • point(float x, float y, float z); Fonction permettant de dessiner un point dans un espace 3D.
  • line(float x1, float y1, float x2, float y2); Fonction permettant de dessiner une ligne dans un espace 2D.
  • line(float x1, float y1, float z1, float x2, float y2, float y3); Fonction permettant de dessiner une ligne dans un espace 3D.
  • triange(float x1, float y1, float x2, float y2, float x3, float y3); Fonction permettant de dessiner un triangle dans un espace 2D.
  • quad(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4); Fonction permettant de dessiner un quadrilatère dans un espace 2D.
  • rect(float x, float y, float largeur, float hauteur); Fonction permettant de dessiner un rectangle dans un espace 2D.
  • ellipse(float x1, float y1, float largeur, float hauteur); Fonction permettant de dessiner une ellipse dans un espace 2D.
  • box(float taille); Fonction permettant de dessiner un cube dans un espace 3D.
  • box(float largeur, float hauteur, float profondeur); Fonction permettant de dessiner un parallélépipède dans un espace 3D.
  • sphere(float rayon); Fonction permettant de dessiner une sphère dans un espace 3D.
  • text(char caractere, float x, float y); Fonction permettant de dessiner un caractère dans un espace 2D.
  • text(char caractere, float x, float y, float z); Fonction permettant de dessiner un caractère dans un espace 3D.
  • text(String mot, float x, float y); Fonction permettant de dessiner une chaîne de caractères dans un espace 2D.
  • text(String mot, float x, float y, flaot z); Fonction permettant de dessiner une chaîne de caractères dans un espace 3D.

Les fonctions de remplissage permettant de définir la couleur de remplissage et de contour.

  • colorMode(mode, int max1, int max2, int max3); Fonction permettant de définir le mode colorimétrique utilisé. Le mode peut être RVB (rouge, verte bleu) ou HSB (teinte, saturation, luminosité). Par défaut Processing est en mode RVB .
    Les valeurs max correspondent aux valeurs maximum des trois composants. Lorsque nous travaillons en teinte, saturation et luminosité nous travaillons la teinte de 0 à 360°, la saturation et luminosité sont quant à elles travaillées de 0 à 100%. Nous écrirons alors :

    Dans le cas du mode colorimétrique RVB  nous savons que nos valeurs rouges, vertes et bleues seront comprises entre 0 et 255, nous écrirons alors :

    Il est également possible de définir la manière dont nous souhaitons traiter l’opacité; de 0 à 100% ou de 0 à 255. Pour cela nous rajouterons un quatrième paramètre au mode colorimétrique afin de définir la façon dont l’opacité sera traitée :

     
  • background(float rouge, float vert, float bleu); Fonction permettant de définir la couleur de fond du programme en RVB (ou HSB). On notera que les valeurs RVB sont comprises entre 0 et 255.
    Il est important de noter que sans couleur de fond, le programme dessinera en sur-impression, c’est à dire que les dessins effectués aux frames précédentes seront toujours visible en dessous du nouveau dessin. Cela reviendrait, dans Photoshop, à dessiner sur plusieurs claques superposés. La fonction background() a donc pour rôle «d’effacer» les dessins effectués aux frames précédentes.

    ixd_processingIntro_00
    Lorsque je dessine, à chaque frame, un cercle à la position de ma souris sans utiliser la fonction background() je remarque que les dessins se superposent au fil du temps.

    ixd_processingIntro_01
    Si pour ce même code j’utilise la fonction background(), alors je dessinerai un fond entre chaque frame. Les dessins des frames précédentes seront effacés et je verrai alors mon cercle se déplacer.
  • fill(float rouge, float vert, float bleu); Fonction permettant de définir la couleur de remplissage d’une forme en RVB (ou HSB). On notera que les valeurs RVB sont comprises entre 0 et 255.
  • fill(float rouge, float vert, float bleu, float opacité); Fonction permettant de définir la couleur de remplissage d’une forme en RVB (ou HSB) + Alpha. On notera que les valeurs RVB et Alpha sont comprises entre 0 et 255.
  • stroke(float rouge, float vert, float bleu); Fonction permettant de définir la couleur de contour d’une forme en RVB (ou HSB). On notera que les valeurs RVB sont comprises entre 0 et 255.
  • stroke(float rouge, float vert, float bleu, float opacité); Fonction permettant de définir la couleur de contour d’une forme en RVB (ou HSB) + Alpha. On notera que les valeurs RVB et Alpha sont comprises entre 0 et 255.
  • strokeWeight(float epaisseur); Fonction permettant de définir l’épaisseur d’un contour.

Pour rappel, nous savons que notre programme s’exécute de la première à la dernière ligne, de haut en bas. Ainsi je devrai définir la couleur d’une forme avant que celle-ci soit dessiné de la manière suivante :

Il existe évidement de nombreuses autres fonctions de dessin permettant de dessiner des courbes de Bézier, des courbes de Catmull-Rom ou encore des réaliser ses formes personnalisées. Je vous invite à les découvrir parmi les références présentes sur le site processing.org.

Les moteurs de rendu

Comme de nombreux autres langages de programmation, Processing possède différents moteurs de rendu. Un moteur de rendu permet de définir la manière dont le programme dessinera. Il peut être en 2D ou 3D. Comme vu plus haut, le moteur de rendu se défini dans la fonction size() . Dans Processing nous avons différent moteurs de rendu tel que :

  • JAVA2D : moteur de rendu 2D JAVA. Il s’agit du moteur de base de Processing.
  • P2D : moteur de rendu 2D utilisant OpenGL.
  • P3D : moteur de rendu 3D utilisant OpenGL.
  • PDF : moteur de rendu PDF.
  • FX2D : moteur de rendu 2D JAVA accéléré.

Aides

Autocomplétion

L’autocomplétion est la capacité pour un élément donné de se compléter de manière automatique. Il s’agit d’une des nouveautés de Processing 3.0. Une fois activée — via la fenêtre Préférences — elle permet à Processing de vous proposer la suite des éléments (ou paramètres) à écrire dans une fonction. Cela est très utile lorsqu’on ne se rappel plus des paramètres à passer dans une fonction. Pour l’utiliser, il nous suffit d’utiliser la commande CTRL+ESPACE lorsque nous écrivons notre fonction.

Ici, via la commande CTRL+ESPACE, Processing me rappel les paramètres possibles que peut prendre la fonction line().
Via la commande CTRL+ESPACE, Processing me rappel les paramètres possibles que peut prendre la fonction line().

Détection et correction des erreurs

La détection des erreurs en programmation est un élément extrêmement important. Qui n’a jamais été frustré par ce code de 4000 lignes qui refuse de compiler suite à un oublie de point virgule ou à une parenthèse manquante parmi ces lignes. La version 3.0 de Processing propose désormais des outils simple permettant de détecter ces erreurs mais également de nous indiquer où elles se trouvent.

Le premier outils pratique est la détection en continu des erreurs. Un fois activé dans la fenêtre Paramètres, il nous permet de détecter des erreurs durant l’écriture et de les indiquer dans la zone de message. Ainsi lorsque j’écris : background(255) la zone de message m’indiquera le message suivant : «Missing a semicolon « ; »» ou «Point virgule manquant». Par ailleurs la ligne où se trouve mon erreur sera indiquée à droite par un trait rouge et l’erreur en elle même sera souligné en rouge dans le code. Je pourrai alors aisément corriger mon erreur.

continousErrors

La zone de message n’indiquant que la dernière erreur je peux également accéder à la liste complète des erreurs via l’onglet Erreurs situé en dessus de la console. Dans cet onglet je découvre alors la liste complète des erreurs détectées ainsi que leurs lignes et les onglets dans lesquelles elles se trouvent. Je peux par un simple clique sur une ligne de l’onglet d’erreur, surligner la ligne comportant l’erreur en question et ainsi la corriger.

consoleError

§ L’onglet Erreurs me permet également de mettre en évidence des avertissements si cette option a été activé via la fenêtre de Préférences. Un avertissement n’est pas une erreur, il n’empêchera pas le code de compiler. Il s’agit d’avertissement concernant l’optimisation du code, notamment lorsqu’on déclare des variables qui ne sont pas utilisées dans la suite du code. En effet chaque variable déclarée prend une certaine place dans la mémoire allouée au programme, il est donc recommandé de ne pas déclarer des variables qui ne seront pas utilisée.

Les avertissement apparaissent dans l’onglet Erreurs sous la forme de pastilles oranges. Au clique sur la ligne le message d’avertissement apparait indiquant ainsi de quel type d’avertissement il s’agit.

warning

Pour aller plus loin

Si vous souhaitez approfondir la découverte de Processing et de ses nouveautés je vous invite à consulter les références suivante :

{des} histoire(s) du design interactif

Le premier cours de l’année est l’occasion pour les étudiants de 3e. année design interactif de découvrir l’histoire du design interactif. Il est difficile de retracer une histoire exhaustive du design interactive tant elle est marquée par de nombreuses personnes et de nombreux évènements. Ce cours, mise à jours chaque année, tente de retracer une histoire du design interactif à travers différent scope.

Cours 2015-2016

Ce cours tente de retracer une histoire du design interactif à travers l’informatique et la communication visuelle.
Une première vision de l’histoire du design interactif est lié à l’histoire de l’informatique. Dans cette première partie sont abordées les grandes évolutions de ce domaine de 1642 à nos jours
Enfin une troisième partie est consacrée au design graphique et la communication visuelle et à l’impact du numérique dans ses différents domaines.

Le document ci-joint, support de cours, présente différentes frises chronologiques non-exhaustif.
Design interactif – {une} histoire du design interactif
Cours rédigé par Alexandre Rivaux

Complément : Le document ci-après reprend l’introduction au cours faite en début année et décrit la méthodologie de travail ainsi que la grille de notation abordée en 2015-2016
Design interactif : introduction

Cours 2014-2015

Ce cours tente de retracer une histoire du design interactif à travers l’informatique, la programmation et de design graphique.
Une première vision de l’histoire du design interactif est lié à l’histoire de l’informatique. Dans cette première partie sont abordées les grandes évolutions de ce domaine de 1940 à nos jours
La seconde partie est dédiée à l’histoire de la programmation depuis les cartes perforées aux langages que nous connaissons aujourd’hui (C/C++, Java…)
Enfin une troisième partie est consacrée au design graphique et à l’impact du numérique dans ses différents domaines.

Le document ci-joint, support de cours, présente différentes frises chronologiques non-exhaustif.
Design interactif – {une} histoire du design interactif
Cours rédigé par Alexandre Rivaux

Installations interactives : pensez à tous les utilisateurs

Les installations interactives sont de plus en plus courantes dans le monde de la communication. Déjà présentes depuis de nombreuses années dans le domaine de l’art numérique avec des artistes comme Jeffrey Shaw ou Myron Krueger — pour n’en citer que deux — elles font depuis quelques années leur apparition dans le monde la communication, désireux, généralement, de sortir de l’écran et d’engager un dialogue physique avec le public. Il est donc normal que cet engouement arrive jusqu’aux domaines de l’enseignement et que de nombreux étudiants ou jeunes diplômés s’essaient à la pratique.

Les installations interactives, comme toutes productions, présentent certaines contraintes qu’il est important de prendre en compte lors de la conception. Ces contraintes relevant souvent de la mise en place technique et de l’exploitation de l’installation, elles ne sont généralement que peu abordées lors des cours, où leurs cas d’usage sont difficiles à mettre en place. Nous allons nous y intéresser à travers 3 types d’utilisateurs qui auront à interagir d’une manière ou d’une autre avec l’installation : l’utilisateur, l’hôte(sse) et le régisseur.

L’utilisateur

L’utilisateur est bien connu du designer puisqu’il est celui pour qui l’installation a été conçue, il est au centre même de la conception. Dans le cadre d’une installation interactive (de marque) il est important prendre en compte le fait que l’utilisateur ne s’est pas spécifiquement déplacé pour découvrir l’installation. À la différence d’un site ou d’une exposition par exemple où il s’est rendu (en règle générale) volontairement, l’utilisateur d’une installation de marque est très souvent présent face à l’installation pour des motivations bien différentes que celles de vivre une expérience, il s’y retrouve en quelque sorte confronté. Dans le cas où le lieu se trouve être un centre commercial ou un magasin, l’utilisateur s’y est probablement rendu pour effectuer un achat — ou simplement pour effectuer un trajet habituel maison-bureau dans le cas d’une vitrine interactive. Le guidage est donc important. Il est nécessaire d’inciter l’utilisateur à prendre part à l’expérience, souvent par le biais d’un «call to action». L’incitation doit être simple et compréhensible de tous dans le mesure où les utilisateurs peuvent être extrêmement variés (âge, langue, temps disponible…).

Installation interactive sonore pour Côte d'Or chocolat à l'occasion de l'évènement le Quartier du Chocolat.
Installation interactive sonore pour Côte d’Or chocolat à l’occasion de l’évènement le Quartier du Chocolat. Agence : Fullsix – Production : Elegangz – Design, sound design & developpement : Bonjour, interactive lab

Une fois que l’utilisateur a été incité à prendre part à l’expérience, il lui faut comprendre l’interaction. L’ergonomie de l’installation a une grande importance. L’utilisateur doit être en mesure de distinguer les éléments d’interfaces des éléments graphiques, il doit également être en mesure de comprendre le ou les interactions qu’il sera amené à avoir, leurs raisons et leurs buts. Une fois encore, notre ergonomie doit prendre en compte le fait que les utilisateurs peuvent être tous différents et ne possèdent pas nécessairement la même culture. Il n’est pas rare en effet de voir une installation interactive extrêmement bien maitrisé par un enfant, alors que ses parents seront en difficulté pour interagir avec et vice versa. Il est donc nécessaire de se rappeler le contexte de l’installation. Souvent l’utilisateur n’alloue que très peu de temps à la compréhension de l’interaction car, rappelons le, il se trouve dans un contexte différent (achats à effectuer, retour chez lui, balade en famille…). Dès lors que l’installation nécessite un outil ou un mode d’interaction relativement nouveau, il devient alors plus compliqué d’en expliquer le fonctionnement.

La phase d’expérience est également une phase importante. Si l’utilisateur le souhaite il doit pouvoir rapidement accéder à une information (que faire à ce point précis de l’installation? comment interagir?) ou être capable de la quitter si celle-ci ne lui convient pas. Dans le cadre d’une installation utilisant une Kinect cela peut être relativement simple. Une interface pourra présenter les canaux d’interactions et l’utilisateur pourra à tout moment quitter l’expérience. Mais cela devient plus ardu lors d’une expérience de réalité virtuelle où l’utilisateur, en plus de voir à 360°, se retrouve avec un casque câblé à un ordinateur. La solution la plus évidente est alors la prise en main de l’utilisateur par un(e) hôte(sse). L’hôte(sse) est une personne en charge de l’installation et ses utilisateurs. Elle pourra alors les guider durant l’expérience, mais également les aider dans leur compréhension de l’interaction ou les inciter à participer.

L’hôte(sse)

L’hôte(sse) est un utilisateur à considérer lors de la phase de conception d’une installation interactive. Il aura pour rôle de représenter la marque et d’animer le lieu de point de contact. Sa mission est autant d’inciter l’utilisateur à participer à l’expérience que de le guider durant celle-ci, mais également de lui faire découvrir la marque et ses produits. Il aura donc un rôle clé durant l’ensemble de l’exploitation et il est important qu’il puisse maitriser l’ensemble des outils mis à sa disposition. Parce qu’il est le point de contact avec les utilisateurs, il est nécessaire de considérer son parcours. Il sera souvent en charge de l’installation de l’utilisateur au sein du dispositif, du lancement de l’expérience ou encore de la récupération des données CRM ou d’envoi d’e-mailling.

Dans le cadre d’une installation nécessitant son lancement par l’hôte(sse) il est nécessaire de penser également l’ergonomie de son interface à destination de cet utilisateur. L’installation doit pouvoir être lancée facilement car l’hôte(sse) doit être en mesure d’interagir avec les personnes présentes sur le lieu. Il devient compliqué de lancer une expérience dès lors que l’hôte(sse) doit aller en régie pour accéder à l’interface ou qu’il(elle) doit suivre sa souris affichée sur un écran géant à 10 mètres de distances. Un écran déporté — avec clavier et souris — à disposition de l’hôte(sse) est souvent la meilleure solution. Si la marque souhaite un stand épuré ne présentant aucun écran, clavier ou souris, d’autres dispositifs peuvent être mise en place.

Par exemple, les expériences Peugeot Connect et Astral Skeleton ne présentaient aucun écran, clavier ou souris, leurs espaces d’expérience ne prévoyant aucun point de contrôle. De plus les expériences étant des expériences de réalité virtuelle vécues à travers un casque Oculus Rift, l’hôte(sse) n’avait aucun repère quant à la position temporelle de l’utilisateur dans l’expérience. Il est alors difficile de savoir si l’expérience a débuté ou si celle-ci est terminée. La solution envisagée fut la mise en place d’un unique bouton rétroéclairé permettant de contrôler l’installation et placé sur la stèle. Lorsque l’hôte(sse) souhaite démarrer l’expérience — une fois l’utilisateur installé — il(elle) appuie sur le bouton. L’expérience démarre et l’éclairage du bouton s’allume indiquant ainsi à l’hôte(sse) que celle-ci est en cours. Une fois l’expérience finie, le rétro-éclairage du bouton s’éteint afin de lui indiquer que l’utilisateur à terminé l’expérience et que le casque peut lui être enlevé. Si un utilisateur souhaite quitter l’expérience, l’hôte(sse) pourra à tout moment la terminer par une simple pression sur le bouton, le rétro-éclairage s’éteignant pour indiquer que l’expérience s’est arrêtée.

peugeot
Le stand Peugeot Expérience présent lors du mondial de l’automobile 2014 était composé de bornes épurées, sans écran de contrôle pour les hôtesses. Par ailleurs chaque hôtesse avait pour mission de prendre l’utilisateur en photo afin de partager l’expérience sur les réseaux sociaux et récolter de l’information emailing pour tout utilisateur intéressé. Un système de bouton pression permettant de contrôler et monitorer l’expérience a donc été mise en place. Peugeot Expérience, salon de l’automobile 2014. Agence : Havas Event – Design, sound design et développement : Bonjour, interactive lab

L’ergonomie en dehors de l’application est également à prendre en compte dans la mesure où l’hôte(sse) pourra également avoir à charge de démarrer et arrêter le dispositif matin et soir. Cette procédure doit donc être aussi simple que possible. Il est envisageable de pré-programmer le démarrage et l’arrêt de l’ordinateur à des heures fixes. Dans le cas où ces derniers nécessitent une action de l’hôte(sse), il est également possible de paramétrer le lancement de l’application au démarrage de l’ordinateur, facilitant ainsi le processus de démarrage du dispositif. Si l’automatisation du dispositif est importante, il arrive toutefois que le lancement du programme soit à la charge de l’hôte(sse) ou qu’il soit obligé de le relancer. Auquel cas le bureau de l’ordinateur devra être suffisamment organisé pour permettre à l’hôte(sse) d’accéder à l’application ou au contact du régisseur rapidement.

Le régisseur

Le troisième utilisateur à considérer est le régisseur. Il s’agit de l’utilisateur le plus avancé de votre expérience étant donné qu’il est en charge de son bon fonctionnement tant logiciel que technique. Il a pour mission de veiller et intervenir si nécessaire sur votre installation dans le cas où celle-ci subirait un dysfonctionnement (ordinateur ne démarrant pas, problème d’affichage… ). Tout comme l’hôte(sse), il a accès non pas au logiciel uniquement mais à l’ensemble de l’ordinateur. Il est donc important que celui-ci soit suffisamment organisé — tant en terme de placement de fichiers que de noms — et qu’il ne regorge pas de nombreuses barrières que pourraient être différents mots de passe.
Dans l’idéal, le régisseur doit avoir accès via le bureau, à un dossier réunissant l’ensemble des éléments nécessaires à la correction d’un problème informatique — tel que les drivers d’origine — ainsi qu’à la fiche contact de l’équipe de développement indiquant mails, numéros de téléphones et heures d’appels.

Dans le cas où le régisseur ferait face à un problème matériel, il devra être en mesure de le remplacer. Il est d’usage d’avoir en régie du matériel en double tels que les capteurs utilisés par exemple. Chaque installation étant spécifique, ce dernier devra également disposer d’un plan de montage de vos capteurs lui indiquant comment démonter le capteur usagé mais également comment monter le capteur, le sécuriser et le connecter à l’ordinateur. Il est donc important d’envisager tous les cas de figures lors de la rédaction du document à destination de la régie, de même que lors du design de la scénographie il est nécessaire de rendre accessible l’ensemble des composants de l’installation.

Si l’utilisateur principale est le premier auquel le designer pense durant la conception et réalisation de son installation, il est donc important de ne pas négliger l’hôte(sse) et le régisseur qui auront autant, voir sans doute plus, d’interactions avec votre dispositif tout au long de son exploitation.

Liste des cours Processing 2012-2015 [Digital Lab]

Retrouvez la liste complètes des cours et sujets travaillés en cours de digital lab — processing (3e. année, option)

Cours et sujets 2014-2015

  1. Design génératif et expériences interactives — introduction
  2. Processing 2.0 — langages, grammaire et variables
  3. Grilles et répétitions de motif — itérations et conditions
  4. Aléatoire Brownien et Perlin
  5. Tableaux — introduction aux classes
  6. Programmation orientée objet : les classes
  7. Sujet semestre 1 : Carte de voeux 2015
  8. Analyse audio et réactivité au son
  9. World of sound : Plongez au coeur d’un environnement reactif au son.

Cours et sujets 2013-2014

  1. Design génératif et expériences interactives — introduction
  2. Processing 2.0 — langages, grammaire et variables
  3. Grilles et répétitions de motif — itérations et conditions
  4. Aléatoire Brownien et Perlin
  5. Tableaux — introduction aux classes
  6. Programmation orientée objet : les classes
  7. Temps : frames, horaires et décomptes
  8. Rappel sur les classes et le processus itératif
  9. Sujet : clip interactif (en fin de document)
  10. Analyse audio et réactivité au son
  11. Transformation 2D
  12. Espace 3D et formes primitives
  13. Expérimentation typographique
  14. Sujet : expérimentation typographique

Cours et sujets 2012-2013

  1. Design génératif et expériences interactives — introduction
  2. Processing 2.0 — langages, grammaire et variables
  3. Grilles et répétitions de motif — itérations et conditions
  4. Aléatoire Brownien et Perlin
  5. Tableaux — introduction aux classes
  6. Programmation orientée objet : les classes
  7. Analyse audio et réactivité au son
  8. Temps : frames, horaires et décomptes
  9. Sujet : Lightpainting procedural
  10. Sujet : Installation interactive

Conférences eyeo 2015

Chaque année depuis sa création en 2011 eyeo festival marque les esprits avec ses conférences. Le festival, basé à Minneapolis, réuni artistes, designers et coders afin d’échanger et partager leurs visions sur les domaines de l’art, de l’interactivité et de l’information.

Voici une sélection de quelques conférences qui ont eu lieu cette année. Vous pourrez également retrouver l’ensemble des conférences sur la page vimeo du festival.

Zach Lieberman — From point A to B.
L’artiste Zach Lieberman s’intéresse ici à l’intersection entre code et dessin, aux différentes manières de dessiner une ligne par le code. Un sujet qui est très présent dans son travail.

Ben Fry — Audience & Context
Ben Fry présente le travail effectué par son studio Fathom sur la datavisualisation et l’importance de considérer le contexte de lecture dans l’information fournie. Il présente également les évolutions prévues pour processing 3.0

Casey Reas — Stochastic cofabulation
L’artiste Casey Reas présente le travail effectué par la fondation processing tant dans le domaine de la création d’outils à destination d’artistes et studios (processing.org, processing.js, processing.py…) que dans le domaine de l’enseignement en art visuel.Il évoque également son travail artistique effectué sur le sujet des médias de masses.

James George — Imaging the futur
L’artiste James George parle de son intérêt pour l’image et la photographie. Il s’intéresse notamment aux nouvelles formes de camera et leurs images. Il présente son travail effectué sur le documentaire interactif Clouds avec Jonathan Minard. Documentaire d’où provient l’image de cet article, extrait de l’interview de Zach Lieberman.

Nicky Case — Systems, Stories & Shenanigans
Le game designer Nicky Case explore la notion de système dans le cadre d’une narration interactive à destination du jeu vidéo et social.

Jesse Louis-Rosenburg et Jessica Rosenkrantz — Events in space time
Les deux designers de Nervous System présentent leurs travaux sur  la simulation de croissance naturelle et leurs applications.

Reza Ali — Let’s get physical
L’artiste Reza Ali présente son intérêt pour la simulation physique et le code dans le cadre de sa résidence effectuée chez Autodesk.

Pour finir je partage également trois autres conférence présentées lors de précédente éditions (2011, 2012 et 2014).

Marius Watz — Computatinal Aesthetics (2011)
L’artiste Marius Watz explore ici le notion d’esthétique du design computationnel et ses nombreux clichés.

Marius Watz — Algorithm critique and computational Aesthetics (2012)
Prolongement de sa conférence de 2011, Marius Watz parle de la notion de critique d’algorithme et l’exploration de nouvelles formes d’esthétique dans le domaine du design computationnel.

Robert Hodgin — Default Title double-click to edit (2014)
L’artiste Robert Hodgin présente son travail et son intérêt pour la simulation de comportement naturel. Il parle également de la notion d’échec et d’erreur dans le domaine du design par le code et la manière de s’en servir pour explorer de nouveaux domaines.

Ergonomie et responsive design

Le design web est en constante évolution et nous voyons chaque année de nouvelles tendances UI ou UX emmerger. Une tendance web de plus en plus présente est l’utilisation du burger menu — appelé ainsi pour la ressemblance de son pictogramme — sur des sites à destination du desktop. Or il arrive que son utilisation ne soit pas toujours pertinente, il est donc intéressant de s’interroger sur celle-ci.

Qu’est ce que le burger menu

Le «burger» menu est une méthode consistant à regrouper la navigation d’un site ou d’une application dans une sous-partie symbolisée par une icône rappelant le principe de couche d’un burger ou d’un sandwich.

icoBurger

D’un point de vue du design ce pictogramme symbolise la notion de liste d’éléments et a notamment été démocratisé avec l’avènement du design mobile. Son objectif est avant tout d’obtenir un gain de place sur les pages ne pouvant afficher les menus comportant de nombreux éléments. En effet le design mobile étant plus restreint en terme de taille — pour rappel la résolution mobile la plus rependue reste 360×640 et est présente sur 19.91% des terminaux mobiles — il est parfois impossible d’afficher sur une même page des menus aux nombreux éléments.

Si sa création relève d’une véritable problématique il est tout de même important de s’intéresser à l’ergonomie résultante de son utilisation. Le langage de l’homme étant basé sur les signes typographique, les mots et les phrases, on est à même de se demander si ce pictogramme est compréhensible aux non initiés au premier abord.

La question que nous poserons ici est celle de l’ergonomie en fonction des supports. Aujourd’hui les terminaux mobiles représentent une grande partie de la navigation web et les sites sont donc tous soumis à des contraintes de responsive. Il n’est donc pas rare de voir des sites desktop (à destination d’ordinateur) arborer un menu «burger» comme pour leurs versions mobiles. Mais son utilisation dans ce cas précis est-elle pertinente?

Ergonomie et Burger sont-ils compatible?

«À tribord toute mon capitaine»

Le «burger» ne date pas d’hier même si le design web mobile est relativement jeune. Alors pourquoi ce questionnement sur ce menu?

Ce questionnement m’est venu après avoir visité plusieurs sites présentant une navigation en haut à droite de la page. Pour chacun de ces sites il me fallu plusieurs secondes avant de découvrir que le menu était caché sous le «burger». Pourquoi m’a-t-il fallu autant de temps pour trouver une navigation pourtant si évidente sur la page? Simplement parce que mes habitudes utilisateur me font réserver la position haute droite de la page pour la navigation de type «action» tel que les menus de loggin, d’enregistrement, de panier ou encore de langues. Il me semblait donc que ce burger réservait dans son sous-menu cette navigation «action» et non de contenu. Je n’allais donc pas y chercher ma navigation.

fi

Je me suis permis de poser cette question d’ergonomie à propos ce menu sur facebook. Julien Vieira, designer et enseignant me fit remarquer que ce choix de position pouvait sans doute trouver son origine du fait que l’interface était pensée pour le tactile en prenant en considération les droitiers. Nous ne serions donc plus dans un site responsive mais tactile à destination des droitier. Nous sommes loin de l’accessibilité.

Nous avons donc une hypothèse concernant le positionnement du menu mais nous ignorons toujours pourquoi utiliser ce menu sur desktop.

«Ergonomiquement cela fonctionne»

Ugo le Prudhomme, à la fois developpeur et UX designer chez Soap Creative, souleva le point intéressant de l’ergonomie en abordant les avantages de ce menu à destination du mobile tel que :

  1. Sa facilité de déploiement (technique)
  2. Son identification simple par l’utilisateur
  3. La non nécessite de traduction
  4. L’accès en un clic à un contenu

Si selon lui, si ce menu n’a pas sa place sur desktop, il reste tout de même une solution fonctionnelle est envisageable dans certains cas. Cependant cela ne doit pas devenir automatique comme il le précise. Je suis cependant en désaccord avec certains points évoqué tel que :

  1. La non nécessite de traduction :
    En effet le pictogramme ne fait que placer dans une sous-partie un menu textuel. Menu qu’il faudra traduire dans la langue de l’utilisateur dans tout les cas.
  2. L’accès au contenu en un clic :
    Là encore je suis en désaccord dans le sens où il faudra un clic pour ouvrir le menu puis un second pour accéder au contenu voulu. Nous sommes donc loin de l’accès rapide.

Il est évident que dans le cas d’une navigation comportant un grand nombre d’éléments ne pouvant s’afficher sur un seul écran ce menu est intéressant mais qu’en est-il dans le cas d’un site desktop ayant la place d’afficher l’ensemble de son menu? Est-ce utile de multiplier les clics avec un tel menu quand la page du site peut aisément afficher l’ensemble du menu? Par ailleurs, l’utilisation du burger menu cache le contenu à l’utilisateur qui ignore donc le type de contenu auquel il pourra accéder. Cela peut donc être un risque de perdre l’utilisateur.

Si nous avons la possibilité d’afficher l’ensemble du menu sur notre page, pourquoi utiliser une navigation venant du mobile?

«Le framework est fait de cette façon… et tout le monde le fait»

Maxime Bodereau, spécialisé en UX et UI, design souleva le dernier point, sans doute le plus intéressant :

Je pense que c’est une question de fainéantise aussi, rapport au fait que les bootstrap/fundation et autres frameworks proposent par défaut ce Hamburger.

Les frameworks serait donc en cause — au premier abord — et j’avoue partager ce point de vue. Nous sommes aujourd’hui à l’air des templates et frameworks à tel point qu’il est dure de ne pas voir un site intégré avec boostrap et dont le template n’a pas été vu et revu sur themeForest. Cette effervescence d’outils et règles préconçues tendent vers une uniformisation du web dont certains annonce la mort (à tords ou à raison, cela est une autre question). Tout ces outils sont en soit intéressant mais il n’est pas rare de voir se développer une fainéantise globale tant du côté du designer se tournant vers un template simple à intégrer que du côté du développeur qui n’utilisera que la couche superficielle de son outils. Ces outils, extrêmement bien fait, facilitent la mise en place de site responsive. Mais comme tout outils ils ne sont pas fait pour s’adapter à tout les besoins mais à certains besoins. Ceux-ci proposent donc le burger menu comme menu par défaut ou en option, facile à déployer et dont le responsive est «parfait».

Cependant c’est aux UX designers de se poser la question de la pertinence de cet outils dans les différents cas de navigation. Pour autant nous avons tous tendance à manger un sandwich quand nous sommes en déplacement, ce n’est pas pour autant que nous en prendrions un au restaurant. Pourquoi serait-ce alors la même chose pour l’ergonomie? Pourquoi serait-elle identique sur mobile et sur desktop?
Lors de mes études dans le domaine de l’art graphique, nos enseignants avaient l’habitude de répéter que les logiciels de création d’images ne sont que des outils comme le sont crayons, fusain et autre encres de chine. J’aborde ce point de vue là également en programmation — notamment avec le design génératif — qui est pour moi un outils à la création. Si l’outil nous aide à créer il n’est pas pour autant le créateur et il est important de ne pas se laisser guider par lui mais de le maîtriser. Dans le cas de notre «burger» menu cela signifie qu’il est important de penser l’ergonomie de son site et de ne pas la laisser à la libre décision de son outils ou des tendances. D’autant plus qu’en grattant un peu sous la couche superficielle, on se rend vite compte que notre outils nous permet de réaliser aisément cette ergonomie que nous aurons pensé en amont.

Références :

Voici quelques références abordées lors de l’échange facebook :

http://blocnotes.iergo.fr/concevoir/le-burger-de-la-mort/ (Merci Julien Vieira)

http://www.lukew.com/ff/entry.asp?1945 (Merci Justin Marsan)

http://deep.design/the-hamburger-menu/ & https://medium.com/@drewbrolik/hamburgers-aren-t-the-problem-menus-are-a-hack-5a371447854 (Merci Maxime Bodereau)

Statistiques des résolutions mobiles 2014-2015

Liste des Sujets 2014-2015 [IxD]

Retrouvez la liste complètes des sujets travaillés en cours de design interactif (3e. année) et Digital Lab (3e. année).

Liste des sujets de design interactif :

Sujet second semestre Digital Lab (application des connaissances)

Expérimentations typographiques interactives

L’option Digital Lab a pour objectif de sensibiliser les étudiants à la conception graphique générative et interactive par l’étude de la forme depuis une approche géométrique et mathématique ainsi que par l’étude de la programmation par l’intermédiaire de Processing. Durant ces cours les étudiants sont amenés à appréhender les méthodes itératives, la création de tableaux et d’objets, la notion de comportement, la gestion d’un espace 2D/3D, les différents type d’aléatoire…

Après plusieurs cours portant sur la création d’objets aux comportements propres — programmation orientée objet — l’aléatoire et la gestion de chaîne de caractère, il leur a été demandé à chacun de réaliser une expérimentation typographique interactive.

Le Brief & les contraintes :

« Réaliser une expérimentation typographique interactive à partir d’une citation qui vous sera donnée. »

À travers cet exercice les étudiants se sont interrogés sur le sens des citations choisies, sur la composition graphique et typographique au sein d’un espace génératif ainsi que sur le comportement dont peut disposer un caractère typographique.

Temps de production : 4 cours

Étudiants :
Cindy Texeira
Savinien Fruhauf
Cyrus Bruns
Vincent Roure
Alice Zhu
Laurine Munsch
Justine Gaudin
Nadège Calegari
Anis Chouk
Romy Kombet
Stefania Giraldo-Garcia

Expérimentations Typographiques

Les expérimentations graphiques et typographiques sont depuis longtemps un des terrains de jeux préférés des graphistes. Entre respect et transgression des règles typographiques et de lectures, de nombreux graphistes tels que Roger Excoffon, Paul Rand, Milton Glaser ou encore Stefan Sagmeister, se sont prêtés à ces exercices. Il en est de même dans le domaine du design interactif et on compte de nombreuses expérimentations typographiques comme Alaphabet interactif de Murielle Lefèvre, Frédéric Durieu et Jean-Jacques Birgé en 1999 ou encore LetterScape en 2002 de Peter Cho, étudiant de John Maeda. À travers ce cours nous allons apprendre à utiliser et mettre un forme un texte à l’aide de processing mais aussi à manipuler les variables de types textes afin de les utiliser par la suite.

Variables textes et méthodes text();

Processing différencie deux types de variables pouvant contenir du texte, la variable de type String et la variable de type char

Comme son nom l’indique la variable de type String est une suite (chaîne) de caractères, elle permet de stocker des mots. Elle se déclare de la manière suivante :

La variable de type char, permet de ne stocker qu’un seul caractère. Elle se déclare de la manière suivante :

Il est important de noter que les suites de caractères sont encadrés par des doubles guillemets «  » là ou le caractère simple n’est encadré que par des simples guillemets  »

Lorsque nous souhaitons afficher un texte dans notre programme nous utilisons la méthode text(), celle-ci nous permettra d’afficher un texte à un endroit précis de notre programme. Cette méthode peut s’utiliser de différentes manières

Enfin la méthode textSize() nous permet de modifier le corps du texte. Comme toutes méthodes de mise en forme, celle-ci doit être placée avant la méthode d’affichage du texte.

Nous verrons un peu plus bas les méthodes de mise en forme de texte avancées.

Manipulations des variables String et char

Lors d’une expérimentation typographique il est souvent utile de pouvoir manipuler le texte.
Nous verrons, dans cette partie, différentes méthodes nous permettant de manipuler nos variables String et char

charAt()

La méthode charAt() permet de connaître un caractère à une position donnée dans une chaîne de caractères.

Ici la variable caractere sera égale à o car il s’agit du 4ème caractère de la variable monTexte

NB : il est important de noter que notre programme commence son calcul à 0. Il compte donc de la sorte :

  • charAt(0) = H
  • charAt(1) = e
  • charAt(2) = l
  • charAt(3) = l
  • charAt(4) = o
  • charAt(5) = (espace)
  • charAt(6) = W

 

substring()

substring() permet d’extraire une chaîne de caractères au sein d’une autre. Nous obtenons ainsi une partie ou un extrait de cette chaîne de caractères.

Ici la variable subst sera égale à World qui correspond à la chaîne de caractères comprise entre le caractère 6 et 11 de la variable monTexte.

length()

Comme pour les tableaux statiques, length() permet de connaitre une taille. Appliquée à une variable de type String, cette méthode nous permet de connaître la taille, en caractère, d’une chaîne de caractères.

Ici la variable len sera égale à 29 car la variable monTexte possède 29 caractères.

indexOf()

La méthode indexOf() permet de connaitre la position d’un caractère dans une chaîne de caractères. Elle correspond à l’inverse de la méthode charAt()

Ici la variable indexMonTexte sera égale à 24 car ‘b’ est en 24ème position de la variable monTexte.

toLowerCase() & toUpperCase()

Ces deux méthodes, plus apparentées à des méthodes de mise en forme, permettent de réécrire une chaîne de caractère en capitale ou bas de casse.

Ici la variable bdc sera égale à « hello world, welcome on board » et CAP à « HELLO WORLD, WELCOME EN BOARD », soit, respectivement, la variable mon monTexte en bas de casse et capitale.

str()

La méthode str() permet de convertir des variables de type int ouf float (nombre entier ou décimal) en chaîne de caractères.

Ici la variable numberToString sera égale à la chaîne de caractères « 2014 ».

char() & int()

Les méthodes char() & int() permettent respectivement de convertir un caractère en sa valeur numérique et vice versa (notamment utilisé en ASCII).

Ici la variable caractere sera égale à ‘A’ qui est la lettre correspondant à la valeur ’65’ et la variable numberChar sera égale à ’69’ qui est la valeur correspondante à ‘E’.

NB : Vous pouvez retrouver les correspondances ASCII ici : Tables de correspondance ASCII

join(), split(), splitTokens()

La méthode join() permet d’assembler les éléments d’un tableau de String en une seule chaîne de caractères. Elle s’emploie de la manière suivante : join(nomDuTableau, « séparateur »);. Séparateur correspond au caractère ou chaîne de caractères que nous souhaitons utiliser pour séparer nos mots.

Ici la variable ensemble sera égale à « les étudiants sont : prénom1, prénom2, prénom3, prénom4, prénom5 » où « ,  » sera le séparateur de chacun de nos mots.

La méthode split() effectue l’inverse de la méthode join(). Elle permet de convertir en tableau de type String une chaîne de caractères. Elle s’emploie de la manière suivante : split(variableString, « séparateur »);. Séparateur correspond au caractère ou chaîne de caractères que nous souhaitons utiliser pour séparer nos mots dans notre variable String.

Ici notre tableau prénom contiendra alors les éléments suivant : prénom1, prénom2, prénom3, prénom4, prénom5.

splitTokens effectue la même action que la méthode split() à cela près qu’elle permet d’utiliser divers séparateurs.

Ici notre tableau phrase contiendra les éléments : « Hello World » et « Welcome on Board » soit notre chaîne de caractères monTexte séparée à chaque ponctuation ‘!’ et ‘.’.

toCharArray()

La méthode toCharArray() permet de convertir en tableau de type char une chaîne de caractères. Elle permet ainsi d’isoler l’ensemble des caractères d’une phrase ou d’un mot.

Ici la tableau car contiendra les éléments suivant : H, e, l, l, o, ,W, o, r, l, d, !.

Ces méthodes constituent les principales méthodes nécessaire à des expérimentations typographique. Il existe évidement encore d’autres méthodes permettant de traiter des variables textes dont vous pourrez retrouver les références sur le site processing

Mise en forme (avancée) de texte

Utiliser une typographie

Comme pour beaucoup de programmes, si nous souhaitons utiliser une typographie spécifique il nous faudra la charger dans notre programme. Processing utilisant une format spécifique pour ses fichiers typographiques, il nous faudra dans un premier temps créer puis charger notre typographie. Cela va se faire très facilement à l’aide de l’outil Create Font disponible via le menu Tools de notre fenêtre processing. Cet outil nous permettra, via la pop-up suivante, de choisir puis créer notre typographie au corps souhaité.

createFont

Une fois notre typographie créée nous pouvons la retrouver dans le dossier /data présent à la racine de notre sketch. Celui portera le nom que nous lui aurons donné précédemment (filename).

Afin de pouvoir utiliser notre typographie dans notre programme il est nécessaire de la charger dans une variable de type PFont. PFont pour processing font est un variable de type typographie. Elle permet de stocker une typographie chargée. Elle s’utilise de la manière suivante :

Nous pouvons alors utiliser notre typographie au sein de notre méthode draw() afin de mettre en forme notre texte. Pour cela nous utiliserons la méthode suivante textFont(nomDeMaVariableFont);

Nous remarquons que notre texte est automatiquement mise en forme au corps auquel nous avons créer notre font (Size dans l’outil de création font). Il nous est cependant possible de changer celle-ci à l’aide de la méthode textSize();

textAlign()

Cette méthode nous permet de mettre en forme l’alignement d’un texte.

  • CENTER pour un alignement centré
  • LEFT pour un alignement à gauche
  • RIGHT pour un alignement à droite

Elle s’utilise de la manière suivante :

Il est également possible de gérer l’alignement vertical d’un texte. Pour se faire nous utiliserons toujours la méthode textAlign() auquel nous ajouterons un argument. Nous aurons donc textAlign(alignementHorizontal, alignementVertical). Les alignements verticaux possible étant:

  • TOP pour un alignement haut
  • BOTTOM pour un alignement bas
  • CENTER pour un alignement centré
  • BASELINE pour un alignement sur la ligne de base

Nous l’utilisons donc la manière suivante :

textLeading()

La méthode textLeading() permet de manipuler, en pixel, l’interlignage d’un texte. Elle s’utilise de la manière suivante :

NB : Il est possible dans une variable String d’indiquer un retour à la ligne. Pour se faire il suffit d’inclure la chaîne de caractères suivante « \n » avant chaque retour à la ligne dans notre variable String. Dans l’exemple ci-dessus nous avons donc écrit : Hello World!\nHello You.\nHello Me afin d’indiquer un retour à la ligne avant chaque nouvelle phrase.

textWidth()

textWidth() permet de connaitre, en pixel, la largeur d’un texte affiché par notre programme.

textAscent() & textDescent()

La méthode textAscent() permet de connaitre la hauteur de jambage supérieur (hampe ou longue ascendante) de la typographie utilisée dans notre programme. Cette hauteur est calculée depuis la ligne de pied de notre typographie.
Elle s’utilise de manière suivante :

La méthode textDescent() permet de connaitre la hauteur de jambage inférieur (hampe ou longue descendante) de la typographie utilisée dans notre programme. Cette hauteur est calculée depuis la ligne de pied de notre typographie.
Elle s’utilise de manière suivante :

En combinant ces deux méthode nous pouvons alors calculer la hauteur d’une ligne en fonction de la typographie utilisée.

Part_05. Exemple d’expérimentation typographique

experimentation_0764

Dans l’exemple suivant nous allons voir comment exploiter les méthodes précédentes afin de réaliser une expérimentation typographique interactive.
Pour cet exemple nous allons utiliser une citation de Charles Eames : « Design is a plan for arranging elements in such a way as best to accomplish a particular purpose. »

Nous souhaitons disposer l’ensemble des caractères formant cette citation sur une grille 3D. Celle-ci effectuera une rotation sur différents axes.
Enfin nous allons voir comment mettre en exergue certaines lettres de cette citation lorsque l’utilisateur appuie sur la touche de son clavier correspondant. Celles-ci avanceront sur l’axe z puis changeront de couleurs.

Nous allons commencer par créer un classe Lettre. Celle-ci permettra de stocker et gérer nos objets caractères. Nous voulons positionner nos lettres dans un espace x, y, z et que nous souhaitons en changer la couleur. Nous aurons donc besoins des variables suivantes :

  • La variable char correspondant à la lettre de la citation
  • La position x,y,z (float)
  • La couleur HSB de la lettre (float)
  • Une variable boolean afin de savoir si notre lettre et appuyée ou non

Cela nous donnera le début de classe suivante :

Nous aurons par ailleurs besoins de diverses méthodes dont :

  • Le constructeur de notre objet
  • Une méthode permettant de définir la lettre et la couleur de notre objet defineLetter(char lettre_)
  • Une méthode permettant de changer le comportement de la lettre si celle-ci est appuyée changeBehavior()
  • Une méthode permettant d’afficher notre lettre display()
  • Une méthode globale permettant d’appeler les méthodes nécessaires à notre programme run()

Ajoutons notre première méthode, à savoir, notre constructeur. Celui-ci va nous permettre de définir la position de notre objet. Nous définirons la lettre puis la couleur dans une seconde méthode afin de s’éviter un calcul de correspondance entre une grille et un suite de caractères.

Nous allons ensuite ajouter notre méthode permettant de définir la lettre et la couleur de notre objet. Nous n’allons pas choisir la couleur de nos lettre au hasard mais allons mapper leur valeurs en ASCII sur des valeurs de bleu du cercle chromatique. Pour ce faire nous allons utiliser la méthode int() vu précédemment puis nous mapperons les valeurs à l’aide d’une méthode map(). Nous définirons le caractère de notre objet en découpant la citation, donc en dehors de l’objet en lui même, nous devrons donc passer la variable caractère à notre méthode. Pour ce faire nous allons utiliser la syntaxe suivante fonction(typeDeVariable nomDeVariable)

Nous ajoutons ensuite nos méthodes changeBehavior() et display(). La première nous permettra de changer la position z et la saturation de notre objet si sa lettre correspondante est appuyée par l’utilisateur. Nous utilisons une simple condition ainsi que notre variable booléenne.

Notre méthode display() dessinera notre lettre au centre de sa position. Nous dessinerons également une tige à notre lettre afin d’accentuer graphiquement notre mise en valeur des lettre appuyées.

Enfin nous regroupons nos deux méthodes changeBehavior() et display dans une méthode run()

Nous obtenons alors la classe suivante

Nous allons à présent nous occuper de découper notre citation puis l’afficher sur scène. Si nous analysons le programme voulu et son design, nous remarquons que nous aurons besoins de

  • Découper notre citation en tableau de caractères
  • Positionner nos caractères sur un grille d’une certaines taille, avec un espace précis entre chacun d’eux
  • Positionner notre grille sur la scène
  • Effectuer une rotation de notre scène

Nous aurons besoins des variables suivantes :

  • Taille de la scène
  • Citation et Auteur
  • Tableau pour stocker l’ensemble des caractères formant la citation
  • Tableau pour stocker l’ensemble de nos objets Lettre
  • La typographie pour notre mise en forme du texte
  • La taille de notre grille
  • les marge haute et basse pour positionner notre grille
  • la résolution en largeur et hauteur de notre grille
  • Les angles x, y, z de notre scène

Soit :

Nous pouvons à présent définir notre setup(). C’est dans ce dernier que nous effectuerons l’analyse de notre texte, la création des objets Lettre et leur position.
Nous commençons par les paramètres de base de notre programme ainsi que le chargement de la typographie créée au préalable :

Puis, à l’aide de la méthode toCharArray() nous allons créer un tableau contenant tout les caractères de la variable citation.

Nous définissons ensuite les paramètres de notre grille, puis à l’aide d’une double boucle for, nous créons et positionnons nos objets de type Lettre.

Enfin nous n’avons plus qu’à définir les lettres de chacun de nos objets. Si nous observons notre grille, nous remarquons qu’il s’agit d’une grille de 100 emplacements. Or notre citation fait 97 caractères. Nous devrons donc, à l’aide d’une condition, définir un caractère vide ‘ ‘ pour tout nous objets n’ayant pas de caractères correspondant (de l’emplacement 98 à 100).

Nous obtenons donc le setup() suivant

Nous allons désormais définir notre draw(). Nous souhaitons pouvoir effectuer une rotation de notre grille. Cela implique donc l’utilisation d’une déplacement de matrice et d’une rotation sur des axes x, y et z. Pour afficher nos objets nous utilisons un simple boucle for() afin d’appeler leur méthodes run().

Une fois notre affichage créé, il ne nous reste plus qu’à réaliser la partie interactive de notre expérimentation. Nous allons utiliser une méthode keyPressed() dans laquelle nous comparons la touche du clavier appuyée par l’utilisateur avec le lettres de nos objets. Si celles-ci correspondent, nous passerons alors les variables booléenne clicked de nos objets en vrai, sinon en faux.

Nous obtenons alors l’expérimentation suivante pour le code suivant :

Espace 3D et formes primitive – [initiation]

L’espace tridimensionnelle cartésien est un espace assez simple à aborder. Il possède l’ensemble des propriétés de l’espace cartésien bidimensionnel à cela prêt que l’ajout d’une dimension offre une nouvelle perspective : la profondeur.

Cet espace est habituellement représenté par les axe X, Y, Z suivant :

espace3D-01

Afin de comprendre cet espace il est important de connaitre le sens des différents axes.
Nous savons que par convention, l’espace bidimensionnel de notre programme est inversé, notre point d’origine 0,0 étant en haut à gauche, les x s’incrémentant de gauche à droite et les y s’incrémentant de haut en bas. De la cas de l’axe Z, celui-ci va en se décrémentant. Ainsi un objet loin de notre point de vue aura une position z inférieur de celle d’un objet proche de notre point de vu.
Nous obtenons alors le schéma suivant :

espace3D-02

Enfin il est important de noter que la position z de notre « oeil » ou point de vue sera de 0 par défaut. Celui-ci regardant dans le sens inverse nous observons alors que notre axe z visible sera un axe inférieur à 0 et se décrémentant. Il sera donc négatif.

L’espace tridimensionnel rajoute donc un concept de point de vu qu’il sera important de maîtriser afin de déplacer son point de vue dans son espace.

Transformations de matrice afin de déplacer son point de vue

Afin de maîtriser son point de vue et donc la position dans un espace nous allons utiliser une méthode vue précédemment pour changer un système de coordonnées, les transformations de matrice.
Nous savons qu’il nous est possible de déplacer notre point d’origine où l’on souhaite dans notre programme et ce sur un axe XY. Il en est de même pour un espace 3D. Dans l’exemple suivant nous allons dessiner un rectangle de taille 20, positionner en 0,0 puis nous verrons comment en changer son point de vue à l’aide des transformations de matrices.

Lorsque nous dessinons notre rectangle en position 0,0,0 nous obtenons l’image suivante.

Notre rectangle, de position 0,0,0 n’est visible que de moitié. Si nous souhaitons le placer au centre de notre programme tout en conservant sa position nous utiliserons une transformation de matrice. Il est est de même si nous souhaitons changer sa position sur l’axe Z. Ainsi nous pouvons obtenir les transformations suivante :

Dans notre cas nous allons positionner notre rectangle en z -100 et au centre de notre programme.

Rotations de matrice

Nous savons, dans un espace bidimensionnel, qu’il nous est possible d’effectuer un rotation de notre objet par le biais d’une rotation de matrice. Cette transformation nous est toujours possible dans un espace 3D en devenant plus précise puisque nous pouvons désormais effectuer des rotations sur un axe choisi.

espace3D-03

Pour ce faire nous allons utiliser les méthodes suivantes

Si nous reprenons notre exemple ci-dessus et que nous appliquons à chacun des axes X,Y,Z un angle s’incrémentant respectivement de 0.01, 0.02, 0.03 radians, nous obtenons alors de notre objet rectangle, une rotation différente sur chacun de ses axes.

Formes primitives

Comme pour l’espace 2D, processing possède des formes primitives en 3D, celle-ci nous permettent d’obtenir rapidement une forme 3D sans avoir à dessiner l’ensemble de ses sommets.
Les deux principales formes primitives sont la box et la sphère.

Nous remarquons qu’aucune de ses formes primitives ne possèdent de position x,y,z, ces dernières devant être définies par des transformations de matrice.
Certaines formes primitives 2D sont elle aussi disponible dans un espace 3D par le simple ajout d’une position z.

Enfin, comme nous l’avons vu précédemment, il nous est toujours possible d’utiliser des formes primitives 2D (rect, quad, triangle…) dans un espace 3D lorsque nous utilisons des transformations de matrice.

Transformations 2D

Lorsque nous dessinons sur nos écrans, nous travaillons sur une grille, une matrice. Dans le cas d’une réalisation de maquette pour un site web, nous travaillons, par exemple, sur des .psd de 1280*1024 soit une grille de pixels de 1280*1024, c’est notre matrice. Nous plaçons ensuite nos éléments sur cette grille. Il en est de même avec processing où notre grille commence au point d’origine 0, 0 pour finir au point width, height.
Nous allons voir comment manipuler cette matrice.

matrice-01-01

Déplacements de matrice

Par défaut le point d’origine (0, 0) de notre matrice se trouve au coin supérieur gauche de notre programme mais il peut être facilement déplaçable.

Déplacer une matrice signifie que l’on décale son point d’origine à un autre endroit. Cela nous donne un autre point de vue et change notre système de géométrie.
Il peut être pratique de déplacer son point d’origine au centre du programme, notamment lorsque nous souhaitons réaliser un programme en symétrie. Ainsi dans le cas d’un rectangle de position 10, 10 dans une symétrie axiale, dont le point d’origine sera le centre de notre programme, le second rectangle aura une position de -10, 10 soit l’inverse de la position x du premier rectangle.

matrice-02-02

Afin d’effectuer un déplacement de matrice dans processing, nous utilisons la méthode suivante :

Cela aura pour effet de déplacer la matrice de x pixels en latéral et y pixels en vertical. Le point d’origine 0,0 sera alors en x, y.
Il est important de savoir que cette méthode est cumulative, c’est à dire que si nous effectuons, tout au long de notre code, les méthodes suivante :

Cela aura pour effet de déplacer une première fois notre matrice en 10,10 puis en 20, 20 puis en 30, 30. Nous devrons donc effectuer un déplacement inverse si nous souhaitons repositionner la matrice à son premier point d’origine.

matrice-03-03

Sauvegarde du point d’origine avant transformation

Afin d’éviter de nombreuses transformations retour durant notre code, il est possible d’isoler notre déplacement de matrice à l’aide des méthodes suivante :

pushMatrix() permet à un instant T d’enregistrer les coordonnées du point d’origine afin de pouvoir les restituer à l’aide de la commande popMatrix()

À l’exécution de ce code, la matrice se déplacera en position x, y lors de la méthode translate(), puis reviendra à son point d’origine lors de la méthode popMatrix(). Cela nous permet donc de changer notre géométrie à un instant T et de dessiner l’ensemble de nos formes voulues dans ce nouveau système de géométrie encadrée par les méthodes pushMatrix(); popMatrix();

matrice-04-04

Rotations de matrice

La rotation d’un élément est un cas particulier. Pour bien comprendre son fonctionnement revenons au point de vue microscopique de notre espace de travail, le pixel.
Nous souhaitons dessiner un rectangle de position 10, 10 et de taille 10, 10.

puis nous souhaitons effectuer un rotation de 45° de ce même rectangle. Le pixel est un élément dessiné, 0 ou 1, plein ou vide, il ne peut être rempli de manière partielle.
Lorsque nous effectuons ce genre de manipulation dans photoshop, notre logiciel dessine notre diagonale sous forme de pixels pleins ou vides.

matrice-05-05

Cette transformation utilisée par photoshop n’est pas la plus simple à réaliser et processing utilise un autre méthode.
Au lieu de redessiner les pixels de notre rectangle, nous allons effectuer une rotation de notre espace de coordonnées à l’aide la méthode suivante :

Cette méthode permet donc faire faire une rotation à notre matrice et ce depuis son point d’origine.

matrice-06-06

Pour obtenir notre rectangle à une véritable position 10, 10 et ayant effectué une rotation à 45° nous devront donc déplacer la matrice un premier temps, puis effectuer la rotation.

matrice-07-07

Cela se traduira en code par :

Exemple

Dans l’exemple suivant, nous allons réaliser un grille de 20*20 pixels contenant des rectangles de 18 pixels. Nous souhaitons que ces rectangles effectuent des rotations lorsque la souris passera en roll over dessus.

Pour cela nous allons partir d’une classe de rectangle relativement simple possédant les variables suivante :

  • position x
  • position y
  • largeur
  • hauteur
  • couleur aléatoire
  • angle
  • vitesse de l’angle

Nous allons ajouter une méthode display() qui affichera nos rectangles et sera appelée par la méthode run().
C’est dans cette méthode que nous effectuerons nos transformations de matrice, c’est à dire untranslate() à la position du rectangle ainsi qu’un rotate() de la valeur de l’angle.

Puis nous réalisons une méthode updateAngle() dans laquelle nous effectuerons une rotation de l’angle et qui sera appelée si notre souris est en roll over sur notre rectangle

Nous pouvons maintenant revenir dans notre feuille principale afin de réaliser notre grille. Pour cela nous allons utiliser un ArrayList<>() pour stocker nos objets et une double boucle for pour réaliser notre grille.

Dans notre draw() nous réalisons ensuite une boucle for sur l’ensemble de notre tableau d’objets afin de les afficher. Puis nous comparons la position de notre souris avec chacun des rectangles. Si un rectangle se trouve sous la souris, celui-ci effectuera une rotation à l’aide de sa méthode updateAngle()

Nous obtenons alors le résultat escompté.

Analyse audio et l’utilisation de données FFT

L’animation d’images synchronisées sur une musique est un procédé reconnu et utilisé depuis longtemps tant dans le VJing que dans les divers domaines de l’animation. De nombreux outils comme after effect nous permettent de synchroniser, de manière automatique ou plus maîtrisée, une animation sur un son, il en est de même avec les outils de creative coding.
Processing permet, par l’utilisation de la librairie Minim, de jouer et analyser un son. Les valeurs récupérées peuvent ensuite être utilisées de manière différente comme dans l’exemple ci-dessous où l’analyse audio permet de gérer la déformation d’un mesh 3D ou le comportement d’un flocon de neige.

Nous verrons ici comment utiliser la librairie Minim et créer un objet nous permettant de récupérer l’amplitude des bandes FFT (issues de la transformation de Fourier) afin d’animer des objets.

Analyse audio et les FFT

Lorsque nous écoutons un son nous entendons les diverses notes jouées. Cependant lorsque nous analysons un son, ce dernier n’est pas représenté en terme de notes mais en amplitudes/temps.
D’une manière simple, l’amplitude à un instant T d’un son correspond à son volume à ce même instant T. Si nous souhaitons représenter un son nous obtenons alors le graphique suivant :

son-amplitude-01-01

Nous pouvons facilement utiliser l’amplitude d’un son comme valeur pour une animation. Dans l’exemple suivant nous avons mappé la valeur y d’une ellipse sur l’amplitude de notre musique.
Pour ce faire, nous avons utilisé after effect afin de convertir les données audio en keyFrame afin de pouvoir lire cette amplitude. Nous avons ensuite mappé la valeur y de notre objet à l’aide de l’expression suivante.

Nous obtenons alors l’animation suivante :

Dans le cas d’une animation simple cela pourrait nous suffir, mais dans le cadre d’un clip génératif par exemple nous souhaitons obtenir plus de variations et pouvoir différencier des notes, des graves ou des aïgues. Pour ce faire nous allons utiliser la transformée de Fourier. La transformée de Fourier est une fonction inventée par Jean Baptiste Joseph Fourier permettant de transformer un spectre en fréquences. Dans notre cas nous allons nous en servir pour transposer l’amplitude de notre son en fréquences Hertz.

Un son est composé d’un ensemble de fréquences Hertz, chacun de ces hertz aura une amplitude différente. Si nous traçons cela nous obtenons le graphique suivant (pour l’instant T, l’amplitude des fréquence changeant à chaque instant)

son-hertz-01-01

Cependant on pourrait se demander en quoi cela nous intéresse de transformer l’amplitude d’un son en fréquence.
Il faut savoir que chaque son possède une fréquence majeure, il s’agit de la fréquence dont l’amplitude sera la plus haute. Chaque son étant différent il est alors possible d’isoler pour chacun d’entre un leur fréquence majeure, cela devient leur empreinte. On peut donc facilement reconnaître une note par sa fréquence majeure, ainsi la fréquence d’un La (octave 2) sera de 220hz.
Evidemment dans le cadre d’une musique, il faut prendre en compte le fait que plusieurs instruments joueront en même temps, il sera donc très difficile d’extraire une note exacte par sa fréquence puisque nous obtenons l’amplitude des fréquences pour l’ensemble des instruments enregistrés.

Un autre élément intéressant des fréquences est leur ordre croissant. Les fréquences audible par l’homme vont en moyenne de 3 hz à 22 000 hz, et il est intéressant de savoir que les sons associés aux fréquences les plus basses sont les sons graves contre les sons aux fréquences hautes qui seront les plus aiguës. Les fréquences peuvent donc nous aider à obtenir des variations tant sur les graves, les médiums que les aiguës. Ils nous offrent alors beaucoup de possibilités en terme d’animation.

Nous avons vu, dans les grandes lignes, ce que nous pouvons analyser d’un son. Passons à la pratique en essayant d’extraire les données de notre musique à l’aide de processing.

L’utilisation d’une librairie intégrée dans processing

Processing ne gère pas de manière « native » la lecture/analyse d’un son. Pour se faire nous allons utiliser une librairie intégrée : Minim. Il s’agit d’une librairie dédiée au traitement de son et permettant à la fois la gestion, lecture, écriture, analyse d’un son. Cette librairie fait depuis longtemps partie du package processing étant donné ses grandes capacités. Minim étant une librairie nous aurons besoins de l’importer dans notre skecth afin de pouvoir accéder à ses méthodes. Pour se faire nous utilisons le code suivant :

Création d’une classe FFTObject – variables et constructeur

Afin de faciliter l’analyse des fréquences tout au long de notre code nous allons créer un objet que nous appellerons fftObject. Cet objet nous permettra à la fois de charger et jouer un son mais aussi d’accéder à l’analyse des bandes FFT de ce même son.

Nous aurons besoins de divers objets liés à la librairie Minim, à savoir :

  • Un objet minim de type Minim permettant de gérer l’ensemble des objets de chargement, lecture et analyse d’un son
  • Un objet music de type AudioPlayer afin de lire notre musique
  • Un objet fft de type FFT afin de réaliser et utiliser la transformée de fourier

Nous aurons ensuite besoins de la variable suivant :

  • Une variable timeSize définissant la taille du buffer de notre son à analyser

Nous pouvons donc commencer à créer notre classe fftObject de la manière suivante :

Passons maintenant au constructeur de notre objet.
Nous allons définir notre variable timeSize à 1024. Il s’agit de la taille du buffer dédié au son. Le buffer est une mémoire tampon, il permet de stocker à l’avance les données du son devant être lues. Ce buffer nous servira lors de l’initialisation de l’objet music.

Nous devons ensuite initialiser notre objet minim de la manière suivante :

Nous remarquons l’ajout d’une variable parent, celle-ci correspond au contexte. En effet lors de son initialisation l’objet minim a besoins de connaitre le contexte dans lequel il va être appelé. Dans notre cas il s’agit de notre application processing. Si nous avions initialisé notre objet dans le setup, nous aurions utilisé la variable this permettant de cibler notre application comme étant le contexte.
Puisque nous somme dans un objet, la variable this ne cible plus l’application comme contexte mais l’objet en lui même. Il nous faudra alors la passer dans notre objet lors de son initialisation. Pour ce faire nous avons ajouté au constructeur une variable parent de type PApplet.

Nous pouvons ensuite initialisé l’objet music. Ce dernier aura besoins de l’url de notre son à jouer ainsi que de la taille du buffer que l’application devra lui allouer.

L’objet fft aura aussi besoins de la taille du buffer ainsi que la fréquence à laquelle la musique a été échantillonné. Cette dernière valeur nous est donnée par l’objet music à l’aide de la méthodes suivante :

Nous obtenons donc pour l’objet fft

Enfin, une fois l’ensemble de nos objets construit nous lançons la lecture de notre son à l’aide de la méthode suivante

Nous obtenons alors, pour notre classe fftObject le constructeur suivant :

Création d’une classe FFTObject – les méthodes

Une fois notre constructeur défini nous avons besoins de créer les diverses méthodes dont notre objet aura besoins. Dans notre cas nous avons besoins des méthodes suivantes :

  • Une méthode getFFTLevel nous renvoyant l’amplitude d’une fréquence souhaitée
  • Une méthode displayFFT permettant de dessiner les amplitudes de chacune de nos fréquences sous forme d’égaliseur

Commençons par la méthode getFFTLevel, celle-ci sera relativement simple.
Nous allons utiliser une méthode de type float. Les méthodes typées (float, int, boolean…) sont des méthodes renvoyant des variables une fois exécutée.

Si on écrit :

Alors x sera égale à valeur
Dans notre cas nous souhaitons pouvoir connaitre l’amplitude d’une bande i et ceux à n’importe quel endroit de notre code. Nous allons donc créer une méthode nous permettant par la suite de dire :

où x sera égale à la valeur de l’amplitude de la fréquence i.

Cette méthode getFFTLevel se composera alors de la manière suivante :

Nous allons désormais définir la méthode displayFFT. Celle-ci nous permettra d’afficher sous forme d’égaliseur les amplitudes de nos fréquences.
Nous aurons besoins de passer diverses variables dans cette méthode, à savoir :

  • la position x de notre égaliseur
  • la position y de notre égaliseur
  • la hauteur maximum heightBande de nos fréquences
  • le nombre nbBandes de fréquences voulues (de nombreuses fréquences n’étant pas couvertes ou non présentes dans notre échantillons nous n’aurons pas besoins de dessiner les 22000 hertz)

enfin à l’aide d’une boucle for nous dessinerons l’ensemble de nos fréquences. Cela nous donnera :

Utilisation de notre class FFTObject

Maintenant que nous avons créé notre classe FFTObject il ne nous reste plus qu’à l’utiliser. Dans notre feuille principale nous allons déclarer un objet fftObj de type FFTObject ainsi qu’une variable parent de type PApplet.

Nous initialisons l’ensemble de nos variables et objets dans notre setup

Nous pouvons désormais dessiner notre égaliseur dans notre boucle draw() à l’aide de la méthode suivante

De la même manière nous pouvons dessiner un lot de 20 ellipses dont la taille pourra varier en fonction de bandes FFT comprises en 0 et 20.

Ils ne vous reste plus qu’à expérimenter à votre tour à créer votre propre application réactive au son.

taille

Bibliographie

Ce cours a été réalisé à l’aide des informations suivantes :

Amplitude et Décibels, Topos générals préliminaires sur l’audio numérique.

Transformation de Fourier

Définition des Hertz

Notes de musique et correspondance en fréquences hertz

échantillonage d’un son

Minim, références

Le processus génératif, retour sur les classes et le temps

Il est parfois utile de revoir ses bases et quoi de mieux qu’une fin d’année pour cela.
Durant cet exercice nous verrons comment réaliser un grand nombres de variations d’une même idée à l’aide du processus génératif.

Cet exercice nous permettra également de revoir les bases suivantes :

  • Création et utilisation des classes
  • Gestion du temps via un timer
  • Utilisation de coordonnées polaires

Définition du sketch 0

Notre skecth 0 sera la base de nos nombreuses variations. Il se traduit par un idée simple autour de laquelle nous pourrons facilement travailler.

Pour cela nous allons nous inspirer du travail de Joshua Nimoy et GMunk réalisé pour le film Tron Legacy et plus précisément l’arrière plan de la scène des « jeux ». Durant cette scène nous pouvons observer des feux d’artifices en arrière plan, ceux-ci présentent toutes les similitudes d’un feu d’artifice normal (étincelles, explosions, physique…) mais ont aussi la particularité d’être géométrique et ceux afin d’accentuer le fait que l’ensemble se passeau cœur d’un programme informatique.
Pour ce faire Joshua Nimoy a travaillé de nombreuses formes tel que les solides de planton comme l’icosaèdre ou le dodécaèdre.

Sur cette même idée nous allons réaliser un « feu d’artifice » géométrique. Notre skecth présentera un élément au comportement simple. Ce dernier effectuera en un temps déterminé un trajet. Lorsque son temps sera écoulé, ce dernier se stoppera et « explosera », laissant apparaître de nouveaux éléments ayant le même comportement et répartis sur un cercle.

expo

Pour réaliser cela nous aurons besoins d’un objet « Point » ayant un comportement défini et un certains nombre de variables.
Nous souhaitons que notre objet effectue un trajet vertical durant un temps donné avant que ce dernier ne s’arrête et « explose » en créant de nouveaux objets identiques à lui même. Enfin, afin que ces nouveaux points soit placés sur un cercle de centre « point explosé » nous aurons besoins de travailler en coordonnées polaires (cf cours trigonométrie).
Notre objet peut se décomposer de la manière suivante :

  • Variables
    • Positions x, y
    • Angle « theta »
    • Rayon « radius »
    • Vitesse du Rayon « vRadius » (cette variable nous permettra de déplacer notre Objet)
    • Valeur booléenne « vie » (Tant que le temps de vie de l’objet sera supérieur à 0 alors son état vie sera vrai)
    • Valeur booléenne « exploded » (Tant que notre objet n’aura pas explosé et engendré de nouveaux objets, alors son état exploded sera faux)
    • Taille « taille » de notre dessin
    • Valeur de margeX et margeY afin de positionner notre dessin sur la scène
    • Un objet Timer permettant de décompter la vie de l’objet
  • Méthodes
    • Methode « run » contrôlant l’ensemble des méthodes de l’objet
    • Methode « UpdateRadius » faisant parcourir ou non un chemin à l’objet en fonction de son état de vie
    • Méthode « displayPoint » affichant une ellipse à la position de l’objet
    • Méthode « displayLine » affichant une ligne depuis l’objet et son origine
  • Constructeur
    • Définitions du rayon, de l’angle et des marges
    • Initialisation des variables

Une fois l’ensemble de éléments composant notre objet défini, nous pouvons concevoir sa classe.
NB : Ici nous utilisons un timer afin de calculer le temps de vie de notre objet. Il ne faudra donc pas oublier d’inclure ce dernier dans notre sketch. Celui-ci est disponible ici

Nous allons désormais définir nos méthodes en commençant par la méthode permettant à notre objet de se mouvoir.
Notre objet possède un temps de vie durant lequel nous souhaitons qu’il se déplace. Lorsque ce temps de vie est épuisé notre objet devra s’arrêter. Pour cela nous allons créer une méthode « updateRadius » interrogeant le timer de notre objet. Il en résultera deux états :

  • Le timer est fini : Alors notre état de vie passe en faux
  • Le timer n’est pas fini : Alors nous incrémentons notre rayons de sa vitesse et mettons à jour les coordonnées de notre objet

Nous réaliserons ensuite deux méthodes permettant de dessiner notre objet ainsi que son parcours

Enfin nous assemblons l’ensemble des ces méthodes dans une méthode contrôleur

Nous venons alors de créer notre classe Point

Nous pouvons donc attaquer la seconde partie de notre sketch permettant d’appeler et afficher nos objets.
Nous savons que nous aurons besoins de dessiner un nombre encore non-défini d’objets Point.
Nous souhaitons aussi que nos objets explosent en créant un certains nombre de point. Nous définirons tout cela dans notre « setup ».

Afin de pouvoir recréer un nouveau « feu d’artifice » quand bon nous semble, nous allons créer un méthode « mousePressed » permettant de vider notre tableau et de re-initialiser nos variables.

Enfin dans notre méthode « draw » nous allons appeler, créer et afficher nos objets. Pour cela nous allons décomposer notre méthode en plusieurs parties

  • Une boucle for() nous permettant de parcourir notre tableau de points et à l’intérieur de laquelle nous effectuerons plusieurs taches
    • Appeler la méthode run() contrôlant nos objets
    • Interroger l’état de vie et d’explosion de notre objet
      • Si notre objet a fini son état de vie (vie == false) et n’a pas explosé (exploded == false) : alors nous créons de nouveaux objets dont l’origine sera la position de l’objet explosant. Enfin nous passerons l’état « exploded » de l’objet explosant en vrai

Si nous effectuons un « run » de notre skecth nous remarquons que nous obtenons l’effet souhaité, cependant notre sketch se met rapidement à ralentir puis se bloque. Cela s’explique par le fait que ce dernier effectue un calcul infini que la mémoire de l’ordinateur ne pourra supporter.

expo-bug

Si nous reprenons notre concept, nous remarquons que notre tableau d’objets augmente de manière exponentielle.
En effet chaque point, une fois sa vie terminée, explose en un nombre de points défini, par exemple 4.
Ainsi à chaque explosion (ou cycle) nous obtenons le calcul suivant : 1^4^4^4^4… soit : 4^nbDeCycle ou : mesPoints.size() = nbNewPts^nbDeCycle

Afin d’éviter à notre sketch de s’étendre à l’infini nous allons donc définir un nombre maximal de cycles auxquel notre tableau de points aura droit. Pour ce faire nous allons devoir compter les cycles de notre tableau, or nous disposons de 2 valeurs dans l’équation suivante : mesPoints.size() = nbNewPts^nbDeCycle soit mesPoints.size() et nbNewPts.

Pour calculer le nombre de cycles de notre tableau nous allons faire appel à une fonction bien pratique en Maths, la fonction logarithme népérien. En effet, en Maths, nous savons que log(a^x) = N ou a^N = x. Cela se note aussi de la manière suivante :
logNeperien

Nous pourrons alors traduire cela dans processing à l’aide des méthodes round() permettant de calculer un nombre arrondi et de la méthode log() permettant de calculer une valeur logarithmique. Ainsi nous aurons :

Il ne nous reste donc plus qu’à reporter cela dans notre sketch et de définir un nombre maximum de cycle pour notre tableau. Enfin dans notre méthode draw nous autorisons nos objets à se créer que si le nombre de cycle actuel n’est pas supérieur au nombre de cycle maximal. Nous rajoutons donc deux nouvelle variables :
cycle et limiteCycle. Notre « draw » se composera alors de la manière suivante :

Nous venons donc de terminer notre sketch 0, base de notre travail génératif.