Прыжковое движение - угол между проксимальной костью и пястной костью (движение из стороны в сторону)

Я пытаюсь получить угол между костями, такими как пястная кость и проксимальная кость (угол движения пальца из стороны в сторону, например, угол, когда указательный палец находится настолько близко к большому пальцу, насколько вы можете его двигать и затем угол, когда указательный палец находится настолько близко к среднему пальцу, насколько вы можете его двигать).

Я пытался использовать Vector3.Angle с направлением костей, но это не работает, так как включает сгибание пальца, поэтому, если рука сжата в кулак, это дает совершенно другое значение открытой ладони.

Что мне действительно нужно, так это способ, которым я могу «нормализовать» (я знаю, что нормализация - неправильный термин, но это лучшее, что я мог придумать) направление костей, чтобы даже если палец согнут, вектор направления все еще указывают вперед, а не вниз, а будут в направлении пальца (из стороны в сторону).

Я добавил диаграмму ниже, чтобы попытаться проиллюстрировать, что я имею в виду.

На второй диаграмме синий представляет то, что я получаю в настоящее время, если использую направления костей, зеленый — направление пястной кости, а красный — то, что я хочу (вид сбоку). На первой диаграмме показано, что я ищу, сверху вниз. Синяя линия — это направление пястной кости, а в этом примере красная линия — это проксимальное направление кости, а зеленое пятно представляет угол, который я ищу.

введите здесь описание изображения

введите здесь описание изображения


person user7856951    schedule 27.02.2018    source источник


Ответы (1)


Чтобы получить это значение, вам нужно «развернуть» направление пальца на основе текущего направления пясти. В конце концов, это немного запутано; вам нужно построить некоторые базисные векторы, чтобы развернуть руку вдоль правой оси. Надеюсь, комментарии в этом примере сценария все объяснят.

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 не имеют большой гибкости по этой оси.

person omonobic    schedule 03.03.2018
comment
вы легенда :) - person user7856951; 06.03.2018