Hand Part Tutorial
<< Back to the TouchID Toolkit page

In this tutorial you learn how to use different hand parts in an application.
Therefore, we will implement a finger painting application together. Each finger will paint in its own color and thickness. Each knuckle is an eraser in the same thickness as its corresponding finger paints.
Table 1 shows the color and thickness for each finger.
Finger | Color | Thickness |
---|---|---|
Thumb | Pink | 35px |
Index finger | Yellow | 25px |
Middle finger | Blue | 20px |
Ring finger | Green | 15px |
Pinkie | Red | 10px |
Prerequisite 1: At least one glove configuration has been created
Glove configurations can be conveniently created with the GloveConfigurator which stores the glove configuration files also directly in the glove repository (My Documents/GroupLab/TouchID Toolkit/Gloves) right away. If you have glove configuration files in a different folder and want them to work with this example, copy them into the glove repository.
Step 1: Creating a new TouchID Application
For detailed information, please read: How to start a new TouchID Application
The TouchID Application template creates the following code skeleton for you:
public Window1(){
InitializeComponent();
//Creates a glove for every glove model in the glove repository
this.LoadHands();
//Alternatively you can also instantiate glove by glove;
//Hand hand = new Hand(this, "Hand1");
//Creates posture recognizer and loads all postures from the posture repository into the recognition engine
this.PostureRecognizer = new PostureRecognizer(this);
this.PostureRecognizer.LoadPostures(PostureRepository);
//Creates gesture recognizer and loads all gesture from the gesture repository into the recognition engine
this.GestureRecognizer = new GestureRecognizer();
this.GestureRecognizer.LoadGestures(GestureRepository);
this.HandpartDown += new EventHandler<TouchEventArgs>(Window1_HandpartDown);
}
void Window1_HandpartDown(object sender, TouchEventArgs e){
Console.WriteLine(e.Glove.Hand + " " + e.Handpart.Identifier);
}
}
Step 2: Replacing the HandpartDown event with FingerDown and KnuckleDown event
Since we know that we would like to handle fingers and knuckles separately, it makes sense to access them not via the general HandpartDown event but the specialized events FingerDown and KnuckleDown. Even though we have to check for hand parts in these vents, too, splitting up the two groups in two events improves the code clearness.
Step 3: Adjusting the callback methods for the FingerDown and KnuckleDown event
The fingers should start painting we they are placed down. The knuckles should erase when they are placed down. Therefor, we adjust the callback methods for each event accordingly:
{
if(e.Handpart.Identifier.Thumb)
{
Paint(e.Handpart.Position, Brushes.Pink, 35.0);
}
else if(e.Handpart.Identifier.IndexFinger)
{
Paint(e.Handpart.Position, Brushes.Yellow, 25.0);
}
else if(e.Handpart.Identifier.MiddleFinger)
{
Paint(e.Handpart.Position, Brushes.Blue, 20.0);
}
else if(e.Handpart.Identifier.RingFinger)
{
Paint(e.Handpart.Position, Brushes.Green, 15.0);
}
else if(e.Handpart.Identifier.Pinkie)
{
Paint(e.Handpart.Position, Brushes.Red, 10.0);
}
}
{
if(e.Handpart.Identifier.ThumbKnuckle)
{
Erase(e.Handpart.Position, 35.0);
}
else if(e.Handpart.Identifier.IndexKnuckle)
{
Erase(e.Handpart.Position, 25.0);
}
else if(e.Handpart.Identifier.MiddleKnuckle)
{
Erase(e.Handpart.Position, 20.0);
}
else if(e.Handpart.Identifier.RingKnuckle)
{
Erase(e.Handpart.Position, 15.0);
}
else if(e.Handpart.Identifier.PinkieKnuckle)
{
Erase(e.Handpart.Position, 10.0);
}
}
Step 4: Adding the Paint and Erase method
In order to keep this tutorial as simple as possible both functions will just draw an ellipse in the defined thickness and color (white for erasing) at the given position. It works better and looks nicer when you use a path instead but it also makes the tutorial unnecessarily complicated.
{
Ellipse ellipse = new Ellipse();
// Setting the thickness.
ellipse.Width = thickness;
ellipse.Height = thickness;
// Setting the color.
ellipse.Fill = brush;
// Translating ellipse to designated position.
ellipse.RenderTransform = new TranslateTransform(this.position.X-thickness/2.0, this.position.Y-thickness/2.0);
this.Canvas.Children.Add(ellipse);
}
{
// Erasing is done by painting a white ellipse in the given thickness and at the designated position.
this.Paint(position, Brushes.White, thickness);
}
Step 5: Subscribing to FingerChanged and KnuckleChanged events
When you run the application at this point, you will notice that we've implemented a stamping and not a painting application so far. In order to change this, we subscribe to the FingerChanged and KnuckleChanged events. These events are raised when the hand parts change their position or orientation. By calling the Paint and Erase methods in the callback method for the FingerChanged event and KnuckleChanged event, respectively, the fingers and knuckles will not only paint and erase when placed down on the surface, but also when moved over it.
Step 6: Adjusting the callback methods for the FingerChanged and KnuckleChanged event
The bodies of the two callback methods are the same as their counterparts for the FingerDown and KnuckleDown events.
{
if(e.Handpart.Identifier.Thumb)
{
Paint(e.Handpart.Position, Brushes.Pink, 35.0);
}
else if(e.Handpart.Identifier.IndexFinger)
{
Paint(e.Handpart.Position, Brushes.Yellow, 25.0);
}
else if(e.Handpart.Identifier.MiddleFinger)
{
Paint(e.Handpart.Position, Brushes.Blue, 20.0);
}
else if(e.Handpart.Identifier.RingFinger)
{
Paint(e.Handpart.Position, Brushes.Green, 15.0);
}
else if(e.Handpart.Identifier.Pinkie)
{
Paint(e.Handpart.Position, Brushes.Red, 10.0);
}
}
{
if(e.Handpart.Identifier.ThumbKnuckle)
{
Erase(e.Handpart.Position, 35.0);
}
else if(e.Handpart.Identifier.IndexKnuckle)
{
Erase(e.Handpart.Position, 25.0);
}
else if(e.Handpart.Identifier.MiddleKnuckle)
{
Erase(e.Handpart.Position, 20.0);
}
else if(e.Handpart.Identifier.RingKnuckle)
{
Erase(e.Handpart.Position, 15.0);
}
else if(e.Handpart.Identifier.PinkieKnuckle)
{
Erase(e.Handpart.Position, 10.0);
}
}
This is where the hand part tutorial ends. You've learned how to differentiate between hand parts and assign separate functions to them.