我在OpenGL上創建了一個非常簡單的項目,並且我被旋轉卡住了。我試圖在所有3個軸上單獨旋轉一個對象:X,Y和Z.由於圍繞一個軸旋轉後出現「萬向節鎖定」問題,我已經過了不眠之夜。然後我知道四元數會解決我的問題。我研究過四元數並實現了它,但是我還沒有能夠將旋轉轉換爲四元數。例如,如果我想圍繞Z軸旋轉90度,則只需創建四元數的{0,0,1}矢量,並使用此處的代碼圍繞該軸旋轉90度:如何從X Y Z旋轉中找到四元數的向量
http://iphonedevelopment.blogspot.com/2009/06/opengl-es-from-ground-up-part-7_04.html(最複雜的矩陣朝向底部)
對於一個矢量來說沒問題,但是,比如說,我首先要圍繞Z旋轉90度,然後圍繞X旋轉90度(就如一個例子)。我需要傳入什麼向量?我如何計算這個向量。我對矩陣和三角學不太瞭解(我知道基本知識和一般規則,但我只是不是專家),但我需要完成這些。有很多關於四元數的教程,但我似乎沒有理解(或者他們不回答我的問題)。我只需要學習構建圍繞多個軸組合的旋轉矢量。
更新:我發現這個漂亮的網頁約四元數,並決定實施他們這樣說:http://www.cprogramming.com/tutorial/3d/quaternions.html
這裏是我的四元數乘法代碼:
void cube::quatmul(float* q1, float* q2, float* resultRef){
float w = q1[0]*q2[0] - q1[1]*q2[1] - q1[2]*q2[2] - q1[3]*q2[3];
float x = q1[0]*q2[1] + q1[1]*q2[0] + q1[2]*q2[3] - q1[3]*q2[2];
float y = q1[0]*q2[2] - q1[1]*q2[3] + q1[2]*q2[0] + q1[3]*q2[1];
float z = q1[0]*q2[3] + q1[1]*q2[2] - q1[2]*q2[1] + q1[3]*q2[0];
resultRef[0] = w;
resultRef[1] = x;
resultRef[2] = y;
resultRef[3] = z;
}
這裏是我的代碼將四元數應用於我的模型視圖矩陣(我有一個tmodelview
變量,它是我的目標模型視圖矩陣):
void cube::applyquat(){
float& x = quaternion[1];
float& y = quaternion[2];
float& z = quaternion[3];
float& w = quaternion[0];
float magnitude = sqrtf(w * w + x * x + y * y + z * z);
if(magnitude == 0){
x = 1;
w = y = z = 0;
}else
if(magnitude != 1){
x /= magnitude;
y /= magnitude;
z /= magnitude;
w /= magnitude;
}
tmodelview[0] = 1 - (2 * y * y) - (2 * z * z);
tmodelview[1] = 2 * x * y + 2 * w * z;
tmodelview[2] = 2 * x * z - 2 * w * y;
tmodelview[3] = 0;
tmodelview[4] = 2 * x * y - 2 * w * z;
tmodelview[5] = 1 - (2 * x * x) - (2 * z * z);
tmodelview[6] = 2 * y * z - 2 * w * x;
tmodelview[7] = 0;
tmodelview[8] = 2 * x * z + 2 * w * y;
tmodelview[9] = 2 * y * z + 2 * w * x;
tmodelview[10] = 1 - (2 * x * x) - (2 * y * y);
tmodelview[11] = 0;
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadMatrixf(tmodelview);
glMultMatrixf(modelview);
glGetFloatv(GL_MODELVIEW_MATRIX, tmodelview);
glPopMatrix();
}
而且我對輪換代碼(我稱之爲外部),其中quaternion
是立方體的一個類變量:
void cube::rotatex(int angle){
float quat[4];
float ang = angle * PI/180.0;
quat[0] = cosf(ang/2);
quat[1] = sinf(ang/2);
quat[2] = 0;
quat[3] = 0;
quatmul(quat, quaternion, quaternion);
applyquat();
}
void cube::rotatey(int angle){
float quat[4];
float ang = angle * PI/180.0;
quat[0] = cosf(ang/2);
quat[1] = 0;
quat[2] = sinf(ang/2);
quat[3] = 0;
quatmul(quat, quaternion, quaternion);
applyquat();
}
void cube::rotatez(int angle){
float quat[4];
float ang = angle * PI/180.0;
quat[0] = cosf(ang/2);
quat[1] = 0;
quat[2] = 0;
quat[3] = sinf(ang/2);
quatmul(quat, quaternion, quaternion);
applyquat();
}
我打電話,說rotatex
,10-11次,僅轉動1度,但我在10度到1度之後,立方體旋轉近90度,這是沒有意義的。此外,在調用不同軸的旋轉函數之後,My cube會發生扭曲,變得二維,並且不可逆地消失(模型視圖矩陣中的一列全部爲零),這顯然不應該在正確實現四元數時發生。
你想獲得四元數的幫助嗎?或者想旋轉一個物體? – Beta 2012-03-25 20:52:46
好吧,我已經走了四元數路徑並編寫代碼,所以如果你有一個涉及四元數的旋轉解決方案,它會很有幫助。我只需要實現的就是能夠在3D空間中旋轉3個自由度的物體 – 2012-03-25 20:54:38
也許Jack Kuipers的書籍「Quaternions and Rotations Sequences」可能對您有所幫助。關於X-Y-Z旋轉(又名歐拉角)有很多說法。例如,你是圍繞舊的X軸還是新的軸旋轉(「附加」到你旋轉的物體上)? – ascobol 2012-03-25 21:20:25