【问题标题】:Arcball camera zooming弧球相机变焦
【发布时间】:2018-04-24 09:51:39
【问题描述】:

我正在尝试通过鼠标移动来更改相机视图,并希望相机以轨迹球方式围绕原点移动而不进入场景;有点像圆顶的视图。

以下内容可以令人满意地获取眼睛坐标并制作这个半弧形视图。我硬编码了一个条件,以便我无法在场景下方查看。这种情况的后果是,相机不会进入场景下方,而是会放大到中心。我无法思考如何阻止相机进行这种“变焦”。当我到达穹顶视图的最低部分时,我希望只能向左或向右移动。距离是恒定的。有什么指导吗?

void onMotion(int x, int y) {
    camX = distance * -sinf(x*(M_PI / 180)) * cosf((y)*(M_PI / 180));
    camY = distance * -sinf((y)*(M_PI / 180));
    camZ = -distance * cosf((x)*(M_PI / 180)) * cosf((y)*(M_PI / 180));
    if (camY < 4) 
        camY = 4;
    glutPostRedisplay();
}

【问题讨论】:

  • 距离有变化吗?或者,如果没有,您的视野是否正在改变?这也可能导致缩放效果。
  • @user1118321,没有距离是静态的。如何检查 FOV 是否在变化?
  • 视野由投影矩阵控制。如果它发生变化,它可能会产生缩放效果。
  • 知道了。但它也没有改变。

标签: c opengl camera


【解决方案1】:

我认为这是因为当camY

您需要使用新的 y 坐标重新计算所有内容,而不仅仅是设置 camY 变量。您可以将camY 设置为4,然后将camXcamZ 推回到新方向上的适当距离。像这样的:

if (camY < 4)
{
    camY = 4;
    // Normalize the new vector
    mag = sqrt(camX * camX + camY * camY + camZ * camZ);
    camX /= mag;
    camY /= mag;
    camZ /= mag;

    // Now push it out to distance
    camX *= distance;
    camY *= distance;
    camZ *= distance;
}

【讨论】:

    【解决方案2】:

    你不需要约束结果坐标而是输入角度:

    4 <= distance * -sin(y)
    -4 / distance >= sin(y)
    //Assuming y is always between -PI/2 and PI/2
    arc sin(-4 / distance) >= y
    

    因此,在开始时执行以下操作:

    double yAngle = y * M_PI / 180;
    double yThreshold = std::asin(-4.0 / distance);
    if(yAngle > yThreshold)
        yAngle = yThreshold;
    

    然后使用yAngle 代替y

    顺便说一句,您从鼠标坐标到角度的映射似乎有点奇怪。我不确定上述公式中的假设是否成立。因此,您可能需要调整代码。更好的是,调整计算角度的方式。它可能应该考虑窗口大小。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-23
      • 1970-01-01
      • 2019-03-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多