2. Dezember 2010
Das Zeichenmodul und die Processing-Programmierung flossen zusammen und wir haben die Permutationen zu animieren begonnen. Zuerst haben wir die Zeichen in Processing nachgezeichnet und so weit parametriesiert, dass wir verschiedene Version einfach erstellen konnten. Für den Anfang habe ich eine Permutation ausgewählt, die sehr einfach nachzubauen war. Die Zeichen bestehen nur aus Kreisen, welche ihre Grösse und Position verändern, zusätzlich dreht sich das äussere Element («Trabant») um das grosse innere Element. In der Permuation selbst ist schon eine Drehung enthalten und ich habe mittels Processing noch eine weitere Rotation integriert. Zusätzlich skalieren sich die Zeichen unterschiedlich, was zu wellenartigen Bewegungen im Gesamtbild führt. Als Experiment habe die Anzahl vervierfach, ohne die Zeichentypen zu verändern, was zu weiteren interessanten Bildern geführt hat. Um die bessere Kontrolle über die Zeichen zu erhalten, habe ich eine Zeichenklasse erstellt, dessen Objekte vom Programmcode in einer Liste gehandhabt werden. Start Umsetzung Maya-Pyramiden Das Programm habe ich so weit verändert, dass die Position der Maus Einfluss auf das Gesamtbild der Permuation nimmt. Ein Zeichenobjekt weiss seine eigene Position und berechnet die Distanz zur Mausposition. Mit diesem Wert wird dann die Skalierung, Strichdicke und/oder Rotation beeinflusst. Durch die Veränderung der Strickdicke in Abhängigkeit zur Mausdistanz entsteht ein Spotlighteffekt. Zusätzlich können sich die Zeichen noch skalieren, sodass sie in Mausnäher nach vorne treten oder zurückweichen. Durch Überlagerungen der Zeichen entstehen bei der Animation diverse interessante Moiré-Effekte und Verformungen. Die Permutation wird mehr als animierte Gesamtfläche wahrgenommen als bei der ersten Version mit den Trabanten. Als Nächstes werde ich die Verschiebung der Quadrate innerhalb der Zeichen einführen, ebenfalls abhängig von der Mausposition. In der ursprünglichen Permutation läuft das Licht von oben rechts nach unten links, in Processing sind dann nahtlose Schritte möglich. Klasse Zeichen (Maya)/** * CLASS SIGN * draws sign for permutation * @author Dominik Stucky */ class Sign { int _type; // type of sign (0-6) int _rotation; // rotation sign int _rotInc; // incrementation of rotation float _scaling; // scaling 1 = original size int _posX; // position x on grid int _posY; // position y on grid PVector _position = new PVector(); int _size = 75; // initial size of sign int _mouseX; // position mouse x int _mouseY; // position mouse y PVector _mousePos = new PVector(); float[] _scaleRange = {2.0,1.0}; // flip range float[] _strokeRange = {0.2, 10.0}; // constructor Sign(int type) { _rotation = type*30; _type = type; _rotInc = _type+1; } void setSize(int sizeIni) { _size = sizeIni; // overwrite default rotate incrementation } void setRotationInc(int rotInc) { _rotInc = rotInc; // overwrite default rotate incrementation } void setPosition(int posX, int posY) // position of sign { _posX = posX; _posY = posY; _position.set(posX,posY,0); } void setPositionMouse(int mX, int mY) // mouse position { _mouseX = mX; _mouseY = mY; _mousePos.set(mX,mY,0); } void setScaleRange(float start, float end) { _scaleRange[0] = start; _scaleRange[1] = end; } void setStrokeRange(float start, float end) { _strokeRange[0] = start; _strokeRange[1] = end; } void draw() { // how far is this sign from mouse start point PVector dir = PVector.sub(_position,_mousePos); float distance = dir.mag(); // distance in px // scaling depends on distance to mouse pointer float _scaling = map(distance,0.0,width,_scaleRange[0],_scaleRange[1]); // 2,1: inverts range -> signs nearest to mous appear the biggest // rotation speed depends on sign type _rotation+=_rotInc; // stroke width depends on distance to mouse pointer float sw = map(distance,0.0,width,_strokeRange[0],_strokeRange[1]); if (sw<0) sw*=-1; // only positive numbers allowed int b1 = _size; pushMatrix(); scale(_scaling); rotate(radians(_rotation)); pushStyle(); noFill(); stroke(0); strokeWeight(sw); for(int i=0; i<5; i++) { float w = b1-(i*b1/5); rect(-1*w/2,-1*w/2,w,w); // black circle 1 } popStyle(); popMatrix(); } }Programm Code
import megamu.shapetween.*; int anzahl = 7; int rand = 100; float xStep; float yStep; int[] permutationsIndexList = { 0, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 5, 2, 3, 4, 5, 6, 5, 4, 3, 4, 5, 6, 5, 4, 3, 4, 5, 6, 5, 4, 3, 2, 5, 6, 5, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 0 }; int numSigns = permutationsIndexList.length; Sign[] signs = new Sign[numSigns]; // holds all objects of signs Tween ani; void setup() { size(760, 760); smooth(); ani = new Tween(this, 100, Tween.FRAMES, Shaper.COSINE); ani.start(); xStep = (width - 2 * rand) / (float)(anzahl-1); yStep = (height - 2 * rand) / (float)(anzahl-1); frameRate(24); int permutationsIndex = 0; for(int y=0; y<anzahl;y++) { for(int x=0; x<anzahl;x++) { signs[permutationsIndex] = new Sign(permutationsIndexList[permutationsIndex]); ++permutationsIndex; } } } void draw() { background(ani.position()*255); int permutationsIndex = 0; pushMatrix(); translate(rand,rand); for(int y=0; y<anzahl;y++) { pushMatrix(); for(int x=0; x<anzahl;x++) { signs[permutationsIndex].setSize(75); signs[permutationsIndex].setScaleRange(0.5,4); signs[permutationsIndex].setStrokeRange(12.0, 0.1); signs[permutationsIndex].setPositionMouse(mouseX,mouseY); signs[permutationsIndex].setPosition((int)xStep*x+rand,(int)yStep*y+rand); signs[permutationsIndex].draw(); ++permutationsIndex; translate(xStep,0.0f); } popMatrix(); translate(0.0f,yStep); } popMatrix(); } void mousePressed() { // set start position /*mouseStartPos.set(mouseX,mouseY,0); mouseEndPos = mouseStartPos.get(); startPosSet=true; endPosSet=false;*/ } void keyPressed() { if (key == CODED) { if (keyCode == UP) { println("up"); // make an attribute changeable through arraw key } else if (keyCode == DOWN) { println("down"); // make an attribute changeable through arraw key } } switch(key) { case ' ': save("permutation_"+hour()+"-"+minute()+"-"+second()+".jpg"); break; } }