使用鼠标事件计算相机的位置和旋转

4

我的计划:

1. 计算鼠标方向 [x, y] [成功]

在我的鼠标移动事件中:

int directionX = lastPosition.x - position.x;
int directionY = lastPosition.y - position.y;

2. 计算角度 [theta, phi] [成功]

float theta = fmod(lastTheta + sensibility * directionY, M_PI);
float phi = fmod(lastPhi + sensibility * directionX * -1, M_PI * 2);

编辑 {

错误修复:

float theta = lastTheta + sensibility * directionY * -1;
if (theta < M_PI / -2)theta = M_PI / -2;
else if (theta > M_PI / 2)theta = M_PI / 2;

float phi = fmod(lastPhi + sensibility * directionX * -1, M_PI * 2);

现在我已经有了theta、phi、中心点和半径,我想要计算相机看向中心点时的位置和旋转。

3. 计算位置坐标[X,Y,Z] [失败]

float newX = radius * sin(phi) * cos(theta);
float newY = radius * sin(phi) * sin(theta);
float newZ = radius * cos(phi);

解决方案 [由meowgoesthedog提供]:

float newX = radius * cos(theta) * cos(phi);
float newY = radius * sin(theta);
float newZ = radius * cos(theta) * sin(phi);

4. 计算旋转 [失败]



float pitch = ?;
float yaw = ?;

解决方案[由meowgoesthedog提供]:

float pitch = -theta;
float yaw = -phi;

感谢您的解决方案!


请参阅Trackball,也称为“arcball”。 - Ripi2
@Ripi2 谢谢,我会阅读它。 - Max Mister
1个回答

2

你的尝试几乎(有点)正确:

  • 如图所示,在OpenGL中,“垂直”方向通常被认为是Y,而你的公式假设它是Z

  • phitheta的顺序错误了

  • 非常简单的转换:yaw = -phipitch = -theta(从相机的角度来看)

修正后的公式:

float position_X = radius * cos(theta) * cos(phi);
float position_Y = radius * sin(theta);
float position_Z = radius * cos(theta) * sin(phi);

(鼠标增量可能也存在一些符号问题,但很容易解决。)

谢谢你的回答。俯仰和偏航可以工作,但位置不行,之前 X 轴可以工作,现在两个轴都不行了。 - Max Mister
@maxmister 抱歉 - 具有讽刺意味的是,我犯了我指出的错误。已修复。 - meowgoesthedog
谢谢,现在x和z可以工作了,但是y只能达到70%的效果,因为如果theta在3.14159和3.13159之间变化,模型会迈出巨大的一步。 - Max Mister
@MaxMister theta(与XZ平面的夹角)定义在范围[-pi/2, pi/2]内。您超出了其范围。(phi[0, 2pi]内)。 - meowgoesthedog

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接