代码之家  ›  专栏  ›  技术社区  ›  rafvasq

电弧球相机变焦

  •  3
  • rafvasq  · 技术社区  · 7 年前

    我试图通过鼠标移动来更改相机视图,并希望相机在不进入场景的情况下以弧形方式围绕原点移动;有点像圆顶。

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

    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();
    }
    
    2 回复  |  直到 7 年前
        1
  •  2
  •   user1118321    7 年前

    我认为这是因为你没有固定距离 camY <4、想想当摄像机接近你的球体南极时。将y坐标设置为4,但x和z仍然靠近轴。

    而不仅仅是设置 凯美 凯美 到4,然后按 camX camZ 在新方向上返回到适当的距离。类似这样:

    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
  •  2
  •   Nico Schertler    7 年前

    您不需要约束结果坐标,但需要约束输入角度:

    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 .

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