運用透視法的《最後的晚餐》 |
工程圖學有投影作圖方法,是假想有一透明平面 (投影面) 置於物體與觀察者之間或在物體後方,以投影方法將物體輪廓頂點投射至投影面上描繪成圖。若觀察者位於有限距離內觀看投影也會形成透視效果,此即所謂透視投影 (Perspective Projection)。
曾在過往的 PC/DOS 時代寫過兩支 C 程式,嘗試以透視投影的基礎在 2D 畫面上描繪簡單的 3D 立方體線框,並沿三軸做旋轉。今日已有許多極其方便的程式庫可供電腦程式作 3D 繪圖用,不似以往得多了解一些像三角幾何的數學知識才能解題。此次重施故技用 HTML5 與 Javascript 在瀏覽器上重溫這些基礎概念,但不再畫線框而是填色立方體的六個面。
幾個運用到數學基礎,如以下:
一、等長的線段在透視法裡表現出近大遠小的效果,是因為「平行線截比例線段性質」,如圖:
假設 3D 空間座標原點 O 位於視線正前方,且 Z 軸朝向視點與視線重疊,投影面位於視點與點 P(x,y,z) 之間且與 Z 軸垂直,則 P 點在投影面上投射點 P' 的計算如以下程式:
function Pt3D(x,y,z){ this.x = x; this.y = y; this.z = z; this.p = function(ctx){ // ctx.dz = [投影面至視點距離,O至投影面距離] // ctx.o = 3D座標原點在電腦螢幕的座標 var _x = this.x * (ctx.dz[1]/(ctx.dz[0]+ctx.dz[1]+this.z)) + ctx.o[0]; var _y = this.y * (ctx.dz[1]/(ctx.dz[0]+ctx.dz[1]+this.z)) + ctx.o[1]; return [_x,_y]; }; }
二、計算線框之 3D 座標繞三個軸旋轉後的新座標,使用了「三角函數和差角公式」:
sin(α + β) = sin(α)cos(β) + cos(α)sin(β) sin(α – β) = sin(α)cos(β) – cos(α)sin(β) cos(α + β) = cos(α)cos(β) – sin(α)sin(β) cos(α – β) = cos(α)cos(β) + sin(α)sin(β)若只繞 Z 軸旋轉,則 z 座標不變而旋轉後的 x, y 座標計算如以下程式:
function(rad){ var _x = this.x*Math.cos(rad) - this.y*Math.sin(rad); var _y = this.x*Math.sin(rad) + this.y*Math.cos(rad); this.x = _x; this.y = _y; };
三、繪圖時為避免繪出隱藏面 (視點看不見的面) 要判斷各面的方向,這需要計算各面的「法線向量」。這部分涉及向量的運算有些複雜,可參考這篇平面法線判定法有詳細的說明。
三維平面的法線是垂直於該平面的三維向量 |
至此,不得不說,別認為程式語言就能解決問題,決戰還得靠數學!
參考資料:
沒有留言:
張貼留言