2011/08/02

Motion 2 : Machine, Organism (processing教學)

今天早餐沒有吃,中餐吃大呼過癮,吃完只有大呼好熱,
晚餐吃神魯,吃完就暈過去一陣子.

有時候要做事情的時候都還是會想我做這幹麻?
但學長說過很多事都是在不問幹麻做就對了的情況下,
自己會有所啟發跟成長,我想我現在有點了解王俊雄那時想對我表達的東西了.
什麼事情都瞻前顧後的的話,最後結果大多是不上不下或是安全牌爾爾,
也許找到其中的平衡點我就可以拿82分了噢.

------------------------------------------------------------------------------------------------------------------------------

再接下來的這篇裡,雖然我們已經學過動畫了,
但p291-299的Motion 2這篇講的比較像是連動關係.
p292,293的範例大概跟Motion 1的範例沒差多少,
其實現在看到sin跟cos沒有那麼害怕了,
因為基本上它通常只是個調節變數(1到-1), nothing to be afraid of.  :)

先從p294的32-03講起.



void setup(){
  size(200,200);
  noStroke();
  smooth();
}

float angle = 0;
float speed = 0.1; //speed數值越大則扭動越快,因為sin的循環每次加總值為6.28

void draw(){

  background(0);

  angle = angle + speed;
  ellipse(100 + (sin(angle + PI) * 5), 70, 30, 30);  //PI = 3.14,而sin(PI) = 0 之後往-1跑,所以上圓會先往左跑
  ellipse(100 + (sin(angle + HALF_PI) * 5), 100, 30, 30); //相較之下中圓會先往右跑,因為sin(HALF_PI)時仍為正數
  ellipse(100 + (sin(angle + QUARTER_PI) * 5), 130, 30, 30); //跟中圓比時,下圓則較其更晚往-1跑

  //if(frameCount < 200){
  //  saveFrame("p294-1-###.jpg");
  //} 
}


簡單來說,就是上圓一開始先往左跑,而中下圓則往右跑,
而下圓又比中圓跑的慢,透過這樣的間隔達到好像球在擺動的效果.
如果還不懂,請回去看p118關於sin,cos的定義.
而32-04基本上也是同樣的用法,透過不同的值造成圓縮放的時間差.



void setup(){
  size(200,200);
  smooth();
  fill(255,180);
}


float angle = 0;
float speed = 0.05; //一樣控制縮放速度


void draw(){
  background(0);
  angle += speed;
  noStroke();
  circlePhase(0);
  circlePhase(QUARTER_PI);
  circlePhase(HALF_PI);
 
  stroke(255,0,0);
  line(45,0,45,200);
  line(155,0,155,200);
 
  if(frameCount < 200){
  saveFrame("p294-2-###.jpg");
  } 
}

void circlePhase(float phase){
  float diameter = 155 + (sin(angle + phase) * 45);

  //我們知道sin就是1到-1,所以圓的直徑最大是200,最小是110
  ellipse(100,100,diameter,diameter);
}


我特意畫了額外兩條紅線,其間距即是110,
所以我們可以看到圓在縮放的時後,最大時是剛好碰到邊框,
最小時則剛好碰到兩條紅線,這應該會比較好理解sin在程式裡的作用.

再來就是p298的32-08與32-09跟noise搭配的案例,
一樣記得,noise只是一個介於1到-1的random,同時俱有方向性.


void setup(){
  size(200,200);
  strokeWeight(20); //很粗的線
  smooth();
}


float n1 = 0;
float inc1 = 0.1;
float n2 = 0;
float inc2 = 0.09;
float k = 0;
float inck = 0.05;


void draw(){
  background(0); //每畫一次都把前一次畫的蓋掉


  n1 += inc1;
  n2 += inc2;
  k += inck;
 
  float y1 = (noise(n1) - 0.5) * 50; //基本上值就是介於-15到15
  float y2 = (noise(n2) - 0.5) * 50; //同上,只是為了讓兩條線擺動時noise值不一樣,所以分出y1,y2
  stroke(255 + (sin(PI+k)*255));  //我額外加的,透過sin讓線在擺動時同時閃爍
  line(0,100,80,100 + y1);
  line(200,100,100,100 + y2);
 
  //if(frameCount < 300){
  //  saveFrame("p298-1-###.jpg");
  //} 
}
 
應該沒什麼大問題吧?再來就是32-09囉. 



void setup(){
  size(200,200);
  noStroke();
}


float inc = 0.06; //值越小畫面越細膩
int density = 4; //值越小馬賽克格子越小
float znoise = 0;


void draw(){
  float xnoise = 0;
  float ynoise = 0;
 
  for(int y = 0; y < height; y += density){
    for(int x = 0; x < width; x += density){
      xnoise += inc;
      float n = noise(xnoise,ynoise,znoise) * 256;
      fill(n);
      rect(y, x, density, density);
    }
    ynoise += inc;
    xnoise = 0;
  }

//基本上這段就跟之前介紹noise一樣,透過x,y向的forloop成圖
  znoise += inc;

//z方向的noise則使畫面得以一直變化,如果把它殺掉你會發現畫面是定住的
//因為noise有方向性,所以xy向只是成一張圖,而z向則是不斷的推移.

  //if(frameCount < 200){
  //  saveFrame("298-2-###.jpg");
  //} 
}


如果把inc改成0.5,而density改成2則會得到以下,



如果你還是不太懂nosie到底在衝三小,
這張diagram不知道會不會幫到你.


基本上你可以想成noise的xyz其實像一團霧,
而當我們只有xy時,我們只看到這團霧的其中一個切面,
但當我們有z方向時,則會在霧中不斷推移,所以每張切面就構成一動畫.

最後則是小作品一則,我有設定當圓在跑時,
碰到邊時會馬上回歸中心點繼續畫,把程式碼丟入processing看動畫會比較清楚.


void setup(){
  size(200,200);
  background(255);
  randomSeed(2);
}


float x = 100;
float y = 70;


void draw(){ 
 
  frameRate(150);
 
  x += random(-8,8);
  y += random(-8,8);
  strokeWeight(random(3,12));
  stroke(random(255),40);
  point(x,y);
 
  if(x < 0 || x >200){
    x = 100;
  }
 
  if(y < 0 || y >200){
    y = 100;
  }
 
  //if(frameCount > 1000 && frameCount < 1002){
  //  saveFrame("p296-1-##.jpg");
  //} 
}



Try it. :)

沒有留言:

張貼留言