Search code examples
c#leap-motion

Leap Motion Get Finger Bending (C#)


Hello I tried a lot diffrent ways to get bending angle in Leap Motion. But I couldn't get true values. I used this method for reading. Thanks in advance.

Bone bone1 = finger.Bone(Bone.BoneType.TYPE_INTERMEDIATE);
Bone bone2 = finger.Bone(Bone.BoneType.TYPE_PROXIMAL);
double angle = 180 - ((bone1.Direction.AngleTo(bone2.Direction) / Math.PI) * 180) * 2;

Solution

  • In this example I'll use array accessors as a quicker way of accessing bones from Finger objects.

    For reference, bone indices are: 0 = metacarpal, 1 = proximal, 2 = intermediate, 3 = distal. You can validate this by looking at the definition of BoneType.

    (Careful, the thumb has one fewer bone than the other fingers.)

    Vector3 bone0Dir = finger.bones[0].Direction.ToVector3();
    Vector3 bone1Dir = finger.bones[1].Direction.ToVector3();
    
    float angle = Vector3.Angle(bone0Dir, bone1Dir);
    

    This example retrieves the angle in degrees between the metacarpal bone and the proximal bone of the finger object.

    Note that Vector3.Angle returns the unsigned angle between the two bones; if you desire a signed angle, you can use the SignedAngle function instead. You'll need to pass it a reference axis; Vector3.Cross(hand.PalmarAxis(), hand.DistalAxis()) would be suitable for this.


    EDIT: Ah, apologies, the answer is a bit different if you're outside of the Unity engine. In that case, Leap.Vector.AngleTo is sufficient, but there's a simpler way to convert radians to degrees:

    Vector bone0Dir = finger.bones[0].Direction;
    Vector bone1Dir = finger.bones[1].Direction;
    
    float angle = bone0Dir.AngleTo(bone1Dir) * Vector.RAD_TO_DEG;
    

    Again, this will return the unsigned angle, but fingers don't usually bend backwards, so this should be sufficient for your use-case. You can also use Math.Asin((bone0Dir.Cross(bone1Dir).Magnitude)) * RAD_TO_DEG to get a (right-handed) signed angle.