2012-12-26 62 views
1

我基本上正在爲slerping工作,雖然它有點作品,它有一個奇怪的視角扭曲問題,我卡住試圖解決現在。Slerp問題,透視變形

Quaternion sLerp(Quaternion start, Quaternion end, float s) 
{ 
    float dot = qDot(start, end); 
    float theta = std::acos(dot); 
    float sTheta = std::sin(theta); 

    float w1 = sin((1.0f-s)*theta)/sTheta; 
    float w2 = sin(s*theta)/sTheta; 

    Quaternion Temp(0,0,0,0); 

    Temp = start*w1 + end*w2; 

    return Temp; 
} 

它做什麼本質(或應該做的)只是兩個值之間slerping提供旋轉,從這個結果被轉換爲旋轉矩陣。但是有什麼問題是一個可怕的,可怕的拉伸視圖......出於某種原因,在旋轉過程中,它拉伸了所有的東西,從一切太長/很薄開始,到達一個更短的中間點,然後開始變回細長。任何幫助都會很棒。

+0

圖形會有所幫助。這不就是一個數學問題嗎? –

回答

1

你球面線性插值代碼看起來很好,儘管人們通常會確保dot>=0因爲否則的話,你旋轉很長的路要走在圓周圍。一般來說,確保dot!=1也是很重要的,因爲你會遇到除以的問題。

適當的四元數不應該拉伸視圖。要麼你傳遞非單位長度的四元數爲startend,或者你的四元數到矩陣的代碼是可疑的(或者你正在得到時髦的行爲,因爲兩個四元數之間的角度非常小,幾乎爲零)。


我從四元數轉換成矩陣用於在OpenGL代碼:

// First row 
glMat[ 0] = 1.0f - 2.0f * (q[1] * q[1] + q[2] * q[2]); 
glMat[ 1] = 2.0f * (q[0] * q[1] + q[2] * q[3]); 
glMat[ 2] = 2.0f * (q[0] * q[2] - q[1] * q[3]); 
glMat[ 3] = 0.0f; 

// Second row 
glMat[ 4] = 2.0f * (q[0] * q[1] - q[2] * q[3]); 
glMat[ 5] = 1.0f - 2.0f * (q[0] * q[0] + q[2] * q[2]); 
glMat[ 6] = 2.0f * (q[2] * q[1] + q[0] * q[3]); 
glMat[ 7] = 0.0f; 

// Third row 
glMat[ 8] = 2.0f * (q[0] * q[2] + q[1] * q[3]); 
glMat[ 9] = 2.0f * (q[1] * q[2] - q[0] * q[3]); 
glMat[10] = 1.0f - 2.0f * (q[0] * q[0] + q[1] * q[1]); 
glMat[11] = 0.0f; 

// Fourth row 
glMat[12] = 0.0; 
glMat[13] = 0.0; 
glMat[14] = 0.0; 
glMat[15] = 1.0f; 
+0

嘿,四元組傳入的是 start(0.92388f,0.f,-0.38268f,0.f); 結束(0.85862f,0.11304f,0.49572f,-0.06526f);矩陣4×4(1-4 * Y-4 * Z,2 *(X * Y)-2 *(W * Z),2 *(X * Z)+ 2 *(W * Y),0, \t \t \t \t \t \t \t \t \t \t 2 *(X * Y)+ 2 *(W * Z),1-4 * X - 4 * Z,2 *(Y * Z) - 2 *(W * X),0, \t \t \t \t \t \t \t \t \t \t 2 *(X * Z) - 2 *(W * Y),2 *(Y * Z)+ 2 *(W * X),1-4 * X-4 * Y,0, \t \t \t \t \t \t \t \t \t \t 0,0,0,1); 對不起,如果它的可怕間隔...但是四元數是作爲那些給出的,矩陣部分是從一本書/網頁中拿出來的,因爲他們彼此都認爲是這樣。 – user1930625

+0

@ user1930625這不是正確的轉換代碼。你誤以爲「乘以2」是「平方」。 [0,0]元素應該是:'1.0f - 2.0f *(Y * Y + Z * Z)' – JCooper

0

您是否需要規範化四元數?

我認爲以下幾點:

float sTheta = std::sin(theta); 

應該是:

float sTheta = sqrt(1.0f - sqr(theta)); 
+0

嘿,這不應該是問題,但我們試過了,不是解決方案大聲笑,雖然看到結果是相當有趣的..但是..我真的不確定問題是什麼,因爲它甚至仍然使用時拉伸所有。 – user1930625