• 沒有找到結果。

利用上一節的物理計量方式,我們可以分析在 xDIVA 畫面中所有的物體移

48

動。而在這一節,我們要了解移動中的物體間相互的作用關係。

5.2.1 力

在物理學上,力(Force,物理上的簡寫為 F)是指物體之間的相互作用或相 互牽引的作用。力會改變一個自由物體的運動狀態,即改變自由物體速度的大小 或方向。

由此我們可以得知,當一個物體的移動狀態改變(速度向量改變,即有加速 度),它必然是受到力的作用了。我們更可以推論:使用者拖拉 xDIVA 畫面中的 物件而改變該物件的移動狀態,便是一種對該物件施力的行為。而這個力還可以 透過二元關係去傳導,去影響其它物件的運動狀態。

5.2.2 資料結構:力與移動

有了移動狀態之後,我們當然還需要記錄這個移動狀態的來源(力)以及承 受運動狀態的主體,我們使用一組力的連結(即施力者與受力者)來表示:

程式碼 5-2 Link

其中 fromVM 是這一個連結(Link)中的施力者,因某種因素產生加速度而施

49

力於另一端物件的 VM 物件,而 toVM 便是再另一端受力的 VM。我們單純將其 解讀為一個力的施力者與受力者。然後,我們就可以將一個移動處理的整體表示 成:

pair<Link*, PositionMoveState*>

便詳細記錄了一個力(施力者與受力者)和這個力作用在目前受力者所造成 的移動狀態。而一群移動的發生就可以用使用 C++ STL 的 map 去管理:

map<Link*, PositionMoveState*> anis;

anis 代表的是動畫 animations,因為速度與移動需要不間斷、平滑的處理,

這種行為是動畫行為,我們必須交由動畫系統去處理。

接下來,我們將說明本論文所實做出的一種力的產生與傳導方式:彈簧(虎 克定律),也是 xDIVA 目前提供的一種力的傳導方式。

5.2.3 彈簧與虎克定律(Hooke's law)

提到虎克定律就會想到彈簧(圖 5-b 彈簧),因為虎克定律應用最常見的例子 就是彈簧。 在彈性限度內,彈簧的彈力 F 和彈簧的長度變化量 x 為線性關係,

即是著名的虎克定律:

F = − kx

50

k 是彈簧的彈力係數,由彈簧材料與外形所決定,數值越大則彈簧越難以變 動其長度(由另一面來看,同樣的長度變動可以產生更多的力),負號則代表彈 簧所產生的力與其伸長或壓縮的方向相反。

圖 5-b 彈簧

在本論文中,彈簧將成為我們探討的力的傳導工具,我們假設 xDIVA 畫面 中各物件之間的二元關係為彈簧,這些彈簧都有一個初始的長度(使用者可以自 行設定),單使用者拖拉畫面中任何一個物件時,物件隨著滑鼠游標而移動,而 因為物件的移動而造成的彈簧一端長度改變(其值可推算並量化使用者拖拉物件 的「力」),所造成的彈力將會影響二元關係裡的另一端的物件使之移動,造成一 環又一環的牽動,形成力的傳導。

5.2.4 方法:產生彈簧力 crateSprForceFromVMtoVMs

首先 createSprForceFromVMtoVMs 這個方法永有兩個傳入參數,第一個是 彈簧力產生的主體,是施力者;第二個參數則是被施力者(受力者),可以為多 個。由方法名稱我們可以知道這個方法是要計算出施力者對受力者們的彈簧力

51

(其大小、造成的移動狀態)。這些力的基本將按照上一節提到的虎克定律產生,

因此,我們必須先計算出彈簧兩端(施力者與受力者)的距離來了解彈簧的長度 變化:(其中 vm 為施力者,infVM 為受力者)

//計算目前的長度為新長度

float newL = computeDistance(vm->Position, infVM->Position);

//新長度與彈簧長度的差距決定力的大小 float dL = newL - _spring_length;

在知道了力的大小之後,我們還需要知道力的作用方向(移動方向):

//兩個位置向量的差就是移動方向

Vector3 dV = vm->getPosition()- infVM->getPosition();

//除以向量長度,得到方向的單位向量

Vector3 direct = Vector3(dV.x/newL, dV.y/newL, dV.z/newL);

如此我們可以得到這個受影響的 VM 它應該產生的移動速度以及方向,如 果配合牛頓第二運動定理(章節 5.4.4),我們就可以產生一個 PositionMoveState 配合兩個 VM 將這個移動加入 anis 參與動畫。