计算旋转以查看3D点?

Rob*_*cks 12 math 3d angle rotation euler-angles

我需要计算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 ) )
Run Code Online (Sandbox Code Playgroud)

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


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

pic http://i53.tinypic.com/33lo6jp.jpg

在此输入图像描述


这是我的系统.

  • 坐标系是x =向右,y =向下,z =向后
  • 一个对象默认为(0,0,1),面向后方
  • 旋转的顺序为X,Y,Z,其中X上的旋转是俯仰,Y是偏航,Z是滚动

我的系统

A. *_*Rex 13

以下是我的工作假设:

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

(术语偏航,俯仰和滚动可能会令人困惑,所以我想避免使用它,但粗略地说,对应关系是x =俯仰,y =偏航,z =滚动.)

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

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) )
Run Code Online (Sandbox Code Playgroud)

希望这是正确的迹象.我认为解决这些迹象的最简单方法是通过反复试验.事实上,你似乎已经开始rotx并且roty正确 - 包括关于z的微妙问题 - 所以你只需要修复标志rotz.

我希望这是非常重要的(可能取决于你在哪个八分区),但在说出错之前请尝试一些可能性.祝好运!


这是最终为我工作的代码.

我注意到当物体从任何前象限(正Z)移动到任何后象限时发生的"翻转"效应.在前象限中,物体的前部总是面向该点.在后象限中,物体的背面始终面向该点.

此代码可校正翻转效果,因此对象的正面始终面向该点.我通过反复试验遇到了它,所以我真的不知道发生了什么!

 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 );
 }
Run Code Online (Sandbox Code Playgroud)


Jim*_*wis 6

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

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

你有:单点的三维坐标

你想要:一组欧拉角

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

您还应该意识到欧拉角度可能是模糊的:Rich的答案假设旋转应用于Z,然后是X',然后是Z',但这不是标准化的.如果必须使用欧拉角度与其他代码进行互操作,则需要确保使用相同的约定.

您可能需要考虑使用旋转矩阵或四元数而不是欧拉角.