gpt4 book ai didi

java - 如何避免相机在四元数旋转时翻转?

转载 作者:行者123 更新时间:2023-11-30 11:45:22 25 4
gpt4 key购买 nike

我有一个使用四元数围绕固定点旋转的相机。问题是当相机绕 x 轴旋转并经过一根杆子时,相机会翻转并产生镜像。这是有道理的,因为相机面向相反的方向,但相机的向上 vector 没有改变。显然,需要根据外观 vector 和正确的 vector 计算出一个新的向上 vector ,但我似乎无法让它工作。注意:这使用 http://commons.apache.org/math/api-2.2/org/apache/commons/math/geometry/Rotation.html来表示四元数。

无论如何,我正在使用以下基本过程来旋转相机。

旋转四元数初始化为身份 [1, 0, 0, 0]:

private Rotation total = Rotation.IDENTITY;

相机的向上 vector 初始化为:

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 和 rotation 由按键生成,如下所示:

@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);

最佳答案

你在做一些奇怪的事情。一个单位四元数表示一个完整的方向。你通常不会用它来使用“向上” vector 。但是......看起来你可以通过使用常量“向上” vector [0,1,0] 而不是从四元数中获取它来获得你想要的效果。

听起来您真的不需要四元数。你想要的是 [0,1,0] 的常量“向上” vector 。然后你想要一个“在”点,它总是你在轨道上运行的点。然后,您需要一个“眼睛”点,它可以(相对于您的轨道点)围绕 y 轴或围绕由您的“向上” vector 与您的轨道点和'眼睛'点。

关于java - 如何避免相机在四元数旋转时翻转?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10354059/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com