2011-11-17 124 views
0

我工作的一個簡單的OpenGL世界 - 到目前爲止我有一大堆的立方體隨意放置約而這是非常有趣去變焦約。不過,我準備繼續前進。我想在我的相機前面放下積木,但我在3D角度上遇到了麻煩。我已經習慣了2D的東西在哪裏可以找到一個終點,我們根本就沿着線的東西:三維從點座標和角

endy = y + (sin(theta)*power); 
endx = x + (cos(theta)*power); 

但是當我添加第三個層面我不知道該怎麼辦!在我看來,第二二維平面的力量會被z軸的COS(THETA)*功率而定,但我還不能肯定。如果這是正確的,在我看來,我會做這樣的事情:

endz = z + (sin(xtheta)*power); 

power2 = cos(xtheta) * power; 

endx = x + (cos(ytheta) * power2); 
endy = y + (sin(ytheta) * power2); 

(其中x theta是向上/向下theta和Y =左/右THETA)

難道我還差得遠在這裏正確的軌道?在給定當前點和兩個角度的情況下,如何找到終點?

回答

2

與歐拉角工作在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], 
}; 

你來了。正如你所看到的,任何地方你都不得不使用角度或三角函數,它只是直線性代數。

0

嗯,我很接近,一些測試後,我發現我的執行正確的公式,它看起來像這樣:

endy = cam.get_pos().y - (sin(toRad(180-cam.get_rot().x))*power1); 
power2 = cos(toRad(180-cam.get_rot().x))*power1; 

endx = cam.get_pos().x - (sin(toRad(180-cam.get_rot().y))*power2); 
endz = cam.get_pos().z - (cos(toRad(180-cam.get_rot().y))*power2); 

這需要我的相機的位置和旋轉角度,並得到的對應點。工程就像一個魅力=]