因此,我在OpenGL場景中爲我的3D對象實現旋轉,到目前爲止基本旋轉本身(使用四元數)工作正常。我也大多解決了「查看」問題,這樣我就可以使任何3D對象,包括相機在內,精確無誤地面對3D空間中的任何點。當只需要X-Y旋轉時,3D對象正在沿着所有三個軸旋轉
然而,指揮的對象時面對一個給定的點,這將經常沿其局部Z軸滾動;看到這張圖片,小船正在看紅色,綠色和藍色線條交匯點。你可以看到它看起來不像人們所期望的那樣,例如,沿着它的Y軸旋轉面對綠線,然後沿着它的X軸向下傾斜以面對三條線的交匯點。
我並不想這樣。我寧願直視那一點,但順時針傾斜一點(從正面看),使它的翼尖處於相同的Y水平。由於面向某一點的整個點是局部Z軸穿過該點,所以不應該如何繞物體的本地Z軸旋轉物體,但結果的旋轉始終傾斜,儘管偏斜似乎取決於物體的相對位置及其焦點。
在任何情況下,這裏是我的LookAt()代碼,我想要修改這些代碼,以便我可以更好地控制最終的Z軸旋轉。
void Thing::LookAt(sf::Vector3<float> Target)
{
///Derived from pseudocode found here:
///http://stackoverflow.com/questions/13014973/quaternion-rotate-to
//Reset the rotation to default
m_Orientation = Quaternion();
//Get the normalized vector from the camera position to Target
sf::Vector3<double> VectorTo(Target.x - m_Position.x,
Target.y - m_Position.y,
Target.z - m_Position.z);
//Get the length of VectorTo
double VectorLength = sqrt(VectorTo.x*VectorTo.x +
VectorTo.y*VectorTo.y +
VectorTo.z*VectorTo.z);
//Normalize VectorTo
VectorTo.x /= VectorLength;
VectorTo.y /= VectorLength;
VectorTo.z /= VectorLength;
//Straight-ahead vector
sf::Vector3<double> LocalVector = m_Orientation.MultVect(sf::Vector3<double>(0, 0, -1));
//Get the cross product as the axis of rotation
sf::Vector3<double> Axis(VectorTo.y*LocalVector.z - VectorTo.z*LocalVector.y,
VectorTo.z*LocalVector.x - VectorTo.x*LocalVector.z,
VectorTo.x*LocalVector.y - VectorTo.y*LocalVector.x);
//Normalize the axis
//Get the length of VectorTo
double AxisLength = sqrt(Axis.x*Axis.x +
Axis.y*Axis.y +
Axis.z*Axis.z);
//Normalize VectorTo
Axis.x /= AxisLength;
Axis.y /= AxisLength;
Axis.z /= AxisLength;
//Get the dot product to find the angle
double DotProduct = (VectorTo.x*LocalVector.x +
VectorTo.y*LocalVector.y +
VectorTo.z*LocalVector.z);
double Angle = acos(DotProduct);
//Determine whether or not the angle is positive
//Get the cross product of the axis and the local vector
sf::Vector3<double> ThirdVect(Axis.y*LocalVector.z - Axis.z*LocalVector.y,
Axis.z*LocalVector.x - Axis.x*LocalVector.z,
Axis.x*LocalVector.y - Axis.y*LocalVector.x);
//If the dot product of that and the local vector is negative, so is the angle
if (ThirdVect.x*VectorTo.x + ThirdVect.y*VectorTo.y + ThirdVect.z*VectorTo.z < 0)
{
Angle = -Angle;
}
//Finally, create a quaternion
//Quaternion AxisAngle;
m_Orientation.FromAxisAngle(Angle, Axis.x, Axis.y, Axis.z);
m_Orientation.RotationMatrix(m_RotationMatrix);
}
我的問題是,我不知道如何獲得對圍繞Z軸的最終旋轉的控制。請注意,當我從m_Orientation四元數中提取一個Z角時,它告訴我上圖所示的船繞其Z軸旋轉0弧度。我嘗試手動將Z分量設置爲0並重新正常化四元數,但是(顯然我猜)沒有工作。目前,可以很好地計算船舶旋轉「頂部向上」所需的特定Z分量,即,使得其兩個翼尖處於相同的Y水平上並且其Y軸陡峭儘可能,但我想更清楚地知道如何操作最終的Z軸旋轉。任何想法或資源?
謝謝!儘管最終的結果是船舶顛倒倒退,但這種方式大多可行。我發現我需要使向上的向量爲'(0,-1,0)',並且X軸向量爲'-VectorTo',以便船舶正確定位。這可能意味着我在代碼中犯了一個錯誤,我確信我會找到它。另一個說明,這是否意味着沒有簡單的方法直接與四元數做到這一點? IIRC Unity引擎的四元數可以佔用一個向量(http://docs.unity3d.com/Documentation/ScriptReference/Quaternion.LookRotation.html),它們也可以在引擎蓋下使用矩陣嗎? – GarrickW
這聽起來像你真的需要轉置矩陣。但是,如果你有一個工作解決方案,沒關係。可能有一種方法可以直接計算四元數。但是,我不能說如何。 –