24. Dezember 2010
Für die Präsentation habe ich den Code überarbeitet und Zeichensets zusammengestellt, die zur gewählten Musik passen. Als Musikstück habe ich "Tuning In" von Groove Armada aus dem Album "Love Box" ausgewählt. Die Übergänge der Permutationen, sowie das Wobbling habe ich dann auf dieses Stück entsprechend angepasst. Als Start werden zwei Permutationen hin- und hergeloopt. Mittels Tasten können neue Sets hinzugefügt werden, wobei jeweils die letzten zwei Sets endlos geloopt werden. Es können auch mehrere Tasten schnell nacheinander gedrückt werden, die Sets werden dem Animations-Array hinzugefügt und dann "abgearbeitet". Am Schluss gibt es wieder einen Endlos-Loop der letzten beiden Einträge, solange bis weitere Tasten gedrückt werden. Die Leertaste schaltet zwischen einem schwarzen und weissen Hintergrund um. Drehen der Zeichen ist ebenfalls mit einer Taste möglich, mehrmaliges Drücken erhöht die Drehgeschwindigkeit. Weitere Angaben finden sich hier: 14. Erweiterungen Interaktion. Snapshots Hauptprogramm-Code// libraries import ddf.minim.*; //import ddf.minim.analysis.*; import fullscreen.*; SoftFullScreen fs; AudioPlayer song; //BeatDetect beat; //BeatListener beatL; // basic ini int backgroundColor = 255; int keyMode = 1; // toogle key values (1|-1), e.g. switch bg color // ini vars signs int numSigns = 7; Sign[] signs = new Sign[numSigns*numSigns]; // holds all objects of signs int stageMargin = 100; int stageHeight = 768; int stageWidth = 768; float xStep; float yStep; // ini appearance signs float scaleRangeTop = 0.1; // 1.0: original sign size float scaleRangeBottom = 0.2; // 1.0: original sign size float strokeRangeTop = 0.5; float strokeRangeBottom = 0.5; float heightRangeTop = 20; float heightRangeBottom = 10; float borderRadiusBlack = 0; float borderRadiusWhite = 0; int mirrorToggle = 1; // whether negative values are set to positive ones (ring) char keyParam = '1'; // used to store key to de- or increase sign parameters int signSize = 40; // default sign size // ini animation Stacks stack; // object for single data (transformation), added to array list animation stacks ArrayList animationStacks = new ArrayList(); // sets of values for animation int keyAnim = 0; // key of stack in animations arrayList int durationAnimStepDefault = 1322; // default duration of one tranformation int durationAnimStep = durationAnimStepDefault; //int durationAnimStepFast = 622; // not yet in use int animationStart = 3200; // milliseconds when animation starts playing int animationStop = 128000; // end of animation boolean animationPlaying = false; // whether animation is playing or not float signWobble = 0.1; // wobble start sequence float signWobbleKeyStack = 0.2; // wobble default signs added with key stacks float prevBorderRadiusBlack = borderRadiusBlack; float prevBorderRadiusWhite = borderRadiusWhite; float prevScaleRangeTop = scaleRangeTop; float prevScaleRangeBottom = scaleRangeBottom; float prevStrokeRangeTop = strokeRangeTop; float prevStrokeRangeBottom = strokeRangeBottom; float prevHeightRangeTop = heightRangeTop; float prevHeightRangeBottom = heightRangeBottom; float prevSignwobble = signWobble; int prevMirrorToggle = mirrorToggle; int animationPrevTimeLimit=0; int timerStack=0; int idleCompleted=0; int currentStack=0; int stackHolder=1; Stacks nextStack; // key pressed = stack replaced in animation list ArrayList nextStacks = new ArrayList(); // filled in with sign placed on keys, added one by one to animation list boolean signIncRotation = false; // signs rotate 360 deg in specific time, this increases duration stepwise int animEndCircleRad = 0; // radius growing circle at end of animation void setup() { // basic setup size(stageWidth, stageHeight); smooth(); // anitaliasing noCursor(); // hide mouse cursor frameRate(24); // steps s/y between signs xStep = (width - 2 * stageMargin) / (float)(numSigns-1); yStep = (height - 2 * stageMargin) / (float)(numSigns-1); // sound Minim minim = new Minim(this); song = minim.loadFile("Tuning_Short.mp3", 1024); song.play(); //beat = new BeatDetect(song.bufferSize(), song.sampleRate()); //beat.setSensitivity(30); //beatL = new BeatListener(beat, song); // use this to get audio input via microphone //in = minim.getLineIn(Minim.STEREO, 512); // fullscreen fs = new SoftFullScreen(this); // add (... ,1) to display on second display //fs.setShortcutsEnabled(true); // enable shortcut (cmd f) fs.enter(); // create sign objects int signIndex = 0; for(int y=0; y<numSigns;y++) { for(int x=0; x<numSigns;x++) { signs[signIndex] = new Sign(signIndex); ++signIndex; } } // transformations stack = new Stacks(keyAnim); stack.setDuration(0); stack._completed = true; animationStacks.add(stack); // starter set stacks keyAnim++; stack = new Stacks(keyAnim); stack.setName("best flower"); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(74); stack.setBorderRadiusWhite(68); stack.setHeightRange(0, 10); stack.setScaleRange(2.1, 0.9); stack.setStrokeRange(0.5, 6.5); animationStacks.add(stack); keyAnim++; stack = new Stacks(keyAnim); stack.doWobble(signWobble); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(2.1); stack.setBorderRadiusWhite(2.0); stack.setHeightRange(0, 10); stack.setScaleRange(1.0, 2.0); stack.setStrokeRange(0.5, 6.5); animationStacks.add(stack); } void draw() { // basic setting background(backgroundColor); // cursor index pushStyle(); int cursorIndexColor = (backgroundColor==255) ? 0 : 255; noStroke(); fill(cursorIndexColor); rect(mouseX,0,5,5); rect(0,mouseY,5,5); popStyle(); // animation setting transformation values animation(); // draw signs int signIndex = 0; for(int y=0; y<numSigns;y++) { for(int x=0; x<numSigns;x++) { //Animation anim = new Animation(signs[signIndex]); signs[signIndex].setMirrorToggle(mirrorToggle); signs[signIndex].doWobble(signWobble); signs[signIndex].doRotate(signIncRotation); signs[signIndex].setSize(signSize); // initial size signs[signIndex].setScaleRange(scaleRangeBottom,scaleRangeTop); signs[signIndex].setStrokeRange(strokeRangeBottom,strokeRangeTop); signs[signIndex].setHeightRange(heightRangeBottom,heightRangeTop); signs[signIndex].setBorderRadiusBlack(borderRadiusBlack); // radius black layers signs[signIndex].setBorderRadiusWhite(borderRadiusWhite); // radius white layers signs[signIndex].setPositionMouse(mouseX,mouseY); // store mouse position signs[signIndex].setPosition((int)xStep*x+stageMargin,(int)yStep*y+stageMargin); // set position sign signs[signIndex].draw(); ++signIndex; } } // animation //beat = new BeatDetect(); if (song.position()>animationStop) { // growing circle at end of animation, overlays sign transformations pushStyle(); fill(0); noStroke(); ellipseMode(CENTER); if (animEndCircleRad<width) animEndCircleRad+=10; ellipse(width/2,height/2,animEndCircleRad*2,animEndCircleRad*2); popStyle(); } else if (song.position()>animationStart) { animationPlay(false); // start animation after intro } if (signIncRotation==true) signIncRotation = false; // reset rotation increase (button once pushed inceares rotatoin duration) } void keyPressed() { if (key == CODED) { // @DEPRECATED numeric keys used to change parameters of signs with arrow keys /**if (keyCode == UP) { keyMode = 1; } else if (keyCode == DOWN) { keyMode = -1; } // USED FOR CREATING SIGNS // added here key passed with ... to de- or increase values with arrow keys switch(keyParam) { // numeric keys case '2': //println("scale range top"); scaleRangeTop+=0.1*keyMode; println("fast"); break; case '1': scaleRangeBottom+=0.1*keyMode; break; case '4': strokeRangeTop+=0.5*keyMode; break; case '3': strokeRangeBottom+=0.5*keyMode; break; case '6': heightRangeTop+=0.5*keyMode; break; case '5': heightRangeBottom+=1*keyMode; break; case '7': borderRadiusBlack+=1*keyMode; break; case '8': borderRadiusWhite+=1*keyMode; break; case '9': mirrorToggle = 1*keyMode; break; }*/ } else { switch(key) { case '0': // save screenshot save("screens/permutation_"+hour()+"-"+minute()+"-"+second()+".jpg"); break; case ' ': backgroundColor = (backgroundColor==255) ? 0 : 255; break; // alphabetic keys case 'x': signIncRotation = true; break; case 'q': stack = new Stacks(stackHolder); stack.setName("default hell wölbung nach vorne"); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(2.0); stack.setBorderRadiusWhite(2.0); stack.setHeightRange(9, 14); stack.setScaleRange(2.2, -1.3); stack.setStrokeRange(0.5, 0.5); stack.doWobble(signWobbleKeyStack); nextStack = stack; nextStacks.add(stack); break; case 'w': stack = new Stacks(stackHolder); stack.setName("kristall an faden"); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(27.0); stack.setBorderRadiusWhite(32.0); stack.setHeightRange(10, 20); stack.setScaleRange(2.9, -0.3); stack.setStrokeRange(2.0, 2.0); stack.doWobble(signWobbleKeyStack); nextStack = stack; nextStacks.add(stack); break; case 'e': stack = new Stacks(stackHolder); stack.setName("quadrate spitz flach"); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(-26.0); stack.setBorderRadiusWhite(-20.0); stack.setHeightRange(0, 27); stack.setScaleRange(1.9, 0.2); stack.setStrokeRange(0.5, 14.5); stack.doWobble(signWobbleKeyStack); nextStack = stack; nextStacks.add(stack); break; case 'r': stack = new Stacks(stackHolder); stack.setDuration(durationAnimStep); stack.setName("spitzen hell netzstruktur"); stack.setBorderRadiusBlack(27.0); stack.setBorderRadiusWhite(24.0); stack.setHeightRange(10, 20); stack.setScaleRange(2.6, -1.8); stack.setStrokeRange(2.0, 2.0); stack.doWobble(signWobbleKeyStack); nextStack = stack; nextStacks.add(stack); break; case 't': stack = new Stacks(stackHolder); stack.setName("3d height multiple bounces"); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(-271.0); stack.setBorderRadiusWhite(104.0); stack.setHeightRange(0, -6.0); stack.setScaleRange(0.2, 0.18); stack.setStrokeRange(2.0, 2.0); stack.doWobble(0); nextStack = stack; nextStacks.add(stack); break; case 'z': stack = new Stacks(stackHolder); stack.setName("blume zentral hell / dunkel floral"); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(-227.0); stack.setBorderRadiusWhite(321.0); stack.setHeightRange(10, 20); stack.setScaleRange(0.8, -5.0); stack.setStrokeRange(2.0, 2.0); stack.doWobble(0); stack.setMirrorToggle(-1); // mirrorToggle nextStack = stack; nextStacks.add(stack); break; case 'u': stack = new Stacks(stackHolder); stack.setName("kacheln fett"); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(-12.0); stack.setBorderRadiusWhite(-33.0); stack.setHeightRange(0.25, 8.9); stack.setScaleRange(2.3, 2.3); stack.setStrokeRange(-9.0, -9.0); stack.doWobble(signWobbleKeyStack); nextStack = stack; nextStacks.add(stack); break; case 'a': stack = new Stacks(stackHolder); stack.setName("best flower"); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(59); stack.setBorderRadiusWhite(54); stack.setHeightRange(9.8,50); stack.setScaleRange(2.1, 0.9); stack.setStrokeRange(1.1, 1.1); stack.doWobble(signWobbleKeyStack); nextStack = stack; nextStacks.add(stack); break; case 's': stack = new Stacks(stackHolder); stack.setName("best flower"); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(11.0); stack.setBorderRadiusWhite(10.0); stack.setHeightRange(0.25, 8.9); stack.setScaleRange(2.3, 2.3); stack.setStrokeRange(-9.5, -9.5); stack.doWobble(signWobbleKeyStack); nextStacks.add(stack); break; case 'd': stack = new Stacks(stackHolder); stack.setName("scheiben dunkel flach 3d"); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(11.0); stack.setBorderRadiusWhite(10.0); stack.setHeightRange(0, 52); stack.setScaleRange(2.3, 2.3); stack.setStrokeRange(2.6, 18.1); stack.doWobble(signWobbleKeyStack); nextStacks.add(stack); break; case 'f': stack = new Stacks(stackHolder); stack.setName("scheiben dunkel flach 3d"); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(20.0); stack.setBorderRadiusWhite(-3.0); stack.setHeightRange(-5, 40); stack.setScaleRange(2.3, 2.4); stack.setStrokeRange(0.5, 26); stack.doWobble(signWobbleKeyStack); nextStacks.add(stack); break; case 'g': stack = new Stacks(stackHolder); stack.setName("scheiben dunkel flach"); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(11.0); stack.setBorderRadiusWhite(10.0); stack.setHeightRange(0.25, 8.9); stack.setScaleRange(2.3, 2.3); stack.setStrokeRange(9.5, 9.5); stack.doWobble(signWobbleKeyStack); nextStacks.add(stack); break; case 'h': stack = new Stacks(stackHolder); stack.setName("weisse scheiben (schwarzer hintergrund)"); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(39.0); stack.setBorderRadiusWhite(195.0); stack.setHeightRange(10.8, 18.1); stack.setScaleRange(0.2, 0.18); stack.setStrokeRange(2.0, 2.0); stack.doWobble(signWobbleKeyStack); nextStacks.add(stack); break; case 'j': stack = new Stacks(stackHolder); stack.setName("hal eye"); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(-7.0); stack.setBorderRadiusWhite(28.0); stack.setHeightRange(27, 31); stack.setScaleRange(2.3, 2.4); stack.setStrokeRange(0.5, 26); stack.doWobble(signWobbleKeyStack); nextStacks.add(stack); break; default: // used for numeric keys to de- increase sign parameters keyParam = key; break; } } } // start animation // once called after start delay // stacks are resetted to start void animationPlay(boolean force) { if (animationPlaying==false || force==true) { animationPlaying = true; for(int i=0; i<animationStacks.size(); i++) { if (i>0) { Stacks stack = (Stacks)animationStacks.get(i); stack._completed=false; // reset animationPrevTimeLimit = millis(); timerStack = 0; } } } } // toggle where to add signs added by keys // if sign added by key -> is being displayed after completion of current transformation void switchStackHolder() { stackHolder = stackHolder==1 ? 2 : 1; } void animation() { // animation int timerStack = millis() - animationPrevTimeLimit; for(int i=0; i<animationStacks.size(); i++) // loop second to third entry { if (i>0 && idleCompleted==0) { // i==0 first entry omitted (idle screen before start) Stacks stack = (Stacks)animationStacks.get(i); Stacks stackPrev = (Stacks)animationStacks.get(i-1); if (((stackPrev._completed==true && stack._completed==false)) && timerStack < stack._duration) { // single tranformation, evaluate transformation values (previous sign to current) borderRadiusBlack = ((stack._borderRadiusBlack - prevBorderRadiusBlack) * timerStack / stack._duration) + prevBorderRadiusBlack; borderRadiusWhite = ((stack._borderRadiusWhite - prevBorderRadiusWhite) * timerStack / stack._duration) + prevBorderRadiusWhite; scaleRangeBottom = ((stack._scaleRangeBottom - prevScaleRangeBottom) * timerStack / stack._duration) + prevScaleRangeBottom; scaleRangeTop = ((stack._scaleRangeTop - prevScaleRangeTop) * timerStack / stack._duration) + prevScaleRangeTop; strokeRangeBottom = ((stack._strokeRangeBottom - prevStrokeRangeBottom) * timerStack / stack._duration) + prevStrokeRangeBottom; strokeRangeTop = ((stack._strokeRangeTop - prevStrokeRangeTop) * timerStack / stack._duration) + prevStrokeRangeTop; heightRangeBottom = ((stack._heightRangeBottom - prevHeightRangeBottom) * timerStack / stack._duration) + prevHeightRangeBottom; heightRangeTop = ((stack._heightRangeTop - prevHeightRangeTop) * timerStack / stack._duration) + prevHeightRangeTop; signWobble = ((stack._signwobble - prevSignwobble) * timerStack / stack._duration) + prevSignwobble; mirrorToggle = stack._mirrorToggle; if (prevMirrorToggle==-1) mirrorToggle = -1; // keep mirror toggle deactivated to prevent gap in animation } else if (stack._completed==false && timerStack > stack._duration) { // single transformation completed stack._completed = true; // store values of this sign to transform to next one prevBorderRadiusBlack = borderRadiusBlack = stack._borderRadiusBlack; prevBorderRadiusWhite = borderRadiusWhite = stack._borderRadiusWhite; prevScaleRangeBottom = scaleRangeBottom = stack._scaleRangeBottom; prevScaleRangeTop = scaleRangeTop = stack._scaleRangeTop; prevStrokeRangeBottom = stack._strokeRangeBottom; prevStrokeRangeTop = stack._strokeRangeTop; prevHeightRangeBottom = stack._heightRangeBottom; prevHeightRangeTop = stack._heightRangeTop; prevSignwobble = stack._signwobble; prevMirrorToggle = stack._mirrorToggle; animationPrevTimeLimit = millis()+stack._idleCompleted; timerStack = 0; idleCompleted = stack._idleCompleted; // idle time at the end of transformation currentStack = i; // add key stack if (nextStacks.size()>0 && stackHolder==currentStack) { switchStackHolder(); // replace neighbouring array entry nextStack = (Stacks)nextStacks.get(0); // get first entry nextStacks.remove(0); // delete first entry nextStack._completed = false; animationStacks.remove(stackHolder); animationStacks.add(stackHolder,nextStack); } } } else { // idle when at end of each transformation if (idleCompleted>0 && animationPrevTimeLimit < millis()) { idleCompleted=0; // loop, last entry reached if (currentStack==animationStacks.size()-1) { animationPlay(true); } } } } }Zeichenklasse Stellt Zeichen gemäss Wertesets dar
/** * CLASS SIGN * draws single sign */ class Sign { int _size = 75; // initial size of sign int _posX; // position x on grid int _posY; // position y on grid PVector _position = new PVector(); int _mouseX; // position mouse x int _mouseY; // position mouse y PVector _mousePos = new PVector(); float[] _scaleRange = {3.0,1.0}; // flip range float[] _strokeRange = {0.2, 10.0}; float[] _heightRange = {1.0, 2.0}; float _borderRadiusBlack = 0; // radius for black rectangles float _borderRadiusWhite = 0; // radous for white ractangles int numSignRect = 5; // how many rectangles // animation int _currentM; // milliseconds since start boolean _rotate = false; // whether to rotate signs or not float _rotation = 0.0; // rotation in degrees int _rotationDuration = 0; // duration rotation in milliseconds int _rotationIncDuration = 800; // duration increment rotation in milliseconds int _rotationMstart; // start rotation, millis() int _rotationMend; // end rotation, millis() int _rotateCycles = 0; // how many cycles in rotation float _wobble = 0; // allows wobbling to beat int _wobbleStep = 0; int _wobbleStepMax = 2; float _wobbleInc = 0.0; int _wobbleSwitch = 1; int _mirrorToggle; // constructor Sign(int index) { // setup } // setter methods void setSize(int s) { _size = s; // 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 setHeightRange(float start, float end) { _heightRange[0] = start; _heightRange[1] = end; } void setBorderRadiusBlack(float radius) { _borderRadiusBlack = radius; } void setBorderRadiusWhite(float radius) { _borderRadiusWhite = radius; } void doRotate(boolean r) { _rotate = r; } void doWobble(float w) { _wobble = w; } void setMirrorToggle(int w) { _mirrorToggle = w; } // draw sign void draw() { // evaluate coordinates PVector dir = PVector.sub(_position,_mousePos); // vector distance to mouse pointer float distance = dir.mag(); // distance to mouse cursor // angle to mouse pointer float angleMouse = atan2(_mousePos.y - _posY, _mousePos.x - _posX); angleMouse+=_rotation; // scaling of sign (depends on distance to mouse pointer), max distance stage width float scaling = map(distance,0.0,width,_scaleRange[0],_scaleRange[1]); // 2,1: inverts range -> signs nearest to mous appear the biggest if (_mirrorToggle<0 && scaling<0.01) { scaling = 0.01; // only positive numbers allowed } // height range float heightShift = map(distance,0.0,30,_heightRange[0],_heightRange[1]); // stroke width depends on distance to mouse pointer float strokeWidth = map(distance,0.0,width,_strokeRange[0],_strokeRange[1]); if (strokeWidth<0) strokeWidth*=-1; // only positive numbers allowed // wobble if (_wobble>0) { _wobbleStep+= _wobbleSwitch; _wobbleInc = _wobbleStep*_wobble*(distance/(width)); if (_wobbleStep>_wobbleStepMax || _wobbleStep<0) { _wobbleSwitch*=-1; } } // sign pushMatrix(); translate(_posX,_posY); // move sign scale(scaling+_wobbleInc); rotateM(_rotate); pushStyle(); noFill(); noStroke(); // draw bezier objects (for outlines a black and white one needed) for(int i=0; i<numSignRect; i++) { pushMatrix(); translate(1*(dir.x/heightShift)*i,1*(dir.y/heightShift)*i); // centered by default, interaction mouse possible float w = _size-(i*_size/(numSignRect)); // width of sign (inner beziers scaled down) // draw black bezier fill(0); bezierRect(-1*w/2,-1*w/2,w,w, _borderRadiusBlack*(w/_size), _borderRadiusBlack*(w/_size)); // draw white bezier fill(255); bezierRect(-1*(float)(w/2-strokeWidth/2),-1*(float)(w/2-strokeWidth/2),w-strokeWidth,w-strokeWidth, _borderRadiusWhite*(w/_size), _borderRadiusWhite*(w/_size)); popMatrix(); } popStyle(); popMatrix(); // animation _currentM = millis(); } /** @param x x-coordinate of upper-left @param y y-coordinate of upper-left @param w width of the rectangle @param h height of the rectangle @param xr radius to inset x-coordinate corners for bezier control points @param yr radius to inset y-coordinate corners for bezier control points */ void bezierRect(float x, float y, float w, float h, float xr, float yr) { float w2=w/2f, h2=h/2f, cx=x+w2, cy=y+h2; // used to make control points visible /*noFill(); stroke(0); ellipse(cx,cy-h2,10,10); ellipse(cx+w2-xr, cy-h2,5,5); ellipse(cx+w2, cy-h2+yr,5,5); ellipse( cx+w2, cy,10,10);*/ beginShape(); vertex(cx,cy-h2); bezierVertex(cx+w2-xr, cy-h2, cx+w2, cy-h2+yr, cx+w2, cy); bezierVertex(cx+w2, cy+h2-yr, cx+w2-xr, cy+h2, cx, cy+h2); bezierVertex(cx-w2+xr, cy+h2, cx-w2, cy+h2-yr, cx-w2, cy); bezierVertex(cx-w2, cy-h2+yr, cx-w2+xr, cy-h2, cx, cy-h2); endShape(); } // animation // rotation depending on milliseconds (on cycle in specific time) // duration can be increased stepwise (resp. key pushed twice = 2cycles) void rotateM(boolean r) { if (_rotateCycles==0 && _rotate==true) { // only set at start _rotationDuration+=_rotationIncDuration; _rotationMstart = _currentM; _rotationMend = _rotationMstart + _rotationDuration; } if (_rotate==true) { _rotationDuration+=_rotationIncDuration; _rotationMend+=_rotationDuration; _rotateCycles++; _rotate=false; } if (_currentM<_rotationMend) { _rotation = map(_currentM-_rotationMstart,0,_rotationDuration,0,360*_rotateCycles); rotate(radians(_rotation)); //radians(_rotation) } else { _rotationDuration=0; _rotateCycles=0; } } }Kleine Klasse zum Speichern der Zeichenwerte Die Werte von ansprechenden Permutation habe ich mir notiert und als Objekt dieser Klasse gespeichert.
/** * CLASS STACKS * stores set of values for a specific permutation */ class Stacks { int _id; // key in stack array String _name; // give your stack a name (to know later what is what) int _duration = 1000; // milliseconds int _idleCompleted = 50; // stop for a moment when transformation ended till next begins (set > 0) float[] _scaleRange = {3.0,1.0}; // flip range float[] _strokeRange = {0.2, 10.0}; float[] _heightRange = {1.0, 2.0}; float _borderRadiusBlack = 0; // radius for black rectangles float _borderRadiusWhite = 0; // radous for white ractangles boolean _completed = true; // is set on mouse click to false float _scaleRangeTop; float _scaleRangeBottom; float _strokeRangeTop; float _strokeRangeBottom; float _heightRangeTop; float _heightRangeBottom; float _signwobble; int _mirrorToggle; // constructor Stacks(int id) { _id = id; // key in stack array } // setter methods void setName(String name) { _name = name; } void setDuration(int duration) { _duration = duration; } void setScaleRange(float start, float end) { _scaleRange[0] = start; _scaleRange[1] = end; _scaleRangeBottom = start; _scaleRangeTop = end; } void setStrokeRange(float start, float end) { _strokeRange[0] = start; _strokeRange[1] = end; _strokeRangeBottom = start; _strokeRangeTop = end; } void setHeightRange(float start, float end) { _heightRange[0] = start; _heightRange[1] = end; _heightRangeBottom = start; _heightRangeTop = end; } void setBorderRadiusBlack(float radius) { _borderRadiusBlack = radius; } void setBorderRadiusWhite(float radius) { _borderRadiusWhite = radius; } void doWobble(float w) { _signwobble = w; } void setMirrorToggle(int w) { _mirrorToggle = w; } }Sammlung von Wertesets, die auf Keys gemappt werden können Diese habe ich mir bei einer vorhergehenden Runde gespeichert und aus diesen dann mir die ansprechendsten rausgelesen.
// sign values that can be places on keys keyAnim++; stack = new Stacks(keyAnim); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(27.0); stack.setBorderRadiusWhite(32.0); stack.setHeightRange(10, 20); stack.setScaleRange(2.9, -0.3); stack.setStrokeRange(2.0, 2.0); animationStacks.add(stack); keyAnim++; stack = new Stacks(keyAnim); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(2.0); stack.setBorderRadiusWhite(2.0); stack.setHeightRange(9, 14); stack.setScaleRange(2.2, -1.3); stack.setStrokeRange(0.5, 0.5); animationStacks.add(stack); keyAnim++; stack = new Stacks(keyAnim); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(27.0); stack.setBorderRadiusWhite(24.0); stack.setHeightRange(10, 20); stack.setScaleRange(2.6, -1.8); stack.setStrokeRange(2.0, 2.0); animationStacks.add(stack); keyAnim++; stack = new Stacks(keyAnim); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(-26.0); stack.setBorderRadiusWhite(-20.0); stack.setHeightRange(0, 27); stack.setScaleRange(1.9, 0.2); stack.setStrokeRange(0.5, 14.5); animationStacks.add(stack); keyAnim++; stack = new Stacks(keyAnim); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(46.0); stack.setBorderRadiusWhite(25.0); stack.setHeightRange(10, 12.5); stack.setScaleRange(2.4, 0); stack.setStrokeRange(8, 12); animationStacks.add(stack); keyAnim++; stack = new Stacks(keyAnim); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(-7.0); stack.setBorderRadiusWhite(28.0); stack.setHeightRange(27, 31); stack.setScaleRange(2.3, 2.4); stack.setStrokeRange(0.5, 26); animationStacks.add(stack); keyAnim++; stack = new Stacks(keyAnim); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(-40.0); stack.setBorderRadiusWhite(98.0); stack.setHeightRange(10, 25); stack.setScaleRange(2.1, 2.4); stack.setStrokeRange(2, 2); animationStacks.add(stack); keyAnim++; stack = new Stacks(keyAnim); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(27.0); stack.setBorderRadiusWhite(24.0); stack.setHeightRange(10, 20); stack.setScaleRange(2.6, -1.8); stack.setStrokeRange(2.0, 2.0); animationStacks.add(stack); keyAnim++; stack = new Stacks(keyAnim); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(-227.0); stack.setBorderRadiusWhite(321.0); stack.setHeightRange(10, 20); stack.setScaleRange(0.8, -5.0); stack.setStrokeRange(2.0, 2.0); animationStacks.add(stack); keyAnim++; stack = new Stacks(keyAnim); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(-227.0); stack.setBorderRadiusWhite(321.0); stack.setHeightRange(10, 20); stack.setScaleRange(0.44, 0.48); stack.setStrokeRange(2.0, 2.0); animationStacks.add(stack); keyAnim++; stack = new Stacks(keyAnim); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(-227.0); stack.setBorderRadiusWhite(321.0); stack.setHeightRange(10, 20); stack.setScaleRange(0, 0.08); stack.setStrokeRange(2.0, 2.0); animationStacks.add(stack); keyAnim++; stack = new Stacks(keyAnim); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(-371.0); stack.setBorderRadiusWhite(304.0); stack.setHeightRange(10, -6.0); stack.setScaleRange(0.2, 0.18); stack.setStrokeRange(2.0, 2.0); animationStacks.add(stack); keyAnim++; stack = new Stacks(keyAnim); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(-639.0); stack.setBorderRadiusWhite(395.0); stack.setHeightRange(20, 20); stack.setScaleRange(0.2, 0.18); stack.setStrokeRange(2.0, 2.0); animationStacks.add(stack); keyAnim++; stack = new Stacks(keyAnim); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(-639.0); stack.setBorderRadiusWhite(395.0); stack.setHeightRange(20.8, 18.1); stack.setScaleRange(0.2, 0.18); stack.setStrokeRange(2.0, 2.0); animationStacks.add(stack); keyAnim++; stack = new Stacks(keyAnim); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(-139.0); stack.setBorderRadiusWhite(195.0); stack.setHeightRange(20.8, 18.1); stack.setScaleRange(0.2, 0.18); stack.setStrokeRange(2.0, 2.0); animationStacks.add(stack); keyAnim++; stack = new Stacks(keyAnim); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(23.0); stack.setBorderRadiusWhite(23.0); stack.setHeightRange(7.8, 75.6); stack.setScaleRange(2.3, 2.3); stack.setStrokeRange(1.0, 1.0); keyAnim++; stack = new Stacks(keyAnim); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(11.0); stack.setBorderRadiusWhite(54.0); stack.setHeightRange(10, 48); stack.setScaleRange(5.0, 0.25); stack.setStrokeRange(1.12, 1.12); animationStacks.add(stack); keyAnim++; stack = new Stacks(keyAnim); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(59.0); stack.setBorderRadiusWhite(54.0); stack.setHeightRange(10, 50); stack.setScaleRange(i*0.25, 5.0); stack.setStrokeRange(1.11, 1.11); animationStacks.add(stack); keyAnim++; stack = new Stacks(keyAnim); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(56.0); stack.setBorderRadiusWhite(55.0); stack.setHeightRange(10, 50); stack.setScaleRange(6.7, i*-0.5); stack.setStrokeRange(1.11, 1.11); animationStacks.add(stack); keyAnim++; stack = new Stacks(keyAnim); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(11.0); stack.setBorderRadiusWhite(11.0); stack.setHeightRange(10, 50); stack.setScaleRange(1.4, 1.4); stack.setStrokeRange(0.5, 0.5); animationStacks.add(stack); keyAnim++; stack = new Stacks(keyAnim); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(11.0); stack.setBorderRadiusWhite(10.0); stack.setHeightRange(0, 52); stack.setScaleRange(2.3, 2.3); stack.setStrokeRange(2.6, 18.1); animationStacks.add(stack); keyAnim++; stack = new Stacks(keyAnim); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(11.0); stack.setBorderRadiusWhite(10.0); stack.setHeightRange(0.25, 8.9); stack.setScaleRange(2.3, 2.3); stack.setStrokeRange(9.5, 9.5); animationStacks.add(stack); keyAnim++; stack = new Stacks(keyAnim); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(11.0); stack.setBorderRadiusWhite(10.0); stack.setHeightRange(0.25, 8.9); stack.setScaleRange(2.3, 2.3); stack.setStrokeRange(-9.5, -9.5); animationStacks.add(stack); keyAnim++; stack = new Stacks(keyAnim); stack.setDuration(durationAnimStep); stack.setBorderRadiusBlack(-12.0); stack.setBorderRadiusWhite(-33.0); stack.setHeightRange(0.25, 8.9); stack.setScaleRange(2.3, 2.3); stack.setStrokeRange(-9.0, -9.0); animationStacks.add(stack);