Blog‎ > ‎Software‎ > ‎

Kinect Angle Tutorial

posted Jan 27, 2012, 7:00 AM by Nick Lorch   [ updated Jan 27, 2012, 8:31 AM ]
Alright, so I did a little thinking and reviewed some old projects and I have a good way to find any angle you want with the Kinect.

Finding the Angles Between Vectors

The Kinect interface allows you to query for different joints in the skeleton.  These joints are represented in a 3D coordinate space.  While the Kinect interface defines the coordinate system, it is not necessarily the right coordinate system for the angle we are looking for.  The easiest way to find an angle of something is to use trig,  Specifically 2D trig.  If I wanted to find the angle between 2 different 2D vectors I can use 1 of 2 methods.  The first method is the dot product.  The equation looks like following:

A*B = |A|*|B| cos(theta).

What this is saying is that if I take the dot product of vector A and vector B, I will get the length of A (|A|) and the length of B times the angle between them.  To make this simpler, if both the vectors lengths are 1 (also called unit vectors), then I can reduce the equation to:

A*B = cos(theta)

So this is one way to find the angle between 2 vectors.  However, I like keeping things simple when at all possible.  In traditional trig, you can find the angle of a triangle if you know 2 sides and an angle.  So if we could align one of our vectors such that it matches an axis, then we could make it look like a triangle and do simple math on it.

                                                        

The goal is to take our vectors and put it into a coordinate system that we can understand. Then we want to align the vectors in a way that we only need to find the change in "X" and the change in "Y" and we can determine our angle.  The challenge with the connect is that it is in 3D space and almost all joints are not in a coordinate system where we can apply the above methods.  Therefore, we will have to do some vector operations to get us there.



Dot and Cross Products

The 2 main vector operations that are used are the dot product (*) and the cross product (x).  As I said before when you take a dot product of 2 unit vectors (length 1) you will get the angle between them.  The cross product is a little different.  Its main function for our sake is that it will return a new vector that is perpendicular to both the input vectors.  An easy example for a cross product is if you took a vector X (1,0,0) and crossed it with vector Y (0,1,0).  This would result in the vector Z (0,0,1).  Cross products are useful for us because its an easy way to define 3 vectors that are all perpendicular to each other (aka a coordinate system).  If I assume the cross product we want is A x B = C, the mathematical formula for a cross product is: 

    C[0] = ( A[1] * B[2] ) - ( A[2] *  B[1] )
    C[1] = ( A[2] * B[0] ) - ( A[0] *  B[2] )
    C[2] = ( A[0] * B[1] ) - ( A[1] *  B[0] )

It is also important to note that A x B != B x A.  If we went back to our first example with X x Y = Z, Y x X actually equals -Z.  Here is a much better explanation of the cross product: http://en.wikipedia.org/wiki/Cross_product

Kinect and Vectors

Steps (ran out of time, better tutorial coming later)
assuming you have 3 points: begin, mid, end and you are finding the angle where mid is the mid point.

  1. F vec = mid - begin
  2. U_tmp vec = mid + begin (trust me, this works)
  3. S = F x U_tmp
  4. U = S x F
Ok, now you have 3 vectors Side (S), Forward (F), Up (U). Now we need to make the 2nd vector (end - mid), and find out how much it has changed (ds, df, du) in regards of our new coordinate system from the point mid. 

  1. My_vec = end - mid
  2. ds = My_vec.dot(S)
  3. df = My_vec.dot(F)
  4. du = My_vec.dot(U)
Here comes the easy part.  Determine which 2 deltas (ds,df,du) you need to make the angle you want.  Most likely this will be ds and df.  Once you determined which two you need, you have created a local coordinate system and put one of the vectors on the axis (just like the 3rd picture above!).  All you need to do is take the arctangant of those 2 values and you have the angle (in radians of course).

  1. my_angle = atan2(df,ds) * radians to degrees.
you can now find any angle between any 3 joints on the entire skeleton!






Comments