我有一個使用四元數圍繞固定點的相機。問題是,當相機圍繞x軸旋轉並通過杆時,相機將翻轉併產生鏡像圖像。這是有道理的,因爲相機朝向相反的方向,但相機的向上矢量沒有改變。顯然,一個新的矢量需要從外觀矢量和正確的矢量來計算,但是我似乎無法使它工作。注意:這使用http://commons.apache.org/math/api-2.2/org/apache/commons/math/geometry/Rotation.html來表示四元數。如何避免相機翻轉四元數旋轉?
無論如何,我正在使用以下基本步驟來旋轉相機。
旋轉四元數被初始化到身份[1,0,0,0]:
private Rotation total = Rotation.IDENTITY;
和照相機的向上矢量被初始化爲:
private Vector3D up = new Vector3D(0, 1, 0);
旋轉完成通過將相機的當前旋轉存儲爲四元數,然後將任何後續旋轉應用於該四元數,然後將組合的四元數(總數)用於旋轉相機的位置。下面的代碼描述此過程:
/**
* Rotates the camera by combining the current rotation (total) with any new axis/angle representation of a new rotation (newAxis, rotation).
*/
public void rotateCamera() {
if (rotation != 0) {
//Construct quaternion from the new rotation:
Rotation local = new Rotation(Math.cos(rotation/2), Math.sin(rotation/2) * newAxis.getX(), Math.sin(rotation/2) * newAxis.getY(), Math.sin(rotation/2) * newAxis.getZ(), true);
//Generate new camera rotation quaternion from current rotation quaternion and new rotation quaternion:
total = total.applyTo(local);
//Rotate the position of the camera using the camera rotation quaternion:
cam = rotateVector(local, cam);
//rotation is complete so set the next rotation to 0
rotation = 0;
}
}
/**
* Rotate a vector around a quaternion rotation.
*
* @param rotation The quaternion rotation.
* @param vector A vector to be rotated.
* @return The rotated vector.
*/
public Vector3D rotateVector(Rotation rotation, Vector3D vector) {
//set world centre to origin, i.e. (width/2, height/2, 0) to (0, 0, 0)
vector = new Vector3D(vector.getX() - width/2, vector.getY() - height/2, vector.getZ());
//rotate vector
vector = rotation.applyTo(vector);
//set vector in world coordinates, i.e. (0, 0, 0) to (width/2, height/2, 0)
return new Vector3D(vector.getX() + width/2, vector.getY() + height/2, vector.getZ());
}
字段newAxis和旋轉,其存儲任何新的旋轉的軸/角度通過按鍵產生如下:
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_W) {
camera.setAxis(new Vector3D(1, 0, 0));
camera.setRotation(0.1);
}
if (e.getKeyCode() == KeyEvent.VK_A) {
camera.setAxis(new Vector3D(0, 1, 0));
camera.setRotation(0.1);
}
if (e.getKeyCode() == KeyEvent.VK_S) {
camera.setAxis(new Vector3D(1, 0, 0));
camera.setRotation(-0.1);
}
if (e.getKeyCode() == KeyEvent.VK_D) {
camera.setAxis(new Vector3D(0, 1, 0));
camera.setRotation(-0.1);
}
}
在每個呈現循環的rotateCamera ()方法被調用,然後下面的代碼設置相機:
glu.gluLookAt(camera.getCam().getX(), camera.getCam().getY(), camera.getCam().getZ(), camera.getView().getX(), camera.getView().getY(), camera.getView().getZ(), 0, 1, 0);
我不明白你爲什麼使用gluLookAt,它會計算相機的位置和你想看的東西的旋轉。如果您已經自己計算旋轉角度,爲什麼不直接設置視圖矩陣? – Ishtar 2012-04-27 17:39:59