如何在 3D 中计算相对于相机视角方向的方位角和仰角......?



我在这里有点生疏。

我有一个矢量(camDirectionX,camDirectionY,camDirectionZ)代表我的相机视角。我有一个(camX,camY,camZ)这是我的相机位置。

然后,我有一个对象放置在(对象X,对象Y,对象Z)

如何从相机的角度计算物体的方位角和仰角?

为了简化问题,我要做的第一件事是变换坐标空间,使相机位于 (0, 0, 0) 并直接指向其中一个轴(因此方向是 (0, 0, 1))。平移使相机位于(0,0,0)是相当微不足道的,所以我不会讨论。旋转以使相机方向为(0,0,1)有点棘手...

一种方法是构建相机的完整正交基础,然后将其粘贴到旋转矩阵中并应用它。相机的"正交基础"是一种奇特的说法,用于表示从相机向前、向上和向右指向的三个矢量。它们都应该彼此成 90 度(这就是正交位的含义),并且它们的长度都应该为 1(这是正常位的含义)。

你可以通过一些跨积技巧得到这些向量:两个向量的叉积垂直(90度)与两个向量垂直。

为了获得朝右的矢量,我们可以将相机方向矢量与(0, 1, 0)(一个指向正上方的矢量)交叉乘积。您需要对从交叉积中获得的向量进行归一化。

为了获得相机的向上矢量,我们可以将相机方向矢量与我们刚刚计算的右向矢量交叉乘积。假设两个输入向量都进行了归一化,则不需要归一化。

我们现在有了相机的正交基础。如果我们将这些向量粘贴到 3x3 矩阵的行中,我们会得到一个旋转矩阵,该矩阵将转换我们的坐标空间,因此相机将直接指向其中一个轴(这取决于您粘贴矢量的顺序)。

现在计算物体的方位角和高程相当容易。

要获取方位角,只需对对象的 x/z 坐标进行atan2

要获得高程,请将对象坐标投影到 x/z 平面上(只需将 y 坐标设置为 0),然后执行以下操作:

acos(dot(normalise(object coordinates), normalise(projected coordinates)))

这将始终给出一个正角度 - 如果对象的 y 坐标小于 0,您可能希望将其取反。

所有这些代码将如下所示:

fwd = vec3(camDirectionX, camDirectionY, camDirectionZ)
cam = vec3(camX, camY, camZ)
obj = vec3(objectX, objectY, objectZ)
# if fwd is already normalised you can skip this
fwd = normalise(fwd)
# translate so the camera is at (0, 0, 0)
obj -= cam
# calculate the orthonormal basis of the camera
right = normalise(cross(fwd, (0, 1, 0)))
up = cross(right, fwd)
# rotate so the camera is pointing straight down the z axis
# (this is essentially a matrix multiplication)
obj = vec3(dot(obj, right), dot(obj, up), dot(obj, fwd))
azimuth = atan2(obj.x, obj.z)
proj = vec3(obj.x, 0, obj.z)
elevation = acos(dot(normalise(obj), normalise(proj)))
if obj.y < 0:
    elevation = -elevation

需要注意的一件事是,当您的相机朝上或朝下时,原始相机矢量与 (0, 1, 0) 的交叉乘积将返回零长度矢量。为了完全定义相机的方向,我假设它总是"直的",但是当它朝上或朝下时,这没有任何意义 - 你需要另一个规则。

最新更新