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。