Willkommen auf unserem Seminar-Blog

Immer auf dem aktuellen Stand bleiben

Dieser Seminar-Blog befindet sich noch im Aufbau und wird in den kommenden Tagen entsprechend verfeinert.

Member Login

Lost your password?

Registration is closed

Sorry, you are not allowed to register by yourself on this site!

You must either be invited by one of our team member or request an invitation by email at viad.info {at} zhdk {dot} ch.

12. Stand der Dinge Zeichen/Processing

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;
  }
}