與歐拉角工作在3D環境中不工作這麼好,有幾個問題和角案件中,他們根本不工作。而且你甚至不必使用它們。
你應該做的,就是利用這樣的事實,即轉換矩陣不是別的,然後協調在理解的形式寫下來系統基地。所以你有你的模型視圖矩陣MV。這種由模型空間變換,隨後視角變換的(列爲主的矩陣乘法從右到左):
MV = V * M
所以我們想知道的是,以何種方式「照相機」位於世界中。這是由反向視圖矩陣V^-1
給你的。當然,你可以使用反轉高斯約旦法觀察矩陣,但大部分的時間你的視圖矩陣將包括一個平移向量P中增加了一個3×3的旋轉矩陣。
R P
0 1
回想
(M * N)^-1 = N^-1 * M^-1
也
(M * N)^T = M^T * N^T
所以似乎有某種換位和反轉之間的關係。並非所有的轉置矩陣都是它們的逆矩陣,但也有一些矩陣的轉置是逆矩陣。即它是所謂的正交矩陣。旋轉是正交的。所以
R^-1 = R^T
整齊!這讓我們通過下面找到視圖矩陣的逆(我建議你嘗試證明它作爲一個exersice):
V =/R P \
\ 0 1/
V^-1 =/R^T -P \
\ 0 1/
那麼,這怎樣幫助我們放置在場景中的新對象在從相機的距離?那麼,V是從世界空間到相機空間的轉換,所以V^-1從相機轉換到世界空間。所以給定相機空間的一個點,您可以將其轉換回世界空間。假設你想在距離d
的距離中央放置一些東西。在相機空間,這將是點(0, 0, -d, 1)
。乘以V^-1:
V^-1 * (0, 0, -d, 1) = (R^T)_z * d - P
這正是你想要的。在你的OpenGL程序中,你的某個地方有你的視圖矩陣V,可能還沒有正確命名,但無論如何它都在那裏。假設你使用舊的OpenGL-1和GLU的gluLookAt:
void display(void)
{
/* setup viewport, clear, set projection, etc. */
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(...);
/* the modelview matrix now holds the View transform */
在這一點上,我們可以提取模型視圖矩陣
GLfloat view[16];
glGetFloatv(GL_MODELVIEW_MATRIX, view);
現在view
是列優先順序。如果我們直接使用它,我們可以直接處理這些列。但請記住轉置是旋轉的反轉,所以我們實際上需要第三行向量。因此,讓我們假設你保持view
身邊,讓你的事件處理程序(外顯示),你可以做到以下幾點:
GLfloat z_row[3];
z_row[0] = view[2];
z_row[1] = view[6];
z_row[2] = view[10];
我們想
GLfloat * const p_column = &view[12];
現在,我們可以計算出新對象的位置在距離d
位置:
GLfloat new_object_pos[3] = {
z_row[0]*d - p_column[0],
z_row[1]*d - p_column[1],
z_row[2]*d - p_column[2],
};
你來了。正如你所看到的,任何地方你都不得不使用角度或三角函數,它只是直線性代數。