Hand

Attributes:

Functions:

class Hand()

The Hand class reports the physical characteristics of a detected hand.

Hand tracking data includes a palm position and velocity; vectors for the palm normal and direction to the fingers; properties of a sphere fit to the hand; and lists of the attached fingers.

Note that Hand objects can be invalid, which means that they do not contain valid tracking data and do not correspond to a physical entity. Invalid Hand objects can be the result of asking for a Hand object using an ID from an earlier frame when no Hand objects with that ID exist in the current frame. A Hand object created from the Hand constructor is also invalid. Test for validity with the valid property.

An uninitialized hand is considered invalid. Get valid Hand objects from a Frame object.

var controller = Leap.loop(function(frame){
    if(frame.hands.length > 0)
    {
        var hand = frame.hands[0];
        var position = hand.palmPosition;
        var velocity = hand.palmVelocity;
        var direction = hand.direction;
    }
});
Hand.arm
Type:Bone()

The position, size, and orientation of the forearm to which this hand is attached.

arm = hand.arm;

Basis vectors fo the arm property specify the orientation of a arm:

  • arm.basis[0] – the x-basis. Perpendicular to the longitudinal axis of the arm; exits laterally from the sides of the wrist.
  • arm.basis[1] – the y-basis or up vector. Perpendicular to the longitudinal axis of the arm; exits the top and bottom of the arm. More positive in the upward direction.
  • arm.basis[2] – the z-basis. Aligned with the longitudinal axis of the arm. More positive toward the elbow.

The bases provided for the right arm use the right-hand rule; those for the left arm use the left-hand rule. Thus, the positive direction of the x-basis is to the right for the right arm and to the left for the left arm. You can change from right-hand to left-hand rule by multiplying the basis vectors by -1.

Leap Motion 2.0.3 and LeapJS 0.6.0

Hand.confidence
Type:number – a value in the range [0..1]

How well the internal hand model fits the observed data.

A low value indicates that there are significant discrepancies; finger positions, even hand identification could be incorrect. The significance of the confidence value to your application can vary with context.

var confidence = hand.confidence;
if(confidence > .7){
    //...
}

Leap Motion 2.0 and LeapJS 0.6.0

Hand.direction
Type:number[] – a 3-element array representing a unit direction vector.

The direction from the palm position toward the fingers.

var direction = hand.direction;
console.table(direction);

The direction is expressed as a unit vector pointing in the same direction as the directed line from the palm position to the fingers.

Hand.fingers[]
Type:array of Pointable() objects representing fingers

The list of fingers detected in this frame that are attached to this hand, given in arbitrary order.

The list can be empty if no fingers attached to this hand are detected.

hand.fingers.forEach(function(finger){
    //...
});
Hand.grabStrength
Type:float – a value in the range [0..1]

The strength of a grab hand pose.

The strength is zero for an open hand, and blends to 1.0 when a grabbing hand pose is recognized. The following example uses grabStrength to determine whether a hand is open or closed. The example also compares the current value to the average value from recent history to determine whether the hand is opening or closing (if the hand isn’t fully open or closed).

function handStateFromHistory(hand, historySamples) {
    if(hand.grabStrength == 1) return "closed";
    else if (hand.grabStrength == 0) return "open";
    else {
        var sum = 0
        for(var s = 0; s < historySamples; s++){
            var oldHand = controller.frame(s).hand(hand.id)
            if(!oldHand.valid) break;
            sum += oldHand.grabStrength
        }
        var avg = sum/s;
        if(hand.grabStrength - avg < 0) return "opening";
        else if (hand.grabStrength > 0) return "closing";
    }
    return"not detected";
}
console.log("Hand is " + handStateFromHistory(hand, 10));

Leap Motion 2.0 and LeapJS 0.6.0

Hand.id
Type:String

A unique ID assigned to this Hand object, whose value remains the same across consecutive frames while the tracked hand remains visible. If tracking is lost (for example, when a hand is occluded by another hand or when it is withdrawn from or reaches the edge of the Leap field of view), the Leap may assign a new ID when it detects the hand in a future frame.

Use the ID value with the Frame.hand() function to find this Hand object in future frames. The following example finds the average hand position over a given number of frames by looking up the Hand object by id.

function avgHandPosition(hand, historySamples) {
        var sum = Leap.vec3.create();
        Leap.vec3.copy(sum, hand.palmPosition);
        for(var s = 1; s < historySamples; s++){
            var oldHand = controller.frame(s).hand(hand.id)
            if(!oldHand.valid) break;
            Leap.vec3.add(sum, oldHand.palmPosition, sum);
        }
        Leap.vec3.scale(sum, sum, 1/s);
        return sum;
}
var average = avgHandPosition(hand, 30);
console.table(average);
Hand.indexFinger
Type:Finger() – a Finger object representing the index finger.

The index finger of this Hand.

var index = hand.indexFinger;

Leap Motion 2.0 and LeapJS 0.6.0

Hand.middleFinger
Type:Finger() – a Finger object representing the middle finger.

The middle finger of this Hand.

var middle = hand.middleFinger;

Leap Motion 2.0 and LeapJS 0.6.0

Hand.palmNormal
Type:number[] – a 3-element array representing a unit direction vector.

The normal vector to the palm. If your hand is flat, this vector will point downward, or “out” of the front surface of your palm.

Palm Vectors

The direction is expressed as a unit vector pointing in the same direction as the palm normal (that is, a vector orthogonal to the palm).

var normal = hand.palmNormal;
Hand.palmPosition
Type:number[] – a 3-element array representing a unit direction vector.

The center position of the palm in millimeters from the Leap origin.

var position = hand.palmPosition;
Hand.palmVelocity
Type:number[] – a 3-element array representing a vector.

The rate of change of the palm position in millimeters/second.

var speed = hand.palmVelocity;
Hand.palmWidth
Type:number

The average outer width of the hand (not including fingers or thumb) in millimeters.

handSize = hand.palmWidth;

New in version 2.0.

Hand.pinchStrength
Type:float – a value in the range [0..1]

The holding strength of a pinch hand pose.

The strength is zero for an open hand, and blends to 1.0 when a pinching hand pose is recognized. Pinching can be done between the thumb and any other finger of the same hand.

The following example compares the distances between the tip of the thumb and other fingers to determine which finger is pinching.

if(hand.pinchStrength > 0){
    var pinchingFinger = findPinchingFinger(hand);
}
function findPinchingFingerType(hand){
    var pincher;
    var closest = 500;
    for(var f = 1; f < 5; f++)
    {
        current = hand.fingers[f];
        distance = Leap.vec3.distance(hand.thumb.tipPosition, current.tipPosition);
        if(current != hand.thumb && distance < closest)
        {
            closest = distance;
            pincher = current; 
        }
    } 
    return pincher;
}

Leap Motion 2.0 and LeapJS 0.6.0

Hand.pinky
Type:Finger() – a Finger object representing the pinky finger.

The pinky finger of this Hand.

var pinkyFinger = hand.pinky;

Leap Motion 2.0 and LeapJS 0.6.0

Hand.pointables[]
Type:array of Pointable() objects

The list of Pointable objects (fingers) detected in this frame that are associated with this hand, given in arbitrary order. The list can be empty if no fingers associated with this hand are detected.

The following example identifies each pointable by finger name.

var nameMap = ["thumb", "index", "middle", "ring", "pinky"];
hand.pointables.forEach(function(pointable){
    if(pointable.tool) console.log("Tool");
    else console.log(nameMap[pointable.type]);
});
Hand.ringFinger
Type:Finger() – a Finger object representing the ring finger.

The ring finger of this Hand.

var thirdFinger = hand.ringFinger;

Leap Motion 2.0 and LeapJS 0.6.0

Hand.sphereCenter
Type:number[] – a 3-element array representing a position vector.

The center of a sphere fit to the curvature of this hand.

var center = hand.sphereCenter;
console.log("Sphere Center: " + center[0] + ", " + center[1] + ", " + center[2] + ")");

This sphere is placed roughly as if the hand were holding a ball.

Hand Ball

Hand.sphereRadius
Type:number

The radius of a sphere fit to the curvature of this hand, in millimeters.

var radius = hand.sphereRadius;
console.log("Sphere Radius: " + radius);

This sphere is placed roughly as if the hand were holding a ball. Thus the size of the sphere decreases as the fingers are curled into a fist.

Hand.stabilizedPalmPosition
Type:number[] – a 3-element array representing a position vector.

The stabilized palm position of this Hand.

Smoothing and stabilization is performed in order to make this value more suitable for interaction with 2D content. The stabilized position lags behind the palm position by a variable amount, depending primarily on the speed of movement.

The following example calculates the difference between the palm position and its stabilized counterpart.

var stabilized = hand.stabilizedPalmPosition;
var delta = Leap.vec3.create();
Leap.vec3.subtract(delta, stabilized, hand.palmPosition);
console.log("Difference between palm and stabilized palm positions: ");
console.table(delta);
Hand.thumb
Type:Finger() – a Finger object representing the thumb.

The thumb of this Hand.

var thumb = hand.thumb;

Leap Motion 2.0 and LeapJS 0.6.0

Hand.timeVisible
Type:number

The amount of time this hand has been continuously visible to the Leap Motion controller in seconds.

var timeVisible = hand.timeVisible;
if(timeVisible > .25){
    //... use hand
}

By ignoring Hand objects with a small timeVisible value, can filter out a certain amount of noise and spuriously detected hands.

Hand.tools[]
Type:array of Pointable() objects representing tools

Notice Tools are deprecated in version 3.0.

In version 2+, tools are not associated with hands. This list is always empty.

The list of tools detected in this frame that are held by this hand, given in arbitrary order.

Hand.type
Type:string – either “right” or “left”

Identifies whether this Hand is a right or a left hand.

var type = hand.type;
if(type == "left"){
    console.log("Left hand.");
} else {
    console.log("Right hand.")
}

Leap Motion 2.0 and LeapJS 0.6.0

Hand.valid
Type:

boolean

Reports whether this is a valid Hand object.

Hand.finger(id)

The finger with the specified ID attached to this hand.

Use this function to retrieve a Pointable object representing a finger attached to this hand using an ID value obtained from a previous frame. This function always returns a Pointable object, but if no finger with the specified ID is present, an invalid Pointable object is returned.

var finger = hand.finger(fingerID);

Finger IDs are based on the hand ID. If tracking of a hand is lost and regained, then the finger IDs are also changed. Note that you can also look up fingers anatomically by hand and type:

var sum = Leap.vec3.create();
var count = 0;
for(var s = 0; s < 30; s++){
    if(!frame.valid || frame.hands.length == 0) break;
    frame.hands.forEach(function(hand){
        if(hand.type == "left"){
            indexTip = hand.indexFinger.tipPosition;
            Leap.vec3.add(sum, indexTip, sum);
            count++;
        }
    });
}
if(count > 0) Leap.vec3.scale(sum, sum, 1/count);
console.table(sum);
Arguments:
  • id (String) – The ID value of a finger from a previous frame.
Returns:

Pointable() – The Finger object with the matching ID if one exists for this hand in this frame; otherwise, an invalid Finger object is returned.

Hand.pitch()

The pitch angle in radians.

Pitch is the angle between the negative z-axis and the projection of the vector onto the y-z plane. In other words, pitch represents rotation around the x-axis. If the vector points upward, the returned angle is between 0 and pi radians (180 degrees); if it points downward, the angle is between 0 and -pi radians.

var pitchRadians = hand.pitch();
Returns:number – The angle of this vector above or below the horizon (x-z plane).
Hand.roll()

The roll angle in radians.

Roll is the angle between the y-axis and the projection of the vector onto the x-y plane. In other words, roll represents rotation around the z-axis. If the vector points to the left of the y-axis, then the returned angle is between 0 and pi radians (180 degrees); if it points to the right, the angle is between 0 and -pi radians.

Returns:number The angle of this vector to the right or left of the y-axis.
var rollRadians = hand.roll();
Hand.rotationAngle(sinceFrame[, axis])

The angle of rotation around the rotation axis derived from the change in orientation of this hand, and associated fingers, between the current frame and the specified frame.

The returned angle is expressed in radians measured clockwise around the rotation axis (using the right-hand rule) between the start and end frames. The value is always between 0 and pi radians (0 and 180 degrees). If you specify an axis parameter, the returned value will be the portion of the total rotation around that axis. If you do not specify an axis, the the total rotation around the primary axis of rotation is returned. You can get the primary axis with the rotationAxis() function.

The following example computes both the total rotation and the rotation around the z-axis:

var previousFrame = controller.frame(1);
var totalRotation = hand.rotationAngle(previousFrame);
var rotationAroundZAxis = hand.rotationAngle(previousFrame, [0,0,1]);
console.log("Rot: " + totalRotation + ", Z Rot:" + rotationAroundZAxis);

If a corresponding Hand object is not found in sinceFrame, or if either this frame or sinceFrame are invalid Frame objects, then the angle of rotation is zero.

Arguments:
  • sinceFrame (Frame()) – The starting frame for computing the relative rotation.
  • axis (number[]) – The axis to measure rotation around.
Returns:

number – A positive value representing the heuristically determined rotational change of the hand between the current frame and that specified in the sinceFrame parameter.

Hand.rotationAxis(sinceFrame)

The axis of rotation derived from the change in orientation of this hand, and associated fingers, between the current frame and the specified frame.

The returned direction vector is normalized.

If a corresponding Hand object is not found in sinceFrame, or if either this frame or sinceFrame are invalid Frame objects, then this method returns a zero vector.

var previousFrame = controller.frame(1);
var axis = hand.rotationAxis(previousFrame);
console.log("Axis of Rotation: (" + axis[0] + ", " + axis[1] + ", " + axis[2] + ")");
Arguments:
  • sinceFrame (Frame()) – The starting frame for computing the relative rotation.
Returns:

number[] – A normalized direction vector representing the axis of the heuristically determined rotational change of the hand between the current frame and that specified in the sinceFrame parameter. The returnd object is a 3-element array containing the vector coordinates.

Hand.rotationMatrix(sinceFrame)

The transform matrix expressing the rotation derived from the change in orientation of this hand, and associated fingers, between the current frame and the specified frame.

If a corresponding Hand object is not found in sinceFrame, or if either this frame or sinceFrame are invalid Frame objects, then this method returns an identity matrix.

var previousFrame = controller.frame(1);
var matrix = hand.rotationMatrix(previousFrame);
console.log("Rotation Matrix:");
console.log("[" + matrix[0] + ", " + matrix[1] + ", " + matrix[2] + "]");
console.log("[" + matrix[3] + ", " + matrix[4] + ", " + matrix[5] + "]");
console.log("[" + matrix[6] + ", " + matrix[7] + ", " + matrix[8] + "]");
Arguments:
  • sinceFrame (Frame()) – The starting frame for computing the relative rotation.
Returns:

number[] – A transformation matrix containing the heuristically determined rotational change of the hand between the current frame and that specified in the sinceFrame parameter. The object returned is a 9-element array containing the matrix coefficients in row-major order.

Hand.scaleFactor(sinceFrame)

The scale factor derived from the hand’s motion between the current frame and the specified frame.

The scale factor is always positive. A value of 1.0 indicates no scaling took place. Values between 0.0 and 1.0 indicate contraction and values greater than 1.0 indicate expansion.

The Leap derives scaling from the relative inward or outward motion of a hand and its associated fingers (independent of translation and rotation).

var previousFrame = controller.frame(1);
var scale = hand.scaleFactor(previousFrame);
console.log("Hand scale: " + scale);

If a corresponding Hand object is not found in sinceFrame, or if either this frame or sinceFrame are invalid Frame objects, then this method returns 1.0.

Arguments:
  • sinceFrame (Frame()) – The starting frame for computing the relative scaling.
Returns:

number – A positive value representing the heuristically determined scaling change ratio of the hand between the current frame and that specified in the sinceFrame parameter.

Hand.toString()

A string containing a brief, human readable description of the Hand object.

console.log(hand.toString());
Returns:String – A description of the Hand as a string.
Hand.translation(sinceFrame)

The change of position of this hand between the current frame and the specified frame

The returned translation vector provides the magnitude and direction of the movement in millimeters.

var previousFrame = controller.frame(1);
var movement = hand.translation(previousFrame);
console.table(movement);

If a corresponding Hand object is not found in sinceFrame, or if either this frame or sinceFrame are invalid Frame objects, then this method returns a zero vector.

Arguments:
  • sinceFrame (Frame()) – The starting frame for computing the relative translation.
Returns:

number[] – A vector representing the heuristically determined change in hand position between the current frame and that specified in the sinceFrame parameter. The object returned is a 3-element array containing the vector coefficients.

Hand.yaw()

The yaw angle in radians.

Yaw is the angle between the negative z-axis and the projection of the vector onto the x-z plane. In other words, yaw represents rotation around the y-axis. If the vector points to the right of the negative z-axis, then the returned angle is between 0 and pi radians (180 degrees); if it points to the left, the angle is between 0 and -pi radians.

var yawRadians = hand.yaw();
Returns:number – The angle of this vector to the right or left of the y-axis.
Hand.Invalid
Type:Hand

An invalid Hand object.

You can use an invalid Hand object in comparisons testing whether a given Hand instance is valid or invalid. (You can also use the Hand valid property.)