UNPKG

5.63 kBJavaScriptView Raw
1var Pointable = require('./pointable'),
2 Bone = require('./bone')
3 , Dialog = require('./dialog')
4 , _ = require('underscore');
5
6/**
7* Constructs a Finger object.
8*
9* An uninitialized finger is considered invalid.
10* Get valid Finger objects from a Frame or a Hand object.
11*
12* @class Finger
13* @memberof Leap
14* @classdesc
15* The Finger class reports the physical characteristics of a finger.
16*
17* Both fingers and tools are classified as Pointable objects. Use the
18* Pointable.tool property to determine whether a Pointable object represents a
19* tool or finger. The Leap classifies a detected entity as a tool when it is
20* thinner, straighter, and longer than a typical finger.
21*
22* Note that Finger objects can be invalid, which means that they do not
23* contain valid tracking data and do not correspond to a physical entity.
24* Invalid Finger objects can be the result of asking for a Finger object
25* using an ID from an earlier frame when no Finger objects with that ID
26* exist in the current frame. A Finger object created from the Finger
27* constructor is also invalid. Test for validity with the Pointable.valid
28* property.
29*/
30var Finger = module.exports = function(data) {
31 Pointable.call(this, data); // use pointable as super-constructor
32
33 /**
34 * The position of the distal interphalangeal joint of the finger.
35 * This joint is closest to the tip.
36 *
37 * The distal interphalangeal joint is located between the most extreme segment
38 * of the finger (the distal phalanx) and the middle segment (the medial
39 * phalanx).
40 *
41 * @member dipPosition
42 * @type {number[]}
43 * @memberof Leap.Finger.prototype
44 */
45 this.dipPosition = data.dipPosition;
46
47 /**
48 * The position of the proximal interphalangeal joint of the finger. This joint is the middle
49 * joint of a finger.
50 *
51 * The proximal interphalangeal joint is located between the two finger segments
52 * closest to the hand (the proximal and the medial phalanges). On a thumb,
53 * which lacks an medial phalanx, this joint index identifies the knuckle joint
54 * between the proximal phalanx and the metacarpal bone.
55 *
56 * @member pipPosition
57 * @type {number[]}
58 * @memberof Leap.Finger.prototype
59 */
60 this.pipPosition = data.pipPosition;
61
62 /**
63 * The position of the metacarpopophalangeal joint, or knuckle, of the finger.
64 *
65 * The metacarpopophalangeal joint is located at the base of a finger between
66 * the metacarpal bone and the first phalanx. The common name for this joint is
67 * the knuckle.
68 *
69 * On a thumb, which has one less phalanx than a finger, this joint index
70 * identifies the thumb joint near the base of the hand, between the carpal
71 * and metacarpal bones.
72 *
73 * @member mcpPosition
74 * @type {number[]}
75 * @memberof Leap.Finger.prototype
76 */
77 this.mcpPosition = data.mcpPosition;
78
79 /**
80 * The position of the Carpometacarpal joint
81 *
82 * This is at the distal end of the wrist, and has no common name.
83 *
84 */
85 this.carpPosition = data.carpPosition;
86
87 /**
88 * Whether or not this finger is in an extended posture.
89 *
90 * A finger is considered extended if it is extended straight from the hand as if
91 * pointing. A finger is not extended when it is bent down and curled towards the
92 * palm.
93 * @member extended
94 * @type {Boolean}
95 * @memberof Leap.Finger.prototype
96 */
97 this.extended = data.extended;
98
99 /**
100 * An integer code for the name of this finger.
101 *
102 * * 0 -- thumb
103 * * 1 -- index finger
104 * * 2 -- middle finger
105 * * 3 -- ring finger
106 * * 4 -- pinky
107 *
108 * @member type
109 * @type {number}
110 * @memberof Leap.Finger.prototype
111 */
112 this.type = data.type;
113
114 this.finger = true;
115
116 /**
117 * The joint positions of this finger as an array in the order base to tip.
118 *
119 * @member positions
120 * @type {array[]}
121 * @memberof Leap.Finger.prototype
122 */
123 this.positions = [this.carpPosition, this.mcpPosition, this.pipPosition, this.dipPosition, this.tipPosition];
124
125 if (data.bases){
126 this.addBones(data);
127 } else {
128 Dialog.warnBones();
129 }
130
131};
132
133_.extend(Finger.prototype, Pointable.prototype);
134
135
136Finger.prototype.addBones = function(data){
137 /**
138 * Four bones per finger, from wrist outwards:
139 * metacarpal, proximal, medial, and distal.
140 *
141 * See http://en.wikipedia.org/wiki/Interphalangeal_articulations_of_hand
142 */
143 this.metacarpal = new Bone(this, {
144 type: 0,
145 width: this.width,
146 prevJoint: this.carpPosition,
147 nextJoint: this.mcpPosition,
148 basis: data.bases[0]
149 });
150
151 this.proximal = new Bone(this, {
152 type: 1,
153 width: this.width,
154 prevJoint: this.mcpPosition,
155 nextJoint: this.pipPosition,
156 basis: data.bases[1]
157 });
158
159 this.medial = new Bone(this, {
160 type: 2,
161 width: this.width,
162 prevJoint: this.pipPosition,
163 nextJoint: this.dipPosition,
164 basis: data.bases[2]
165 });
166
167 /**
168 * Note that the `distal.nextJoint` position is slightly different from the `finger.tipPosition`.
169 * The former is at the very end of the bone, where the latter is the center of a sphere positioned at
170 * the tip of the finger. The btipPosition "bone tip position" is a few mm closer to the wrist than
171 * the tipPosition.
172 * @type {Bone}
173 */
174 this.distal = new Bone(this, {
175 type: 3,
176 width: this.width,
177 prevJoint: this.dipPosition,
178 nextJoint: data.btipPosition,
179 basis: data.bases[3]
180 });
181
182 this.bones = [this.metacarpal, this.proximal, this.medial, this.distal];
183};
184
185Finger.prototype.toString = function() {
186 return "Finger [ id:" + this.id + " " + this.length + "mmx | width:" + this.width + "mm | direction:" + this.direction + ' ]';
187};
188
189Finger.Invalid = { valid: false };