2011/07/02

Math 2 : Curves (processing教學)

當我看到p79的標題寫著Math 2 : Curves時,我就知道又要崩潰了.
因為通常這種標題的內容都是上數學課,
對於加減尚算熟稔但到乘除就有點吃力的我來說,
還有學什麼平方,平方根,remap等等真的是要我老命,
在看完p79-84之後,我只能說我理解了,
但要我自己想圖要怎麼畫出來跟lady gaga來台住到我旁邊的空房一樣或然率為零,
所以就開始囉 ........................................................

基本上我們會看到幾個指令
sq()
sqrt()
pow()
norm()
lerp()
map()


1. sq()
顧名思義sq即為square的縮寫,平方的意思
所以當我們打 flaot a = sq(3) 即 a = 3*3 = 9 ............
同理也可以寫入負數 float b = sq(-4) 即 b = (-4)*(-4) = 16 ...........
我知道你們看到這一定認為我當各位是白癡嗎
不要心急 你後面就會體會到Math 2這篇玄妙的真締


2. sqrt()
square root即是平方根的意思,所以同上面的經驗,
當我們打 float c = sq(6561) 即 c = 81 因為 81*81 = 6561
同時要記得sqrt()內只能填正數
哩娘勒 林杯只背過九九乘法表 還沒背過 九九平方根表勒


3. pow()
pow內的寫法為pow(num,exponent)
exponent是指數的意思,為防有人數學跟我一樣爛,下面是指數的解釋
 a的b次方  a其中的b即為指數
所以pow內第一個數即為a,第二個數為b
當我們寫float d = pow(2,3) 即 d = 2*2*2 = 8
但當我們寫 float e = pow(3,-2)時 e = 1 / ((-3)*(-3))
為什麼就不要問了 作者就是這樣定義的 ............


4.norm()
norm是normalization的縮寫
基本上就是把任一數值間距轉化為0.0至1.0的間距
因此當我打 float f = norm(102,0,255)時
它的意思為把0至255的間距轉換為0至1時
本來處於0至255間距中的102它在0至1時數值為何 (繞口令了嗎)
因此f = 255 / 102 = 0.4

當然我們也可以把0至1間距內的數套到別的間距內
例如當我要知道0.4被套到-20到60的間距時,它的數值應為多少
公式為 x(0至1內的數值) * 新間距長 + (新間距的最小值)
所以我們知x = 0.4, 新間距長為80, 新間距的最小值為-20
算式即為 0.4 * 80 + (-20) = 12
得知0至1時0.4的位置在-20到60的間距時位置為12
如果這你了解了 後面兩個就比較容易懂


5.lerp()
lerp為linear interpolation的縮寫,意即線性插值法 (三小啦)
lerp(value1,value1,amt)
value1為間距最小值
value2為間距最大值
amt則為0至1中間任一數,一定得介於0至1
其實就是把上述的0至1轉到別的間距時數值應為多少的指令
當我們寫float g = lerp(-30,60,0.5)時
g = amt * 新間距長 + (新間距的最小值)
g = 0.5 * 90 + (-30) = 15


6.map()
map(value,low1,high1,low2,high2)
基本上就是把間距A(low1至high1)內的數(value)轉到新的間距B(low2至high2)時為多少
如果把裡面拆開的話,我們可以把map()看成先norm再lerp
value,low1,high1 = norm()
low2,high2 = lerp()
讓我們驗證p.83的第一行即可知道
float x = map(20,0,255,-1,1)  答案是 x = -0.84
首先我們先norm(20,0,255) 得 20/255 = 0.0784313725.... 約為0.08
(float基本上不會算到小數很後面,似乎只算到小數第二位)
再lerp(0.08,-1,1) 得  0.08 * 2 + (-1) = 0.16 - 1 = -0.84


看得暈頭轉向後我們還是要知道這些東西要應用在哪裡,
誠如標題Math 2 : Curves所說,是哪來畫曲線的,
所以你可以自行看p83下面簡單的兩個案例,
基本上他透過y=x的n次方來定義點,就可以慢慢畫出曲線.
透過for()定義x, 再透過norm(x)把n鎖定在0至1之間
最後再透過y = pow(n,4) 跟 y *= 100 來將y值轉換為0至100的間距,
所以整條曲線會剛好結束在圖框的右下角,因為作者預設size(100,100)
如果改成y = pow(n,0.4)則改變曲線曲的方向
這一定要自己試一次你才會知道(花生什麼事)

p084則是比較進階一點的寫法,其他兩個好好看一下你就會懂,
但要我自己想實在是力不從心,希望對你來說是輕輕鬆鬆
我拿第一個案例梢做改變來解釋


size(200,200);
background(255);
noFill();
smooth();


for(int x = 0; x <= 200; x += 8){  //總共從(0,0)開始畫26個點

  float n = norm(x,0,200);  //將x轉為0至1之間的值成為n
  float y = pow(n,2);  // 決定曲度跟曲的方向,若2改成0.2即向下曲
 float k = random(50,350);  //每個圓的半徑介於50至350之間
  y *= 200;  //讓曲線最後一點會在右下角,因為size為(200,200)

  stroke(random(128,255));
  fill(random(255),10);
  strokeWeight(0.1);
 
  ellipse(x,y,k,k);
}

//saveFrame("p084-2-##.jpg");


我知道有點抽象,所以請一定要自己試一遍........
至於這次的圖只能說根本跟這一篇沒什麼關係啊!!!!!!!!!!!!!!!


size(200,200);
background(255);
noFill();
smooth();

for(int x = 0; x <= 200; x += 1){

  float n = norm(x,0,200);
  float y = pow(n,7);
  float k = random(10,200);
  y *= 200;
 
  stroke(random(128,255));
  fill(random(255),10);
  strokeWeight(0.1);
  beginShape(TRIANGLE_STRIP);
  vertex(200+random(200),200+random(200));
  vertex(x+random(200),y+random(200));
  vertex(x+random(200),x+random(200));
  endShape();
}

//saveFrame("p084-1-##.jpg");


Try it. :)

沒有留言:

張貼留言