OpenGL實(shí)例教程13:攝像機(jī)旋轉(zhuǎn)
目標(biāo):通過啟用鼠標(biāo)方向控制來完成攝像機(jī)的實(shí)現(xiàn)。
能夠?qū)⑾鄼C(jī)旋轉(zhuǎn)360度(圍繞正Y軸),這對應(yīng)于向左或向右旋轉(zhuǎn)。(軸是確定的)
能夠向上或向下傾斜攝像機(jī)。(軸是不確定的,實(shí)現(xiàn)相對困難)

實(shí)現(xiàn)方式:跟隨鼠標(biāo)的移動,當(dāng)鼠標(biāo)左右移動時改變水平角度,當(dāng)鼠標(biāo)上下移動時改變垂直角度。通過這兩個角度,計(jì)算目標(biāo)和向上的向量。
下邊是二戰(zhàn)高射炮,與我們將要建造的攝像機(jī)類似:

旋轉(zhuǎn)可以采用歐拉角(易懂)或四元數(shù)(難懂,但容易實(shí)現(xiàn))表示。通過使用四個數(shù)來表示方位。可以避免萬向節(jié)死鎖這樣的問題。
四元數(shù)(基于復(fù)數(shù)系統(tǒng)):

歸一化四元數(shù)于歸一化向量類似。這里將介紹使用四元數(shù)圍繞任意向量旋轉(zhuǎn)所需的步驟。計(jì)算四元數(shù)` W `的通用函數(shù)是:

` a `表示旋轉(zhuǎn)角度,` V `被旋轉(zhuǎn)的向量(頂點(diǎn)位置),其中Q為旋轉(zhuǎn)四元數(shù),定義為:

計(jì)算` W `后,旋轉(zhuǎn)后的向量就是(W.x,W.y,W.z)。
計(jì)算水平旋轉(zhuǎn):

目標(biāo)向量是(x,z)。圓的半徑長度為1,alpha的正弦函數(shù)正好是z。因此,計(jì)算z的反正弦函數(shù)將得到alpha。z在范圍[-1,1]內(nèi),asine的結(jié)果是-90度到+90度。但是水平角度的范圍是0-360度。此外,四元數(shù)是順時針旋轉(zhuǎn)的。當(dāng)用四元數(shù)旋轉(zhuǎn)90度時,最終在Z軸上得到-1,與實(shí)際的正弦90度(即1)相反。
最簡單的方法是始終使用Z的正值來計(jì)算asine函數(shù),并將結(jié)果與矢量所在的圓的特定四分之一相結(jié)合。例如,當(dāng)我們的目標(biāo)向量是(0,1)時,我們計(jì)算asine(1),即90,然后用360減去它。結(jié)果是270。0到1的正弦范圍是0到90度。把它和圓的四分之一結(jié)合起來,就得到了最終的水平角度。
計(jì)算垂直旋轉(zhuǎn):
計(jì)算垂直角比較簡單,將移動范圍限制在-90度(等于270度——直視上方)到+90度(直視下方)。這意味著只需要目標(biāo)向量中Y分量的asine函數(shù)的負(fù)值。當(dāng)Y = 1時(向上看)正弦等于90所以我們只需要反轉(zhuǎn)符號。當(dāng)Y = -1時(垂直向下)正弦值是-90而倒過來是90。
計(jì)算四元數(shù)的數(shù)學(xué)庫:
Camera庫中的相關(guān)實(shí)現(xiàn):
(camera.cpp)
應(yīng)用程序?qū)崿F(xiàn)代碼: