每次默默停刊(我是富X義博?)後,要再重拾書本時真是萬分不捨,
這絕對不是成語亂用,沒辦法,只要稍一怠惰我就可以完全放軟舒服攤平,
尤其是看完之後還要打成網誌真的是挺麻煩的,
但我相信自己打過一遍後,雖然不是說完全精通,但至少記得更清楚.
不過CCC說看太慢了 ...............
但同時他也幫我解套噢噢噢,
那就是我不需要拘泥在每篇都要完整介紹,
有些其實暫時用不到或是很少用到,
可以先挑自己有興趣的即可 ................
WOW,所以有些我有看過但覺得暫時無用我會先跳過不講,
但千萬記得自己要看過一遍.
所以讓我們先快樂的跳過p110-116的Typography 1吧! :)))
記得沒講的自己要看過一遍!!!!!!!!!!
----------------------------------------------------------------------------------------------
這次會講p117-125的Math 3 : Trigonometry (又是數學...)
基本上就是學習如何運用角度跟sin,cos的關係,另外尾巴再加上一點arc
關於角度,一定要記得processing的角度計算是以x軸順時針來看的,
以東南西北來說就是
270度
180度 + 0,360度
90度
而表示一個角度除了360度數外,我們也可以用 π 來表示(廢話,這我都會.)
在processing裡面π要以大寫的PI代表,而0,90,180,270依序應寫為
TWO_PI, HALF_PI, PI, PI + HALF_PI
不過這樣打我個人覺得超麻煩的,所以不如記0, 1.57, 3.14, 4.71
也就是我們熟知的π = 3.14xxxxxxxx
processing裡也能以這樣取代π,雖然有些微差距但我覺得可以接受
所以我們可以很簡單知道在processing裡簡單的一個180度可以寫成
radians(180) 或 degree(PI) 或 degree(3.14)
在知道角度之後,就是超靠杯的sin跟cos了
首先不要被p118那個莫名其妙的diagram給蠱惑了
我們只要知道sin與cos的值永遠會介於1至-1之間
然後對應表如下
sin() cos()
0,2π 0 1
π /2 1 0
π 0 -1
3π/2 -1 0
背起來之後就可以先拿p119的14-06做練習
size(400,200);
background(128);
smooth();
noStroke();
float angle = 0; //先定義一個float為angle,值為0
for(int x = 0; x <= width; x += 5){ //for loop內總共會執行81次
fill(255);
float y = 100 + (sin(angle) * 30);
ellipse(x,y,4,4);
//白色圓點線
//隨著x的推移,同時讓y座標上下變動
//因為無論sin或cos一定是1到-1
//會*30只是為了讓y的增減較明顯
fill(255,255,0);
float k = 100 + (cos(angle) * 15);
rect(x,k,2,8);
//黃色長方形線
//道理同上,只是換成用cos,所以我們可以看到兩條線
//因為只*15,所以我們可以看到波動比較小
angle += 3.14/10;
//本來課本是寫PI/10,我只是改成3.14/10
//這行是用來定義上面sin與cos的angle一次會遞增多少
}
//saveFrame("p119-##.jpg");
至於p121其實只是把一些控制項用float定義出來而已,
一大串沒什麼好怕的.基本上它把畫一條線的控制項分為三種
offset (偏移)
scaleVal (比例縮放)
angleInc (角度增加值)
直接跟上面對比就知道了,而它們三個也不是processing內的指令
只是作者方便撰寫才取的,如果重寫上面的程式就會變成
size(400,200);
background(128);
smooth();
noStroke();
float offset = 100;
float scaleValA = 30;
float scaleValB = 15;
float angleInc = 3.14/10; // or PI/10
float angle = 0;
for(int x = 0; x <= width; x += 5){
fill(255);
float y = offset + (sin(angle) * scaleValA);
ellipse(x,y,4,4);
fill(255,255,0);
float k = offset + (cos(angle) * scaleValB);
rect(x,k,2,8);
angle += angleInc;
}
//saveFrame("p119-##.jpg");
再進階一點的畫法就是p122那搭配我們之前在p69學過的vertex來畫
size(400,200);
background(128);
smooth();
stroke(128);
float angle = 0;
beginShape(TRIANGLE_STRIP);
for(int x = -3; x <= width + 5; x += 5){
fill(255,255,0);
float y = sin(angle) * 30;
if((x%2) == 0){
vertex(x,100 + y);
}
else{
vertex(x,100 - y);
}
angle += 3.14/22;
}
endShape();
//saveFrame("p122-##.jpg");
基本上我們可以看到作者就是說當x整除2時y會向上升
其餘時則會向下降,而注意看那for loop,
for(int x = -3; x <= width + 5; x += 5){
依序為-3,2,7,12,17,22,27,32,......................
所以其實是很規律的2不能整除,2可以整除,2不能整除,2可以整除,.............
那就可以想像點一定是一上一下的,透過vertex的TRIANGLE_STRIP把點連起來,
色塊上成黃色,就是結果了,voila!
接著是p123的14-11,你可能會跟我一樣迷失得莫名其妙,
就讓我簡化它來讓你看清
size(400,200);
background(128);
smooth();
fill(255,20);
float scaleVal = 15;
float angleInc = 3.14/28;
float angle = 0;
//這邊就是剛剛上面提到的把控制項拉出來
for(int offset = 15; offset <= width + 10; offset += 50){ //x總共跑8次,這決定會有幾條線
for(int y = 0; y <= height; y += 2){ //y總共跑101次,這決定線的波動多寡
//這邊我們再次遇到for中有for的情況,要記得永遠是裡面的for先算
//同時我們發現本來三個基本的控制項的offset被抓進for裡面了
float x = offset + (sin(angle) * scaleVal);
noStroke();
ellipse(x,y,10,10);
stroke(0);
point(x,y);
//上面不過是共用點,然後同時畫點跟半透明的圓罷了
angle += angleInc;
}
}
//saveFrame("p123-##.jpg");
在這要做一個簡單的算數給大家看,你們是否會覺得第一條線跟第六條線很像?
首先我們知道每次角度的增加值為3.14/28 = 0.11214xxxxx
我們同時知道當0.11一直疊加到6.28時,sin就過了一次週期然後再重新一次波動,
而每次y會跑101次,所以我們知道畫完一條曲線共疊加了0.11*101 = 11.32614
而11.32614/6.28 = 1.8,這代表著每條曲線只跑了1又0.8的sin,而不是剛好跑2次sin週期
但因為我們只有設x跟y的for loop,並未設角度增值的for,
因此不是每次新的曲線生成時,角度又從0開始,這導致前五條線扭的不太一樣,
不過正因每次只跑1.8次的sin,但跑5條線後剛好為1.8*5=9,
所以我們知道在第五條線畫完時剛好跑完9次sin,
因此第六條曲線開始畫時剛好sin為0開始,因此會跟第一條線一模一樣囉,
只要稍微改一下x跟y的遞增值你就可以畫出跟作者一樣的圖囉. :)
至於最後的arc其實就是應用前面的觀念,只是改成畫弧線而已,
p125只多用了radius而已,應該不難理解,就請自己看囉!
那要如何應用上面的技巧來畫出下面的彩色旋風呢?
size(200,200);
background(255);
smooth();
stroke(255,80);
float radius = 1;
beginShape(TRIANGLE_STRIP);
for(int deg = 0; deg < 360*60; deg += 55){
float angle = radians(deg);
float x = 100 + (cos(angle) * radius);
float y = 100 + (sin(angle) * radius);
vertex(x,y);
fill(random(100,255),random(100,255),random(100,255),180);
radius = radius + 0.8;
}
endShape();
//saveFrame("p125-##.jpg");
Try it. :)
沒有留言:
張貼留言