从欧拉旋转到四元数的旋转。

时间:2021-02-27 20:26:52

I am using the Leap Motion device to get usable data on the position and orientation of my hand. At the moment I am having trouble with the orientation segment of the coding. The Leap API only has code for frame by frame rotation, however, it also provides a normal vector (normal to the palm of the hand) and a pointer vector (pointing in the direction from the palm outwards towards the fingers). These two vectors are perpendicular.

我正在使用Leap Motion设备来获取我手的位置和方向上的可用数据。目前,我对编码的定位部分有问题。Leap API只有帧旋转的代码,但是它也提供了一个法向量(手掌的正常)和一个指针矢量(指向从手掌向外的方向)。这两个向量是垂直的。

The vectors:

向量:

Leap.Vector normal = current.PalmNormal;
Leap.Vector pointer = current.Direction; 

More information can be found on the Leap Hand API: https://developer.leapmotion.com/documentation/Languages/CSharpandUnity/API/class_leap_1_1_hand.html

可以在Leap Hand API上找到更多信息:https://developer.leapmotion.com/documentation/Languages/CSharpandUnity/API/class_leap _1_ 1_hand.html。

Converting to Unity Vector3 class:

转换到Unity Vector3类:

Vector3 normalU = new Vector3();
normalU.x = normal.x;
normalU.y = normal.y;
normalU.z = normal.z;
Vector3 pointerU = new Vector3();
pointerU.x = pointer.x;
pointerU.y = pointer.y;
pointerU.z = pointer.z;

I use these to vectors to calculate the Euler Angles orientation of my hand (a rotation of theta_x degrees about the x-axis, theta_y degrees about the y-axis, and theta_z degrees about the z-axis) using the code:

我用这些向量来计算我的手的欧拉角方向(x轴的旋转角度,y轴的角度,以及z轴上的ta_z度)

float rXn = Mathf.Atan (normalU.y/normalU.z);
rXn *= (180f/Mathf.PI);
if ((normalU.y < 0 && normalU.z < 0) || (normalU.y > 0 && normalU.z < 0))
{
    rXn += 180f;
}
float rZn = Mathf.Atan (normalU.y/normalU.x);
rZn *= (180f/Mathf.PI);
if ((normalU.y < 0 && normal.x > 0) || (normalU.y > 0 && normalU.x > 0))
{
    rZn += 180f;
}
float rYn = Mathf.Atan (pointerU.x/pointerU.z);
rYn *= (180f/Mathf.PI);
if ((pointerU.x > 0 && pointerU.z > 0) || (pointerU.x < 0 && pointerU.z > 0))
{
    rYn += 180f;
}

The Euler Angles are then converted to a Quaternion and implemented using the code:

然后将欧拉角转换为四元数,并使用代码实现:

Quaternion rotation = Quaternion.Euler (-rZn+90, -rYn, rXn+90);
rigidbody.MoveRotation (rotation);

More information on the Unity Quaternion class can be found here: http://docs.unity3d.com/Documentation/ScriptReference/Quaternion.html

更多关于统一四元数类的信息可以在这里找到:http://docs.unity3d.com/Documentation/ScriptReference/Quaternion.html。

As I coded this, I tested each axis of rotation individually, commenting out the others (setting them to 0), and they worked properly. However, when I implemented all three at once, the behaviors of rotations around an individual axis changed, which confuses me. Why would including recognition of rotation about the y-axis change the way rotation about the x-axis occurs?

当我编写这个代码时,我分别测试了每一个旋转轴,并将其他的(设置为0)注释掉,并且工作正常。然而,当我同时实现这三个步骤时,围绕单个轴旋转的行为改变了,这让我很困惑。为什么包括对y轴旋转的认识改变了x轴旋转的方式?

As each individual axis of rotation worked when the others were commented out (and set to 0), I think the problem lies in the way the Euler Angles are converted to a Quaternion. I do not have a great understanding of the way Quaternions are used to represent rotations, however I am confused as to why changing the value of the angle of rotation about the y-axis would change the angle of rotation about the x-axis.

当每一个旋转的旋转轴在其他被注释掉的时候工作(并设置为0),我认为问题在于欧拉角被转换成四元数的方式。我不太理解四元数用来表示旋转的方式,但是我很疑惑为什么改变y轴旋转角度的值会改变绕x轴旋转的角度。

Thanks for your help.

谢谢你的帮助。

2 个解决方案

#1


2  

The order of rotation is relevant, and this might be what causes your confusion. Imagine a point on the x-axis at (1, 0, 0). When we now do a rotation of 90° around the x axis, nothing happens. Then we do a rotation of 90° around the y axis, which makes the point lie on the positive z-axis. If we change the order of rotation, the point will end on the y axis. Depending on the way your functions are implemented, they require a certain order of rotation to get the expected results.

旋转的顺序是相关的,这可能是造成混淆的原因。想象一个在x轴上的点(1,0,0)。当我们现在做一个在x轴旋转90°,什么也不会发生。然后我们做一个y轴旋转90°,使点躺在积极的z轴。如果我们改变旋转的顺序,这个点就会在y轴上结束。根据函数的实现方式,它们需要一定的旋转顺序才能得到预期的结果。

#2


0  

It's not perfect, but I am getting pretty good results with:

这并不完美,但我得到了很好的结果:

private void UpdateHandNormal( Hand hand, Transform marker )
{

    float y = Mathf.Atan( hand.Direction.x / hand.Direction.z );
    if( float.IsNaN( y ) ) y = 0;
    marker.localRotation = new Quaternion( hand.PalmNormal.z, -y, hand.PalmNormal.x, 1 ) ;  

}

Where hand is the Hand instance from the leap controller and marker is a simple rectangle representing the hand rotation.

手是跳跃控制器的手实例,标记是一个代表手旋转的简单矩形。

I was getting NaN for y so I added the set to 0 check.

我得到了NaN,所以我把它加到0。

ath

长沙

J.

J。

#1


2  

The order of rotation is relevant, and this might be what causes your confusion. Imagine a point on the x-axis at (1, 0, 0). When we now do a rotation of 90° around the x axis, nothing happens. Then we do a rotation of 90° around the y axis, which makes the point lie on the positive z-axis. If we change the order of rotation, the point will end on the y axis. Depending on the way your functions are implemented, they require a certain order of rotation to get the expected results.

旋转的顺序是相关的,这可能是造成混淆的原因。想象一个在x轴上的点(1,0,0)。当我们现在做一个在x轴旋转90°,什么也不会发生。然后我们做一个y轴旋转90°,使点躺在积极的z轴。如果我们改变旋转的顺序,这个点就会在y轴上结束。根据函数的实现方式,它们需要一定的旋转顺序才能得到预期的结果。

#2


0  

It's not perfect, but I am getting pretty good results with:

这并不完美,但我得到了很好的结果:

private void UpdateHandNormal( Hand hand, Transform marker )
{

    float y = Mathf.Atan( hand.Direction.x / hand.Direction.z );
    if( float.IsNaN( y ) ) y = 0;
    marker.localRotation = new Quaternion( hand.PalmNormal.z, -y, hand.PalmNormal.x, 1 ) ;  

}

Where hand is the Hand instance from the leap controller and marker is a simple rectangle representing the hand rotation.

手是跳跃控制器的手实例,标记是一个代表手旋转的简单矩形。

I was getting NaN for y so I added the set to 0 check.

我得到了NaN,所以我把它加到0。

ath

长沙

J.

J。