Table des matières

Le motif

Description

Création d'une production portant sur le motif suite à une visite au Château Borély.

Aborder la thématique du motif en englobant l'espace du Musée des Arts Décoratifs et de la Faïence nous a poussé à l'appréhender dans ce cadre spatio-temporel particulier.

Construit au XVIIIe siècle, son architecture est issue du classicisme français et est fortement influencé des modèles de l’art antique : le Château Borély propose une approche de l’ornementation très équilibrée, régulière et rythmée.
Trois siècles plus tard, cette accumulation des éléments décoratifs nous paraît surabondante, excessive, presque écœurante. Nous avons trouvé intéressant de rendre compte de ce ressentit dans notre production. En effet, si le motif a traversé les âges, sa stylistique et son usage sont marqués par l’empreinte de son époque.

Quel était le motif au XVIIe ? Quel pourrait-il être aujourd’hui ?
Notre réflexion s’est construite autour de ces questionnements. La production se veut être une ouverture possible à ces vastes interrogations.

Vidéo de présentation

[petite qualité]

Photos

Ensemble des motifs extraits au sein du Château Borély

Motifs transformés par le code

Présentation du projet au Château Borély

Microédition portant sur nos recherches plastiques et textuelles ; dialectique entre artisanat et numérique.

Code

Liens des codes et des fichiers en open source :

kaleidoscope_applet_final

import processing.core.*; 
//import processing.xml.*; 

import processing.opengl.*; 
import javax.swing.filechooser.*; 
import javax.swing.*; 

import java.applet.*; 
import java.awt.*; 
import java.awt.image.*; 
import java.awt.event.*; 
import java.io.*; 
import java.net.*; 
import java.text.*; 
import java.util.*; 
import java.util.zip.*; 
import java.util.regex.*; 

/**
 * Picture Kaleidoscope (Version Applet)
 * par David Buchmann <écire à davidbu.ch>
 * Traduction et adaptation : Flora WIERZBICKI, 2016 <écrire à flora.wierzbicki@gmail.com>
 * Delphine KREIS, 2016 <écrire à delphine-kreis@hotmail.fr>
 *
 * Bouge la souris pour changer la part de l'image montrée
 *   - bouton gauche appuyé pour bouger l'image
 *   - bouton droit appuyé + bouger à droite et à gauche pour tourner
 *
 * Boutons:
 *   - r / R: accélérer/décélérer la rotation de l'image résultante
 *
 * (c) David Buchmann, 2010
 *
 * Ce programme est libre; vous pouvez le redistribuer et/ou le modifier
 * en respectant les termes du la GNU General Public License. Ce programme  
 * est ditribué dans l'espoir qu'il pourra être utile, dans le cas où il 
 * est réutilisé SANS AUCUNE GARANTIE; sans seulement l'implicite garantie  
 * d'une COMMERCIALISATION ou autre CONVENANCE ayant pour OBJECT UN QUELQUONQUE
 * BENEFICE PARTICULIER.
 * Se référer au GNU General Public License pour plus de renseignements/
 */



/** longueur du bord du rectangle utilisable en plein écran */
public static final int radius = 250;

/** montrer les messages de debug */
public static final boolean DEBUG = false;

private KeyboardController controller;

// variable globale pour la gestion du nom de l'image
String imageName;


/**
 * préparation du résultat
 */
void setup() {
    //size(1395,1415,JAVA2D); //taille de la fenêtre 
    fullScreen(); //plein écran
    frameRate(60); 
    noCursor(); //masquer le curseur
    
    controller = new KeyboardController(radius, 1, false, DEBUG); 
    //appel de la classe KeyboardController

    //charger le(s) image(s)
    imageName = "motif_6_multicolor.jpg";
    PImage i = loadImage(imageName);
    
    // chargement de l'image dans le “controller”/ gestion des erreurs s'il y un problème au niveau du chargement de l'image 
    if (i == null) throw new RuntimeException ("motif_4_fluorescent.jpg not found");
    controller.changeImage(i, "applet-can-not-save", true);
    
    // ouvir le dialogue de fichier d'image
    try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (Exception e) {
        e.printStackTrace();
    }
}

/**
 * principale boucle de dessin: dirigée directement vers le KaleidoscopeController
 */
void draw() {
    controller.draw();
}

/**
 * mouvement avant de la souris vers le KeyboardController
 */
public void mouseDragged() {
    controller.mouseDragged();
}

/**
 * gestion des touches clavier vers KaleidoscopeController 
 */
//void keyReleased() {
    //controller.keyReleased();
//}

public void keyReleased() {
    switch(key) {
        case 'o':
            new Thread () { //ne pas bloquer pas la fenêtre
                public void run() {
                chooseImage();
                }
            }.start();
            break;
            
            
            
         case ' ':  
           int i_im = (int)random(1,13); //charger aléatoirement les images de "1” à "13”
           imageName = "motif_" + i_im + "_multicolor.jpg";
           
           //text(imageName,100,100);
           
           PImage i = loadImage(imageName);
            //chargement de l'image dans le “controller”/gestion des erreurs s'il y a un problème
            if (i == null) throw new RuntimeException ("motif_4_fluorescent.jpg not found");
            controller.changeImage(i, "applet-can-not-save", true);
    
             // ouvir le dialogue de fichier d'image
              try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (Exception e) {
                e.printStackTrace();
            }
           
        default:
            controller.keyReleased();
            break;
    }
}

/**
 * afficher le sélecteur de fichier et charger une nouvelle image si image sélectionnée
 */
private void chooseImage() {
    JFileChooser fc = new JFileChooser();
    if (JFileChooser.APPROVE_OPTION == fc.showOpenDialog(null)) {
        File f = fc.getSelectedFile();
        controller.changeImage(loadImage(f.getPath()), f.getName(), true);
    }
}

Kaleidoscope

/**
 * Picture Kaleidoscope
 * par David Buchmann <mail at davidbu.ch>
 * Traduction et adaptation : Flora WIERZBICKI, 2016 <écrire à flora.wierzbicki@gmail.com>
 *
 * The Kaleidoscope class
 *
 * Cette classe s'affiche avec une taille et un nombre de segments.
 * Elle permet de mettre en tampon les fichiers que vous voulez kaléidoscoper.
 *
 * Peu importe, vous mettez à jour le tampon (usuellement dans votre cicle draw principal)
 * vous appelez “Kaleidoscope.draw” pour dessiner le nouveau kaléidoscope.
 * Le paramètre de rotation peut être utilisé pour permettre de tourner
 * de manière circulaire l'image résultante.
 *
 * (c) David Buchmann, 2010
 *
 * Ce programme est libre; vous pouvez le redistribuer et/ou le modifier
 * en respectant les termes du la GNU General Public License. Ce programme  
 * est ditribué dans l'espoir qu'il pourra être utile, dans le cas où il 
 * est réutilisé SANS AUCUNE GARANTIE; sans seulement l'implicite garantie  
 * d'une COMMERCIALISATION ou autre CONVENANCE ayant pour OBJECT UN QUELQUONQUE
 * BENEFICE PARTICULIER.
 * Se référer au GNU General Public License pour plus de renseignements/
 */
 
class Kaleidoscope {
    /** segments du kaléidoscope */
    int segments;
    /** radius du kaléidscope en pixels */
    int radius;
    /** hauteur du cache, calculé à partir du radius et du nombres de segments */
    int bufferheight;
    /** pas de rotation pour les segments, basé sur le nombre de segments */
    float angle;

    /** le cache pour “getBuffer”, dans la taille standard des bufferheight usuels */
    PGraphics buffer;
    /** masquer l'image et remplir le cache pour obtenir une “part de tarte” */
    PGraphics triangle_mask;

    /**
     * Instancier le Kaleidoscope
     *
     * @param le nombre de segments par part. la moitié de ceux qui vont être miroités
     * @param radius du kaléidoscope
     */
    public Kaleidoscope(int segments, int radius) {
        this.segments = segments;
        this.radius = radius;
        angle = TWO_PI/segments;
        bufferheight = Math.round(sin(angle+0.02)*radius)+1;
        buffer = createGraphics(radius,bufferheight);
//        buffer.background(0);
        triangle_mask = createGraphics(radius,bufferheight);
/*        triangle_mask.beginDraw();
        triangle_mask.background(color(0));
        triangle_mask.stroke(color(255));
        triangle_mask.arc(0,0,radius*2,radius*2,0,angle+0.02); //ellipse with center 0,0 and width and height of 2*radius. part angle of that, with an additional 0.02 to avoid black gaps
        triangle_mask.endDraw();
        */
    }

    /**
     * Sélectionne une image-cache pour l'utiliser avec le kaléidoscope
     * L'utilise comme un paramètre pour dessiner, pour s'assurer que vous avez 
     * la bonne taille de cache et la performance optimale.
     */
    public PGraphics getBuffer() {
        return buffer;
    }

    /**
     * Dessinez l'image inclinée et miroitée autour du centre
     * 
     * L'image est masquée pour obtenir une “part de tarte”
     *
     * @param img Devrait retourner l'objet par {@link getBuffer}. Même si ce n'est pas le cas, elles doivent avoir exactement les mêmes dimensions.
     * @param rotation Angle permettant la rotation du kaléidoscope (en radians)
     */
    public synchronized void draw(PImage img, float rotation) {
        triangle_mask.beginDraw();
        triangle_mask.background(color(0));
        triangle_mask.stroke(color(255));
        triangle_mask.arc(0,0,radius*2,radius*2,0,angle+0.02); //ellipse ayant pour centre 0,0 et de largeur et d'hauteur 2*radius
        triangle_mask.endDraw();
        img.mask(triangle_mask);
        //image(img, 0, 0, 400, 161); //si (true) retour;
        
        //segments réguliers
        for (int i=0; i<segments/2; i++) {
            pushMatrix();
            //rotate around center
            translate(radius,radius);
            rotate(rotation);
            rotate(i*angle*2);
            translate(-radius,-radius); //attention : garde l'origine intacte
            //dessiner l'image avec le plus haut coin de gauche au centre
            image(img,radius,radius);
            popMatrix();
        }
        //segments miroités

        for (int i=0; i<segments/2; i++) {
            pushMatrix();
            //miroirs sur l'axe x. (le miroitement inverse toutes les valeurs suivantes de cet axe)
            scale(-1,1);
            //tourne autour du centre
            translate(-radius,radius);
            rotate(-rotation);
            rotate(-PI); //commence directement par l'adjacent des segments non miroités
            rotate(i*angle*2);
            translate(radius,-radius); //attention : garde l'origine intacte
            //dessiner l'image du plus haut coin de gauche au centre
            image(img,-radius,radius);
            popMatrix();
        }

    }
}

KaleidoscopeController

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Picture Kaleidoscope
 * par David Buchmann <mail at davidbu.ch>
 * Traduction et adaptation : Flora WIERZBICKI, 2016 <écrire à flora.wierzbicki@gmail.com>
 *
 * Controlleur pour contrôler les mouvements de la souris et les caractères.
 *
 * Directement le dessin, mouseDragged et KeyReleased s'acctionnent dans cette classe
 * Mise à jour de l'image courrante avec la méthode “changeimage”.
 * 
 *
 * Pour utiliser avec avec des modules assynchrones comme tuio, il faut synchroniser la plupart des méthodes. 
 *
 * (c) David Buchmann, 2010
 *
 * Ce programme est libre; vous pouvez le redistribuer et/ou le modifier
 * en respectant les termes du la GNU General Public License. Ce programme  
 * est ditribué dans l'espoir qu'il pourra être utile, dans le cas où il 
 * est réutilisé SANS AUCUNE GARANTIE; sans seulement l'implicite garantie  
 * d'une COMMERCIALISATION ou autre CONVENANCE ayant pour OBJECT UN QUELQUONQUE
 * BENEFICE PARTICULIER.
 * Se référer au GNU General Public License pour plus de renseignements/
 */
 
class KaleidoscopeController {
    /** montrer les messages de debug */
    private boolean DEBUG;
    
    private boolean snapshot = false, pushed = false; 

    /** contrôle du bouton 'r' et 'R' accélérant/décélérant la vitesse de rotation */
    private static final float ROTATE_INCREMENT = 0.005;

    /** facteur permettant d'aggrandir le kaléidoscope pour l'enregistrer en meilleure résolution */
    private int scalefactor; // > ne marche pas en mode plein écran

    /** radius du cercle s'affichant à l'écran */
    private int screenradius;

    /** rotation de l'intégralité du dessin */
    private float baserotate;
    /** augmentation de la rotation */
    private float rotateKal = 0;

    //les variables H sont exploitées lorsque l'on enregistre avec avec un facteur d'échelle > 1
    /** cache contenant l'image de base à dessiner*/
    private PImage img, imgH;
    /** dessin hors champ, dessine l'image avec “translate” et “rotate”, applique un masque pour obtenir une jolie “part de tarte” */
    private PGraphics graph, graphH;
    /** exemple de kaléidoscope à dessiner */
    private Kaleidoscope kaleidoscope, kaleidoscopeH;

    /** changer le morceau d'image visible: x, y bouger, z rotation */
    private PVector drag = new PVector(0,0,0);;
    /** dernière position, pour vérifier que le graphique a besoin d'être redessiné */
    private PVector lastDrag = new PVector(1,1,1); //contenu initial ignoré, doit être différent du dessin précédent 
    /** utilisé pour un mouvement régulier. le dernier dessin utilise une part de la dernière vitesse et change l'accélération basé sur le mouvement de la souris */
    private PVector lastd = new PVector(0,0,0);
    
    /** au cas où le dessin a besoin d'être raffraîchit */
    private boolean refresh = false;

    /** nom de fichier courant, à utiliser pour capture d'écran */
    private String imagename;


    /** statistiques/debug */
    float now=0;
    PFont font;

    /**
     * Create this controller.
     *
     * @param screenradius le radius du kaléidoscope à l'écran
     * @param scalefactor pour mettre en meilleure résolution les captures d'écran
     * @param debug pour afficher les informations de debug
     */
    public KaleidoscopeController(int screenradius, int scalefactor, boolean debug) {
        this.screenradius = screenradius;
        this.scalefactor = scalefactor;
        this.DEBUG = debug;

        //kaleidoscope = new Kaleidoscope(16, screenradius);
        kaleidoscope = new Kaleidoscope(16, 100);
        graph = kaleidoscope.getBuffer();
        if (scalefactor != 1) {
            kaleidoscopeH = new Kaleidoscope(16, screenradius*scalefactor);
            graphH = kaleidoscopeH.getBuffer();
        }
        if(DEBUG) {
            font = loadFont("Arab-24.vlw");
        }
    }

    /**
     * prendre le cache du kaleidoscope pour dessiner directement dessus
     */
    public synchronized PGraphics getBuffer() {
      return kaleidoscope.getBuffer();
    }
    public Kaleidoscope getKaleidoscope() {
      return kaleidoscope;
    }

    /**
     * changer l'image 
     *
     * @param i la nouvelle image, le nouveau fichier à charger
     * @param name le nom de l'image à utiliser lorsque l'on enregistre les captures d'écran
     */
    public synchronized void changeImage(PImage i, String name, boolean reset) {
        try {
            //img = (PImage) i.clone();
            
            img = i.copy();
            
            img.resize(Math.round(screenradius*1.5),0);

            if (scalefactor != 1) {
                imgH = (PImage) i.clone();
                //imgH = i.copy();
                imgH.resize(Math.round(screenradius*scalefactor*1.5),0);
            }

            imagename = name;
            
            refresh = true;

            if (reset) {
            //réinitialisation du mouvement
            drag.x = 0;
            drag.y = 0;
            drag.z = 0;
            lastDrag.x = 0;
            lastDrag.y = 0;
            lastDrag.z = 0;
            }
        } catch(CloneNotSupportedException e) {
            //ignorer
        }
    }

    /**
     * dessiner la boucle
     */
    public synchronized void draw() {
        if (snapshot) return;
        pushMatrix();
        pushed = true;
        background(0);
        
        /// debug
        if (DEBUG) {
            float t = millis();
            if (t > now+1000) {
                println("fps "+Math.round(frameRate));
                now = t;
            }
        }
        ////////// arrêter debug

        if (refresh || drag.x != lastDrag.x || drag.y != lastDrag.y || drag.z != lastDrag.z) {
            updateGraph(graph, img, 1);
            if (scalefactor != 1) {
                updateGraph(graphH, imgH, scalefactor);
            }
            lastDrag.x = drag.x;
            lastDrag.y = drag.y;
            lastDrag.z = drag.z;
        }
    
     

        if (DEBUG) {
            textFont(font, 14);
            fill(0xFFFFFFFF);
            text("fps "+Math.round(frameRate), 15, 15);
            fill(0);
            text("fps "+Math.round(frameRate), 15, 30);
        }
        if (! snapshot) popMatrix();
        pushed = false;
    }

    public synchronized void move(int dx, int dy) {
            lastd.x = dx * 0.1 + lastd.x * 0.9;
            lastd.y = dy * 0.1 + lastd.y * 0.9;
            drag.x += lastd.x;
            drag.y += lastd.y;
            if (drag.x > graph.width) drag.x = graph.width;
            if (drag.x < -img.width) drag.x = -img.width;
            if (drag.y > graph.height) drag.y = graph.height;
            if (drag.y < -img.height) drag.y = -img.height;      
    }

    /** augmentation de la rotation par r */
    public synchronized void rotateIncrement(float r) {
      drag.z += r;
    }

    /** ensemble des rotations assignées à r */
    public synchronized void rotate(float r) {
      drag.z = r;
    }
    
    /** ensemble des positions assignées à -1 jusqu'à 1 */
    public synchronized void setPositionFraction(float x, float y) {
        if (x < -1 || x > 1 || y < -1 || y > 1) return;
        drag.x = graph.width * x;
        drag.y = graph.height * y;
    }
    
    /**
     * mettre à jour le cache sur l'image dans son actuelle position
     *
     * appellée via la principale boucle de dessin
     *
     * @param i l'image à dessiner sur le cache
     * @param m facteur de mise à l'échelle relatif au screenradius
     */
     
     
    private synchronized void updateGraph(PGraphics graph, PImage i, int m) {
        
      
        graph.beginDraw();
        
        // 1ère image 
        graph.translate(drag.x*m,drag.y*m);
        //graph.translate(m*screenradius/2,m*screenradius/2);
        graph.translate(m*0,m*0);
        graph.rotate(drag.z);
        //graph.translate(-m*screenradius/2,-m*screenradius/2);
        ///////////////////////////////////////////////////////////////////////////////////////////////////
        graph.image(i,0,0); // affiche l'image correspondant à....
        
          //placer sur 1ère ligne, en 1er en partant de la gauche
       //int shiftx = (width - height)/2;
       //if (scalefactor > 1) shiftx += (displayWidth-displayHeight)/2;
        translate(50,50);
        baserotate += rotateKal;
        baserotate %=  TWO_PI;
        kaleidoscope.draw(graph,baserotate);
        
        // 2ème image 
        graph.translate(drag.x*m,drag.y*m);
        graph.translate(m*screenradius/2,m*screenradius/2);
        graph.rotate(drag.z);
        graph.translate(-m*screenradius/2,-m*screenradius/2);
        ///////////////////////////////////////////////////////////////////////////////////////////////////
        graph.image(i,540,540); // affiche l'image correspondant à....
        
          //placer sur 1ère ligne, en 2ème en partant de la gauche
       //int shiftx = (465 - 0)/2;
       //if (scalefactor > 1) shiftx += (displayWidth-displayHeight)/2;
       translate(375,0);
        baserotate += rotateKal;
        baserotate %=  TWO_PI;
        kaleidoscope.draw(graph,baserotate);
        
        // 3ème image
        graph.translate(drag.x*m,drag.y*m);
        graph.translate(m*screenradius/2,m*screenradius/2);
        graph.rotate(drag.z);
        graph.translate(-m*screenradius/2,-m*screenradius/2);
        ///////////////////////////////////////////////////////////////////////////////////////////////////
        graph.image(i,540,540); // affiche l'image correspondant à....
        
          //placer sur 1ère ligne, en 3ème en partant de la gauche
       //int shiftx = (465 - 0)/2;
       //if (scalefactor > 1) shiftx += (displayWidth-displayHeight)/2;
       translate(375,0);
        baserotate += rotateKal;
        baserotate %=  TWO_PI;
        kaleidoscope.draw(graph,baserotate);
        
        // 4ème image
        graph.translate(drag.x*m,drag.y*m);
        graph.translate(m*screenradius/2,m*screenradius/2);
        graph.rotate(drag.z);
        graph.translate(-m*screenradius/2,-m*screenradius/2);
        ///////////////////////////////////////////////////////////////////////////////////////////////////
        graph.image(i,540,540); // affiche l'image correspondant à....
        
          //placer sur 1ère ligne, en 4ème en partant de la gauche
       //int shiftx = (465 - 0)/2;
       //if (scalefactor > 1) shiftx += (displayWidth-displayHeight)/2;
       translate(375,0);
        baserotate += rotateKal;
        baserotate %=  TWO_PI;
        kaleidoscope.draw(graph,baserotate);
        
      
        
         // 5ème image
        graph.translate(drag.x*m,drag.y*m);
        graph.translate(m*screenradius/2,m*screenradius/2);
        graph.rotate(drag.z);
        graph.translate(-m*screenradius/2,-m*screenradius/2);
        ///////////////////////////////////////////////////////////////////////////////////////////////////
        graph.image(i,540,540); // affiche l'image correspondant à....
        
          //placer sur 2nde ligne, en 1er en partant de la droite
       //int shiftx = (465 - 0)/2;
       //if (scalefactor > 1) shiftx += (displayWidth-displayHeight)/2;
       translate(0,300);
        baserotate += rotateKal;
        baserotate %=  TWO_PI;
        kaleidoscope.draw(graph,baserotate);
        
         // 6ème image
          graph.translate(drag.x*m,drag.y*m);
        //graph.translate(m*screenradius/2,m*screenradius/2);
        graph.translate(m*0,m*0);
        graph.rotate(drag.z);
        //graph.translate(-m*screenradius/2,-m*screenradius/2);
        ///////////////////////////////////////////////////////////////////////////////////////////////////
        graph.image(i,540,540); // affiche l'image correspondant à....
        
          //placer sur 2nde ligne, en 2ème en partant de la droite
       //int shiftx = (width - height)/2;
       //if (scalefactor > 1) shiftx += (displayWidth-displayHeight)/2;
        translate(-375,0);
        baserotate += rotateKal;
        baserotate %=  TWO_PI;
        kaleidoscope.draw(graph,baserotate);
        
        // 7ème image
          graph.translate(drag.x*m,drag.y*m);
        //graph.translate(m*screenradius/2,m*screenradius/2);
        graph.translate(m*0,m*0);
        graph.rotate(drag.z);
        //graph.translate(-m*screenradius/2,-m*screenradius/2);
        ///////////////////////////////////////////////////////////////////////////////////////////////////
        graph.image(i,540,540); // affiche l'image correspondant à....
        
          //placer sur 2nde ligne, en 3ème en partant de la droite
       //int shiftx = (width - height)/2;
       //if (scalefactor > 1) shiftx += (displayWidth-displayHeight)/2;
        translate(-375,0);
        baserotate += rotateKal;
        baserotate %=  TWO_PI;
        kaleidoscope.draw(graph,baserotate);
        
        // 8ème image
          graph.translate(drag.x*m,drag.y*m);
        //graph.translate(m*screenradius/2,m*screenradius/2);
        graph.translate(m*0,m*0);
        graph.rotate(drag.z);
        //graph.translate(-m*screenradius/2,-m*screenradius/2);
        ///////////////////////////////////////////////////////////////////////////////////////////////////
        graph.image(i,540,540); // affiche l'image correspondant à....
        
          //placer sur 2nde ligne, en 4ème en partant de la droite
       //int shiftx = (width - height)/2;
       //if (scalefactor > 1) shiftx += (displayWidth-displayHeight)/2;
        translate(-375,0);
        baserotate += rotateKal;
        baserotate %=  TWO_PI;
        kaleidoscope.draw(graph,baserotate);
        
         // 9ème image
        graph.translate(drag.x*m,drag.y*m);
        graph.translate(m*screenradius/2,m*screenradius/2);
        graph.rotate(drag.z);
        graph.translate(-m*screenradius/2,-m*screenradius/2);
        ///////////////////////////////////////////////////////////////////////////////////////////////////
        graph.image(i,540,540); // affiche l'image correspondant à....
        
          //placer sur 3ème ligne, en 1er en partant de la gauche
       //int shiftx = (465 - 0)/2;
       //if (scalefactor > 1) shiftx += (displayWidth-displayHeight)/2;
       translate(0,300);
        baserotate += rotateKal;
        baserotate %=  TWO_PI;
        kaleidoscope.draw(graph,baserotate);
        
        // 10ème image
        graph.translate(drag.x*m,drag.y*m);
        graph.translate(m*screenradius/2,m*screenradius/2);
        graph.rotate(drag.z);
        graph.translate(-m*screenradius/2,-m*screenradius/2);
        ///////////////////////////////////////////////////////////////////////////////////////////////////
        graph.image(i,540,540); // affiche l'image correspondant à....
        
          //placer sur 3ème ligne, en 2ème en partant de la gauche
       //int shiftx = (465 - 0)/2;
       //if (scalefactor > 1) shiftx += (displayWidth-displayHeight)/2;
       translate(375,0);
        baserotate += rotateKal;
        baserotate %=  TWO_PI;
        kaleidoscope.draw(graph,baserotate);
        
         // 11ème image
        graph.translate(drag.x*m,drag.y*m);
        graph.translate(m*screenradius/2,m*screenradius/2);
        graph.rotate(drag.z);
        graph.translate(-m*screenradius/2,-m*screenradius/2);
        ///////////////////////////////////////////////////////////////////////////////////////////////////
        graph.image(i,540,540); // affiche l'image correspondant à....
        
          //placer sur 3ème ligne, en 3ème en partant de la gauche
       //int shiftx = (465 - 0)/2;
       //if (scalefactor > 1) shiftx += (displayWidth-displayHeight)/2;
       translate(375,0);
        baserotate += rotateKal;
        baserotate %=  TWO_PI;
        kaleidoscope.draw(graph,baserotate);
        
         // 12ème image
        graph.translate(drag.x*m,drag.y*m);
        graph.translate(m*screenradius/2,m*screenradius/2);
        graph.rotate(drag.z);
        graph.translate(-m*screenradius/2,-m*screenradius/2);
        ///////////////////////////////////////////////////////////////////////////////////////////////////
        graph.image(i,540,540); // affiche l'image correspondant à....
        
          //placer sur 3ème ligne, en 4ème en partant de la gauche
       //int shiftx = (465 - 0)/2;
       //if (scalefactor > 1) shiftx += (displayWidth-displayHeight)/2;
       translate(375,0);
        baserotate += rotateKal;
        baserotate %=  TWO_PI;
        kaleidoscope.draw(graph,baserotate);
        
        graph.endDraw();
    }

    public void increaseRotate() {
        rotateKal += ROTATE_INCREMENT;      
    }
    public void decreaseRotate() {
        rotateKal -= ROTATE_INCREMENT;
    }

    /**
     * Changer le nombre d'axes du kaléidoscope
     *
     * Va créer un nouvelle instance de Kaleidoscope et un nouveau cache pour la “part de tarte”
     *
     * @param segments le nombre de segments à utiliser
     */
    public synchronized void setSegmentNumber(int segments) {
        PGraphics oldg = graph;
        kaleidoscope = new Kaleidoscope(segments, screenradius);
        graph = kaleidoscope.getBuffer();
        graph.image(oldg,0,0);

        if (scalefactor != 1) {
            oldg = graphH;
            kaleidoscopeH = new Kaleidoscope(segments, screenradius*scalefactor);
            graphH = kaleidoscopeH.getBuffer();
            graphH.image(oldg,0,0);
        }

        lastDrag.x += 0.0001; //déclancher le “redraw”
    }

    /**
     * Enregistrer une image de l'écran actuel (après avoir appuyé sur le “s”)
     *
     * Le nom du fichier comprend le kaléidoscope, l'actuelle estampe et nom de fichier 
     * pour éviter d'écraser des fichiers existants
     *
     * Si le paramètre de mise à échelle est plus grand que 1, le kaleidoscopeH est dessiné et enregistré
     * à la place de l'écran actuel
     */
    public synchronized void saveSnapshot() {
        snapshot = true;
        if (pushed) popMatrix();
        if (scalefactor != 1)  {
            background(0);
            //center the screen
            translate((width - height)/2,0);

            kaleidoscopeH.draw(graphH, baserotate);
        }
        DateFormat f = new SimpleDateFormat("'kaleidoscope_"+imagename+"_'yyyy-MM-dd_HH-mm-ss'.png'");
        String imgfile = f.format(new Date());
        try {
            save("/home/david/" + imgfile);
        } catch(RuntimeException t) {
            t.printStackTrace();
            println("Failed to save current state to "+imgfile);
        }
        snapshot = false;
    }
}

KeyboardController

class KeyboardController extends KaleidoscopeController {

    private boolean canSave;
   
   public KeyboardController(int screenradius, int scalefactor, boolean canSave, boolean debug) { 
       super(screenradius, scalefactor, debug);
       this.canSave = canSave;
   }
   
    /**
     * actions sur touches du clavier (chiffres, r, R, s, o)
     */
    public void keyReleased() {
        switch(key) {
            case '0':
            case '1':
            case '2':
                setSegmentNumber((Integer.parseInt(key+"")+10)*2);
                break;
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
                setSegmentNumber(Integer.parseInt(key+"")*2);
                break;
            case 'r':
                increaseRotate();
                break;
            case 'R':
                decreaseRotate();
                break;
            case 's':
                if (canSave) {
                    saveSnapshot();
                }
                break;
    
            default:
                //unknown key
                break;
        }
    }
    /**
     * suit les mouvements de la souris pour mettre à jour la position de l'image
     */
    public void mouseDragged() {
        if (mouseButton == LEFT) {
            move(mouseX - pmouseX, mouseY - pmouseY);
        } else if (mouseButton == RIGHT) {
            rotateIncrement((mouseX - pmouseX) * 0.01);
        }
    }
}

Documentation

Livre disponible dans notre cafoutch en salle de DSAA. Il permet d'apporter des références et d'avoir accès à des codes en open source, que l'on peut retrouver également sur le site ci-dessus.