给出3D空间中的一个点,将一条线转换为指向该对象所需的三个角度(例如欧拉角)是什么?
想象一下我在3D中有一条线(或一个盒子),我想转换其航向,俯仰和倾斜以从原点指向3D点,我将使用那些角度的值?
我无法计算出指向诸如(1,2,3)
之类的位置的角度的数学。
注意:我将使用3D Math Primer for Graphics and Game Development by Fletcher Dunn定义的约定“航向,俯仰,倾斜”,而不是“偏航,俯仰,滚动”。
首先,请注意,在2D坐标系中,只需一个角度+大小即可“指向” 2D中的任何点。
类似地,在3D坐标系中,您only need two angles +幅度可“指向” 3D中的任何点。最后一个角度(“倾斜”或“横滚”)不影响3D中点的位置。而是“旋转”指向它的箭头。如果对象是360度对称的,则根本不会看到旋转影响对象。如果物体不对称(例如飞机),则会影响物体(例如,将一侧机翼向地面倾斜,将另一侧机翼向天空倾斜)。
因此,最初的问题实际上变成了:“我如何找到航向角,俯仰角和大小以“指向” 3D空间中的任何点?”
您可以使用三角函数轻松解决这一问题。想象一下,我们有点(1,2,3)
,我们正在尝试计算航向,俯仰,幅度。
对于下面的示例,我们使用此图,其中左轴为X,上轴为Y,右轴为Z。然后,(1,2,3)
点由蓝色球体表示。
首先,让我们找到最简单的值,即幅度。对我们来说幸运的是,无论我们处于多少维度,都可以轻松找到任意两点之间的大小(长度),只需使用Pythagorean theorem。由于我们处于3D状态,并且我们正在计算从原点到我们点的距离,因此我们的距离公式变为:
magnitude = sqrt(x*x + y*y + z*z)
使用我们的实际值:
magnitude = sqrt(1*1 + 2*2 + 3*3)
= 3.7416573868
所以我们的幅度(或长度)是〜3.741
。
[接下来,要找到标题,请注意,我们只关心绕XZ平面的旋转,而根本不关心Y轴。如果我们要将3D空间“展平”为2D,则为becomes trivial to find the heading。
我们可以绘制一个与X轴成90度角的三角形(红色三角形),然后计算该角度。回忆三角函数tan(angle) = opposite / adjacent
,求解angle
,得到angle = arctan(opposite / adjacent)
。
在这种情况下,“相邻”是已知数量(redAdjacent = x = 1
),而“相反”也是已知数量(redOpposite = z = 3
)。但是,我们不想使用arctan来求解方程,而是要使用atan2,因为它将为我们处理x和y的所有不同情况。
所以我们有:
heading = atan2(redOpposite, redAdjacent)
使用我们的实际值:
heading = atan2(3, 1)
= 1.249045772398
所以我们的heading是1.249
rad,或〜72°
。
最后,我们需要找到音高。与航向相似,我们可以沿着包含以下三个点的平面将3D空间展平为2D:(A)原点(0,0,0)
,(B)我们的点(1,2,3)
和(C)我们的点,因为它将投影到XZ平面(1,0,3)
上(例如,通过将Y值设置为0)。
如果我们在所有这三个点之间绘制一个三角形,您会注意到它们再次形成了直角三角形(绿色三角形)。我们可以再次简单地使用arctan2
计算角度。
我们已经在第1步中计算了绿色斜边(即向量的大小):
greenHypotenuse = sqrt(x*x + y*y + z*z)
= 3.7416573868
我们也知道绿色三角形的对面与y值相同:
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
所以我们的pitch是0.5634
弧度,或大约32°
。
如果从原点画一条线,长度为3.741
,标题为1.249
rad,螺距为0.564
rad,它将从(0,0,0)
延伸到(1,2,3)
。