简体   繁体   English

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

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

Given a point in 3D space, what are the three angles (eg Euler angles) needed to transform a line to point to that object?给定 3D 空间中的一个点,将一条线转换为指向该 object 所需的三个角度(例如欧拉角)是多少?

Imagine I have a line (or a box) in 3D and I want to transform its heading, pitch, and bank to point to the 3D point from the origin, what values would I use for those angles?想象一下,我在 3D 中有一条线(或一个框),我想将它的航向、俯仰和坡度转换为从原点指向 3D 点,这些角度我将使用什么值?

I can't figure out the math to calculate the angles to point to a location such as (1,2,3) .我无法计算出数学来计算指向(1,2,3)等位置的角度。

Note: Instead of "yaw, pitch, roll", I'm going to use the conventions "heading, pitch, bank" as defined by 3D Math Primer for Graphics and Game Development by Fletcher Dunn .注意:我将使用3D Math Primer for Graphics and Game Development by Fletcher Dunn定义的约定“航向、俯仰、倾斜”,而不是“偏航、俯仰、滚动”。

Firstly, notice that in a 2D coordinate system, you only need a single angle + magnitude to "point" to any point in 2D.首先,请注意,在 2D 坐标系中,您只需要一个角度 + 幅度即可“指向”2D 中的任何点。

Similarly, in a 3D coordinate system, you only need two angles + magnitude to "point" to any point in 3D.同样,在 3D 坐标系中,您只需要两个角度+ 幅度即可“指向”3D 中的任何点。 The last angle ("bank" or "roll") does not affect the location of a point in 3D.最后一个角度(“bank”或“roll”)不影响 3D 中点的位置。 Instead it "spins" the arrow that would point to it.相反,它会“旋转”指向它的箭头。 If the object is 360 degrees symmetrical, you won't see spin affecting the object at all.如果 object 是 360 度对称的,则根本不会看到影响 object 的自旋。 If the object is not symmetrical (eg an airplane) it will affect the object (eg tilting one wing towards the ground and the other towards the sky).如果 object 不对称(例如飞机),它将影响 object(例如,将一个机翼向地面倾斜,另一个向天空倾斜)。

So the original question actually becomes, "how do I find the heading angle, pitch angle, and magnitude to "point" to any point in 3D space?"所以最初的问题实际上变成了,“我如何找到航向角、俯仰角和幅度来“指向”3D 空间中的任何点?

You can easily figure this out using trigonometry functions.您可以使用三角函数轻松计算出这一点。 Imagine we have the point (1,2,3) and we're trying to calculate the heading, pitch, magnitude.假设我们有点(1,2,3) ,我们正在尝试计算航向、俯仰、幅度。

For the following example, let's use this diagram, where the left axis is X, up is Y, and right is Z. The point (1,2,3) , then is represented by the blue sphere.对于以下示例,让我们使用此图,其中左轴为 X,上轴为 Y,右轴为 Z。点(1,2,3)则由蓝色球体表示。

在此处输入图像描述

1. Find the magnitude 1. 找出量级

First, let's find the easiest value, the magnitude.首先,让我们找到最简单的值,即幅度。 Luckily for us, the magnitude (length) between any two points is easy to find no matter how many dimensions we are in, simply by using the Pythagorean theorem .对我们来说幸运的是,只要使用勾股定理,任何两点之间的大小(长度)都很容易找到,无论我们有多少维。 Since we are in 3D and we're calculating the distance from the origin to our point, our distance formula becomes:由于我们在 3D 并且我们正在计算从原点到我们点的距离,我们的距离公式变为:

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

Plugging in our actual values:插入我们的实际值:

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

So our magnitude (or length) is ~ 3.741 .所以我们的大小(或长度)是 ~ 3.741

2. Find the heading 2.找到标题

Next, to find the heading, notice that we just care about rotation about the XZ plane, and we don't care about the Y-axis at all.接下来,要找到航向,请注意我们只关心围绕 XZ 平面的旋转,而根本不关心 Y 轴。 If we were to "flatten" the 3D space into 2D, it becomes trivial to find the heading .如果我们要将 3D 空间“展平”为 2D 空间,则查找标题变得微不足道

We can draw a triangle that forms a 90 degree angle with the X-axis (red triangle) and then calculate that angle.我们可以画一个三角形 forms 与 X 轴成 90 度角(红色三角形),然后计算该角度。 Recall from trigonometry tan(angle) = opposite / adjacent , and solving for angle , we get angle = arctan(opposite / adjacent) .回忆三角函数tan(angle) = opposite / adjacent ,求解angle ,我们得到angle = arctan(opposite / adjacent)

In this case "adjacent" is a known quantity ( redAdjacent = x = 1 ), and "opposite" is known too ( redOpposite = z = 3 ).在这种情况下,“相邻”是一个已知量( redAdjacent = x = 1 ),“相反”也是已知的( redOpposite = z = 3 )。 Instead of using arctan to solve the equation though, we want to use atan2 since it'll handle all the different cases of x and y for us.我们不想使用 arctan 来求解方程,而是使用atan2 ,因为它会为我们处理 x 和 y 的所有不同情况。

So we have:所以我们有:

heading = atan2(redOpposite, redAdjacent)

Plugging in our actual values:插入我们的实际值:

heading = atan2(3, 1)
        = 1.249045772398

so our heading is 1.249 rad, or ~ 72° .所以我们的航向1.249 rad,或 ~ 72°

3. Find the pitch 3.找到音高

Finally we need to find the pitch.最后,我们需要找到音高。 Similarly to what we did with the heading, we can flatten the the 3D space into 2D along the plane that contains these three points: (A) the origin (0,0,0) , (B) our point (1,2,3) , and (C) our point as it would project onto the XZ plane (1,0,3) (eg by setting 0 for the Y-value).与我们对标题所做的类似,我们可以将 3D 空间沿包含这三个点的平面展平为 2D:(A)原点(0,0,0) ,(B)我们的点(1,2,3)和 (C) 我们的点,因为它将投影到 XZ 平面(1,0,3) (例如,通过将 Y 值设置为 0)。

If we draw a triangle between all 3 of these points, you will notice that they form a right-triangle again (green triangle).如果我们在这三个点之间画一个三角形,你会注意到它们又形成了一个直角三角形(绿色三角形)。 We can simply calculate the angle using arctan2 again.我们可以再次使用arctan2简单地计算角度。

We already calculated the green hypotenuse in step 1 (ie the magnitude of our vector):我们已经在步骤 1 中计算了绿色斜边(即我们的向量的大小):

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

We also know the opposite of the green triangle is the same as the y-value:我们还知道绿色三角形的对面与 y 值相同:

greenOpposite = y
              = 2

Using the pythagorean theorem, we can find the length of the adjacent angle:使用勾股定理,我们可以找到相邻角的长度:

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)

Notice that another way to calculate the adjacent length of the green triangle is to notice that redHypotenuse == greenAdjacent , and we could find redHypotenuse using:请注意,计算绿色三角形相邻长度的另一种方法是注意redHypotenuse == greenAdjacent ,我们可以使用以下方法找到redHypotenuse

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

Plugging in actual values, we get:插入实际值,我们得到:

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

So now that we know the adjacent and opposite lengths of the green triangle, we can use arctan2 again:所以现在我们知道了绿色三角形的相邻和相反的长度,我们可以再次使用arctan2

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

So our pitch is 0.5634 radians, or about 32° .所以我们的间距0.5634弧度,或大约32°

Conclusion结论

If you were to draw a line from the origin, with length 3.741 , heading 1.249 rad, and pitch 0.564 rad, it would extend from (0,0,0) to (1,2,3) .如果要从原点画一条线,长度为3.741 ,航向为1.249弧度,间距为0.564弧度,它将从(0,0,0)延伸到(1,2,3)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM