【问题标题】:Calculate rotations to look at a 3D point?计算旋转以查看 3D 点?
【发布时间】:2019-04-12 21:59:26
【问题描述】:

我需要计算 3D 对象面对任意 3D 点的 2 个角度(偏航角和俯仰角)。这些旋转被称为“欧拉”旋转,因为在第一次旋转之后(假设 Z,基于下图),Y 轴也随着对象旋转。

这是我正在使用的代码,但它不能完全工作。在地平面 (Y = 0) 上,对象正确旋转以面对该点,但只要我在 Y 中向上移动该点,旋转看起来就不正确。

// x, y, z represent a fractional value between -[1] and [1]
// a "unit vector" of the point I need to rotate towards

yaw = Math.atan2( y, x )
pitch = Math.atan2( z, Math.sqrt( x * x + y * y ) )

你知道如何计算给定一个点的 2 个欧拉角吗?


下图显示了我旋转的方式。这些是我需要计算的角度。 (唯一的区别是我按 X、Y、Z 的顺序旋转对象,而不是 Z、Y、X)


这是我的系统。

  • 坐标系是 x = 向右,y = 向下,z = 更靠后
  • 默认情况下,对象位于 (0,0,1) 处,面向后
  • 旋转的顺序是 X、Y、Z,其中在 X 上的旋转是俯仰,Y 是偏航,Z 是滚动

【问题讨论】:

  • 当您说“在 Y 中向上移动对象”时,您的意思是“在 Y 中向上移动点”吗?物体在旋转前朝向哪个方向?
  • @Beta - 是的,我就是这个意思。对象在旋转前朝后,就像站在桌子上一样。
  • 你好@Robinicks,你能告诉我你在哪里拍的照片i53.tinypic.com/33lo6jp.jpg好吗?
  • @GennaroArguzzi - 我在 Adob​​e Flash 中设计了该图形
  • 你好@Robinicks,我参考了上面那个,请看上面的链接。

标签: math 3d rotation angle euler-angles


【解决方案1】:

这是我的工作假设:

  • 坐标系 (x,y,z) 使得 x 正向向右,y 正向向下,z 为剩余方向。特别是,y=0 是地平面。
  • (0,0,0) 处当前面向 (0,0,1) 的对象正在转向面向 (x,y,z)。
  • 为了实现这一点,将先绕 x 轴旋转,然后绕 y 轴旋转。最后,围绕 z 轴进行旋转以使物体直立。

(yaw、pitch 和 roll 的术语可能会让人混淆,所以我想避免使用它,但大致对应的是 x=pitch, y=yaw, z=roll。)

在此设置下,我尝试解决您的问题:

rotx = Math.atan2( y, z )
roty = Math.atan2( x * Math.cos(rotx), z )
rotz = Math.atan2( Math.cos(rotx), Math.sin(rotx) * Math.sin(roty) )

希望这是正确的迹象。我认为修复标志最简单的方法是反复试验。事实上,您似乎已经正确地了解了rotxroty 上的标志——包括关于z 的一个微妙问题——所以你只需要修复rotz 上的标志。

我希望这不是微不足道的(可能取决于您所在的八分圆),但请先尝试几种可能性,然后再说它是错误的。祝你好运!


这是最终对我有用的代码。

我注意到当对象从任何前象限(正 Z)移动到任何后象限时会发生“翻转”效果。在前象限中,对象的 front 将始终面向该点。在后象限中,对象的背面始终朝向该点。

此代码修正了翻转效果,使对象的正面始终朝向该点。我是通过反复试验遇到的,所以我真的不知道发生了什么!

 rotx = Math.atan2( y, z );
 if (z >= 0) {
    roty = -Math.atan2( x * Math.cos(rotx), z );
 }else{
    roty = Math.atan2( x * Math.cos(rotx), -z );
 }

【讨论】:

  • 所以这是我的一个误解。您说如果对象位于 y=0 处,您的代码就可以工作,但我不明白这是怎么回事。在这种情况下,您计算 yaw=0 但 pitch!=0,这似乎不正确。 (这就是我问 z 是否向上/向下的原因。)有什么想法吗?
  • 是的,它可以工作,因为我的对象离它所面对的点有一段距离,唯一真正改变的角度是偏航(在 Y 轴上旋转,所以对象水平旋转以面对点位于地平面上)。我说了什么令人困惑的事情吗?
  • @Rex - 我已经在我编辑的问题中解释了我所能做的一切,如果您需要更多内容,请回信。等待您的更新代码。
  • @Rex - 非常感谢!正确答案!!!它就像一个魅力,我的对象正确旋转以面对矢量......呸!!!为寻找正确答案而苦苦挣扎了将近一周。
  • @Braineeee:Stack Overflow 于 8 年前推出。您正在评论一个 7 年前提出的问题,该问题最近一次出现在 6 年前。
【解决方案2】:

Rich Seller 的回答向您展示了如何将一个点从一个 3-D 坐标系旋转到另一个系统,给定一组描述两个坐标系之间旋转的欧拉角。

但听起来你要求的是不同的东西:

你有:单个点的 3-D 坐标

你想要:一组欧拉角

如果这就是您所要求的,那么您没有足够的信息。求欧拉角, 您需要两个坐标系中至少两个点的坐标,以确定从一个坐标系到另一个坐标系的旋转。

您还应该知道欧拉角可能是模棱两可的:Rich 的回答假设 旋转应用于 Z,然后是 X',然后是 Z',但这不是标准化的。如果您必须使用欧拉角与其他一些代码进行互操作,则需要确保使用相同的约定。

您可能需要考虑使用旋转矩阵或四元数来代替欧拉角。

【讨论】:

  • "你没有足够的信息" .. 我不是已经描述了 3D 空间中的 2 点吗?第一个点是任何东西,第二个点是 0,0,0 ...所以我想按 XYZ 顺序测量这两个点之间的欧拉旋转。
  • 请考虑更新您的答案,因为我已经编辑了我的问题并添加了 +500 赏金。
【解决方案3】:

这一系列的轮换会给你你想要的:

  1. 关于 X:0
  2. 关于 Y:atan2(z, x)
  3. 关于Z:atan2(y, sqrt(x*x + z*z))

除非您首先定义如何使用这些术语,否则我无法告诉您这些术语是什么“滚动”、“俯仰”和“偏航”。您没有以标准方式使用它们。

编辑:
好吧,那就试试这个:

  1. 关于 X:-atan2(y, z)
  2. 关于 Y:atan2(x, sqrt(y*y + z*z))
  3. 关于Z:0

【讨论】:

  • @Beta - 感谢您的回答。请查看我已编辑的问题以了解我的确切旋转系统 - 我真的不需要它们的俯仰/偏航而是旋转 X 和旋转 Y(请参阅我的图片以了解我的意思)
  • 我假设 x,y,z 指的是我试图旋转的方向的单位向量?
  • 我尝试了您的解决方案,但由于某种原因无法正常工作。太累了,无法弄清楚为什么,因为雷克斯的回答在 99% 的时间里都有效。不过非常感谢!并保持良好的工作。
  • 我想我知道原因:您的图表是错误的。
  • 嗯,这很刻薄,你猜怎么着,我的图表是正确的,因为 Rex 找到了正确的答案。看看最终对我有用的更新代码,它与你的相似,毫无疑问,但它仍然是有效的。
【解决方案4】:

说到轴的旋转,我认为第3步应该是X'-,Y''-和Z'-轴围绕Y''-轴的旋转。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-06
    • 2016-07-22
    • 2019-11-19
    • 1970-01-01
    • 2021-10-28
    • 2014-12-26
    • 1970-01-01
    相关资源
    最近更新 更多