跳跃运动-近端骨与掌骨的角度(左右移动) [英] Leap Motion - Angle of proximal bone to metacarpal (side to side movement)

查看:125
本文介绍了跳跃运动-近端骨与掌骨的角度(左右移动)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试获取诸如掌骨和近端骨之类的骨骼之间的角度(将手指左右移动的角度,例如,食指尽可能接近拇指时的角度)移开它,然后在食指尽可能靠近中指时移动角度).

I am trying to get the angle between the bones, such as the metacarpal bone and the proximal bone (angle of moving the finger side to side, for example the angle when your index finger is as close to your thumb as you can move it and then the angle when your index finger is as close to your middle finger as you can move it).

我已经尝试过使用Vector3.Angle的骨骼方向,但是由于包括了手指的弯曲,所以它不起作用,因此如果手握拳,则它给张开的手一个完全不同的值.

I have tried using Vector3.Angle with the direction of the bones but that doesn't work as it includes the bending of the finger, so if the hand is in a fist it gives a completely different value to an open hand.

我真正想要的是一种可以规范化"骨骼的方向(我知道规范化不是正确的术语,但这是我能想到的最好的方法),这样即使手指弯曲了,骨骼的方向也可以向量仍然会指向前方而不是向下,而是指向手指的方向(左右).

What i really want is a way i can "normalize" (i know normalizing isn't the correct term but it's the best i could think of) the direction of the bones so that even if the finger is bent, the direction vector would still point out forwards and not down, but would be in the direction of the finger (side to side).

我在下面添加了一个图表,试图说明我的意思.

I have added a diagram below to try and illustrate what i mean.

在第二张图中,蓝色表示如果我使用骨骼的方向,我现在会得到什么,绿色表示掌骨方向,红色是我想要的(从侧面看).第一张图从上到下显示了我要查找的内容.蓝线是掌骨方向,在本示例中,红线是近端骨方向,绿色污迹代表我要寻找的角度.

In the second diagram, the blue represents what i currently get if i use the bone's directions, the green is the metacarpal direction and the red is what i want (from the side view). The first diagram shows what i am looking for from a top-down view. The blue line is the metacarpal bone direction and in this example the red line is the proximal bone direction, with the green smudge representing the angle i am looking for.

推荐答案

要获取此值,您需要根据当前的掌骨方向松开"手指方向.最后涉及一点点.您必须构造一些基向量,以使手沿未弯曲的右轴松开.希望此示例脚本中的注释能够解释所有内容.

To get this value, you need to "uncurl" the finger direction based on the current metacarpal direction. It's a little involved in the end; you have to construct some basis vectors in order to uncurl the hand along juuust the right axis. Hopefully the comments in this example script will explain everything.

using Leap;
using Leap.Unity;
using UnityEngine;

public class MeasureIndexSplay : MonoBehaviour {

  // Update is called once per frame
  void Update () {
    var hand = Hands.Get(Chirality.Right);
    if (hand != null) {
      Debug.Log(GetIndexSplayAngle(hand));
    }
  }

  // Some member variables for drawing gizmos.
  private Ray _metacarpalRay;
  private Ray _proximalRay;
  private Ray _uncurledRay;

  /// <summary>
  /// This method returns the angle of the proximal bone of the index finger relative to
  /// its metacarpal, when ignoring any angle due to the curling of the finger.
  /// 
  /// In other words, this method measures the "side-to-side" angle of the finger.
  /// </summary>
  public float GetIndexSplayAngle(Hand h) {
    var index = h.GetIndex();

    // These are the directions we care about.
    var metacarpalDir = index.bones[0].Direction.ToVector3();
    var proximalDir   = index.bones[1].Direction.ToVector3();

    // Let's start with the palm basis vectors.
    var distalAxis = h.DistalAxis(); // finger axis
    var radialAxis = h.RadialAxis(); // thumb axis
    var palmarAxis = h.PalmarAxis(); // palm axis

    // We need a basis whose forward direction is aligned to the metacarpal, so we can
    // uncurl the finger with the proper uncurling axis. The hand's palm basis is close,
    // but not aligned with any particular finger, so let's fix that.
    //
    // We construct a rotation from the palm "finger axis" to align it to the metacarpal
    // direction. Then we apply that same rotation to the other two basis vectors so
    // that we still have a set of orthogonal basis vectors.
    var metacarpalRotation = Quaternion.FromToRotation(distalAxis, metacarpalDir);
    distalAxis = metacarpalRotation * distalAxis;
    radialAxis = metacarpalRotation * radialAxis;
    palmarAxis = metacarpalRotation * palmarAxis;

    // Note: At this point, we don't actually need the distal axis anymore, and we
    // don't need to use the palmar axis, either. They're included above to clarify that
    // we're able to apply the aligning rotation to each axis to maintain a set of
    // orthogonal basis vectors, in case we wanted a complete "metacarpal-aligned basis"
    // for performing other calculations.

    // The radial axis, which has now been rotated a bit to be orthogonal to our
    // metacarpal, is the axis pointing generally towards the thumb. This is our curl
    // axis.
    // If you're unfamiliar with using directions as rotation axes, check out the images
    // here: https://en.wikipedia.org/wiki/Right-hand_rule
    var curlAxis = radialAxis;

    // We want to "uncurl" the proximal bone so that it is in line with the metacarpal,
    // when considered only on the radial plane -- this is the plane defined by the
    // direction approximately towards the thumb, and after the above step, it's also
    // orthogonal to the direction our metacarpal is facing.
    var proximalOnRadialPlane = Vector3.ProjectOnPlane(proximalDir, radialAxis);
    var curlAngle = Vector3.SignedAngle(metacarpalDir, proximalOnRadialPlane,
                                        curlAxis);

    // Construct the uncurling rotation from the axis and angle and apply it to the
    // *original* bone direction. We determined the angle of positive curl, so our
    // rotation flips its sign to rotate the other direction -- to _un_curl.
    var uncurlingRotation = Quaternion.AngleAxis(-curlAngle, curlAxis);
    var uncurledProximal = uncurlingRotation * proximalDir;

    // Upload some data for gizmo drawing (optional).
    _metacarpalRay = new Ray(index.bones[0].PrevJoint.ToVector3(),
                             index.bones[0].Direction.ToVector3());
    _proximalRay = new Ray(index.bones[1].PrevJoint.ToVector3(),
                           index.bones[1].Direction.ToVector3());
    _uncurledRay = new Ray(index.bones[1].PrevJoint.ToVector3(),
                           uncurledProximal);

    // This final direction is now uncurled and can be compared against the direction
    // of the metacarpal under the assumption it was constructed from an open hand.
    return Vector3.Angle(metacarpalDir, uncurledProximal);
  }

  // Draw some gizmos for debugging purposes.
  public void OnDrawGizmos() {
    Gizmos.color = Color.white;
    Gizmos.DrawRay(_metacarpalRay.origin, _metacarpalRay.direction);

    Gizmos.color = Color.blue;
    Gizmos.DrawRay(_proximalRay.origin, _proximalRay.direction);

    Gizmos.color = Color.red;
    Gizmos.DrawRay(_uncurledRay.origin, _uncurledRay.direction);
  }
}

就其价值而言,当食指卷曲时,跟踪的Leap手在该轴上没有很大的灵活性.

For what it's worth, while the index finger is curled, tracked Leap hands don't have a whole lot of flexibility on this axis.

这篇关于跳跃运动-近端骨与掌骨的角度(左右移动)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆