如何计算 3D 中某个点的偏航、俯仰和滚动?

How do I calculate the yaw, pitch, and roll of a point in 3D?

给定 3D 中的一个点 space,将一条线转换为指向该对象所需的三个角度(例如欧拉角)是多少?

假设我有一条 3D 线(或一个方框),我想将其航向、俯仰和坡度转换为从原点指向 3D 点,我将为这些角度使用什么值?

我无法计算出指向 (1,2,3) 等位置的角度的数学运算。

注意:我将使用 3D Math Primer for Graphics and Game Development by Fletcher Dunn.

定义的约定 "heading, pitch, bank" 而不是 "yaw, pitch, roll"

首先,请注意,在二维坐标系中,您只需要一个角度 + 大小到 "point" 到二维中的任何点。

类似地,在 3D 坐标系中,您 only need two angles + 幅度到 "point" 到 3D 中的任何点。最后一个角度("bank" 或 "roll")不影响点在 3D 中的位置。相反,它 "spins" 指向它的箭头。如果 object 是 360 度对称的,您根本不会看到旋转影响 object。如果 object 不对称(例如飞机),它将影响 object(例如将一个机翼向地面倾斜,另一个向天空倾斜)。

所以原来的问题实际上变成了,“我如何找到 "point" 到 3D space 中任意点的航向角、俯仰角和星等?”

您可以使用三角函数轻松计算出这一点。想象一下,我们有一个点 (1,2,3),我们正在尝试计算航向、俯仰、震级。

下面的例子,我们就用这张图,左轴是X轴,上轴是Y轴,右轴是Z轴。点(1,2,3),然后用蓝色球体表示。

1。求大小

首先,让我们找到最简单的值,即震级。对我们来说幸运的是,无论我们在多少维度中,都可以很容易地找到任意两点之间的大小(长度),只需使用 Pythagorean theorem。由于我们在 3D 中并且我们正在计算从原点到我们点的距离,我们的距离公式变为:

magnitude = sqrt(x*x + y*y + z*z)

插入我们的实际值:

magnitude = sqrt(1*1 + 2*2 + 3*3)
          = 3.7416573868

所以我们的幅度(或长度)是~3.741

2。找到标题

接下来,要找到航向,请注意我们只关心 XZ 平面的旋转,而根本不关心 Y-axis。如果我们要"flatten"把3Dspace变成2D,那就becomes trivial to find the heading.

我们可以画一个与 X-axis(红色三角形)成 90 度角的三角形,然后计算该角度。回忆一下三角函数 tan(angle) = opposite / adjacent,求解 angle,我们得到 angle = arctan(opposite / adjacent).

在这种情况下,"adjacent" 是已知量 (redAdjacent = x = 1),"opposite" 也是已知量 (redOpposite = z = 3)。不过,我们不想使用 arctan 来求解方程,而是想使用 atan2,因为它会为我们处理 x 和 y 的所有不同情况。

所以我们有:

heading = atan2(redOpposite, redAdjacent)

插入我们的实际值:

heading = atan2(3, 1)
        = 1.249045772398

所以我们的 航向 1.249 弧度,或 ~72°.

3。找到间距

最后我们需要找到音调。与我们对标题所做的类似,我们可以沿着包含以下三个点的平面将 3D space 展平为 2D:(A) 原点 (0,0,0),(B) 我们的点 (1,2,3),和 (C) 我们的点,因为它将投影到 XZ 平面 (1,0,3)(例如,通过为 Y-value 设置 0)。

如果我们在所有 3 个点之间画一个三角形,您会注意到它们再次形成 right-triangle(绿色三角形)。我们可以再次使用 arctan2 简单地计算角度。

我们已经在步骤 1 中计算了绿色斜边(即向量的大小):

greenHypotenuse = sqrt(x*x + y*y + z*z)
                = 3.7416573868

我们也知道绿色三角形的反面与y-value相同:

greenOpposite = y
              = 2

利用勾股定理,我们可以求出邻角的长度:

greenOpposite^2 + greenAdjacent^2 = greenHypotenuse^2
y*y + greenAdjacent^2 = x*x + y*y + z*z
greenAdjacent^2 = x*x + z*z
greenAdjacent = sqrt(x*x + z*z)

注意另一种计算绿色三角形相邻长度的方法是注意redHypotenuse == greenAdjacent,我们可以使用:

找到redHypotenuse
redHypotenuse^2 = redAdjacent^2 + redOpposite^2
                = x*x + z*z
redHypotenuse = sqrt(x*x + z*z)

代入实际值,我们得到:

greenAdjacent = sqrt(1*1 + 3*3)
              = 3.1622776602

所以现在我们知道了绿色三角形的相邻和相反的长度,我们可以再次使用arctan2

pitch = atan2(greenOpposite, greenAdjacent)
      = atan2(2, 3.1622776602)
      = 0.563942641356

所以我们的 间距 0.5634 弧度,或者大约 32°.

结论

如果您要从原点画一条线,长度为 3.741,航向为 1.249 弧度,间距为 0.564 弧度,它将从 (0,0,0) 延伸至 (1,2,3).