3

I am reasonably new to Kinect development and I am trying to build a component that allows rotations of Kinect joints. The purpose of this is to manually "fix" any skeleton data I've captured, post capture, where the skeleton starts jumping around.

I am displaying the Kinect skeleton in 3D space using the helix toolkit. I can pause the skeleton stream at any given point and see the matrix values held in the BoneRotations object for the AbsoluteRotation and the HierarchicalRotation.

I've created three sliders which represent an X-axis, Y-axis and Z-axis. I have set their min/max values to something which is relevant to bone's natural movement that is to be manipulated (e.g on the Yaxis, the shoulder doesn't move above roughly 40 degrees). If we take the shoulder (right) joint as an example, I want to be able to apply rotations on each of the axis so that I can change the position of the bone in 3D space. I believe the terminology that relates to this sort of action is forward kinematics.

My questions are:

a) The Kinect SDK gives an absolute and hierarchical matrix for the joint. Which one should I be looking at to manipulate?

b) What does the Quaternion give you that the matrix doesn't?

c) How do I take the 4x4 matrix information and find the angle (either in degrees or radians) for the X-axis, Y-axis and Z-axis?

d) I've seen how to transform 3x3 matrices by multiplying them using a calculation like this:

    Matrix3X3 matrixx = new Matrix3X3();
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            matrixx.elements[(i * 3) + j] = ((R2.elements[i * 3] * R1.elements[j]) + (R2.elements[(i * 3) + 1] * R1.elements[3 + j])) + (R2.elements[(i * 3) + 2] * R1.elements[6 + j]);
        }
    }
    return matrixx;

How do I transform the 4x4 matrix that is given by the Kinect SDK?

More specifically, can I transform the 4x4 matrix on each axis so that I can have a slider for each axis? So how do I apply an X-axis rotation of 10 degrees? I've seen rotations done on 3x3 matrices as follows:

    public static Matrix3D NewRotateAroundX(double radians)
    {
        var matrix = new Matrix3D();
        matrix._matrix[1, 1] = Math.Cos(radians);
        matrix._matrix[1, 2] = Math.Sin(radians);
        matrix._matrix[2, 1] = -(Math.Sin(radians));
        matrix._matrix[2, 2] = Math.Cos(radians);
        return matrix;
    }
    public static Matrix3D NewRotateAroundY(double radians)
    {
        var matrix = new Matrix3D();
        matrix._matrix[0, 0] = Math.Cos(radians);
        matrix._matrix[0, 2] = -(Math.Sin(radians));
        matrix._matrix[2, 0] = Math.Sin(radians);
        matrix._matrix[2, 2] = Math.Cos(radians);
        return matrix;
    }
    public static Matrix3D NewRotateAroundZ(double radians)
    {
        var matrix = new Matrix3D();
        matrix._matrix[0, 0] = Math.Cos(radians);
        matrix._matrix[0, 1] = Math.Sin(radians);
        matrix._matrix[1, 0] = -(Math.Sin(radians));
        matrix._matrix[1, 1] = Math.Cos(radians);
        return matrix;
    }

Thanks for help in advance!

Rob
  • 6,819
  • 17
  • 71
  • 131

1 Answers1

2

This is multiple questions and you should probably break them down and ask each one separately.

a) I haven't played with Kinect but generally speaking absolute is relative to world space and hierarchical is relative to the parent. Most of the time you want to move a joint relative to its parent.

b) This question is asked the wrong way round. A quaternion represents an axis and a rotation about that axis, a matrix can store this transform plus many other types including scale, translate, skew, projection etc.

c) The first 3 elements of the first 3 rows in a matrix give you each axis i.e. X, Y, and Z (again in either world space or parent space, depending on which one you're working with). Extract those, pick the 2 you're after and Google "angle between any 2 3D lines" (it's the inverse cosine of the dot product between them).

d) The correct algorithm to use depends on a number of things, there's the "correct" way and then there are a lot of other (faster) ways that will also work if you can guarantee that your matrices will always follow certain properties like being affine etc. Wikipedia has a page about matrix multiplication or you can read an old article I wrote almost 20 years ago with code. The latter should also help explain a bit more about how they work and maybe show you how to do some of the other things you'll looking to do.

Mark Feldman
  • 15,731
  • 3
  • 31
  • 58
  • Thanks for that Mark. Answer A makes sense. Question B -> I know you've not really experienced with the Kinect SDK, but it gives a Quaternion, so I just don't understand what it contains. What axis is its rotation information based on? (might just be my lack of understanding). Question C-> Think I can work this out, thanks. Question D -> Time to get reading and understanding! :-) – Rob Dec 09 '13 at 19:25
  • There are plenty of tutorials out there that explain quaternions in far more detail than I can here, a good one is http://www.cprogramming.com/tutorial/3d/quaternions.html. A quaternion consists of 4 components (XYZW) and is typically used to do a rotation i.e. rotate the point about the line P1=<0,0,0> and P2= and rotate it by W radians. As that article shows you can convert a quaternion into a matrix, although you can't always convert a matrix into a quaternion because it may have other things like translation etc. – Mark Feldman Dec 09 '13 at 21:34
  • All this begs the question "well why use quaterions in the first place?". Quaternions have math operations just as matrices do but if you're dealing with rotations only then quaternion math tends to be a bit easier and also faster. That said I spent 16 years as a 3D graphics programmer and didn't really use them much other than when I needed to import them from somewhere else like you are now. If you have a good matrix library and your app isn't time-critical then just convert them to matrices and use regular matrix operations for everything, you'll save yourself a lot of headache IMO. – Mark Feldman Dec 09 '13 at 21:38