ahmad05
ahmad05

Reputation: 458

Body joints angle using Kinect

I have just working on kinect and C# programming so I am very amateur at it I would like to know about joint angles.

I created this code just to test my skill without using kinect but am having trouble with the code.

I supposed vector3 v1 and vector3 v2 as a joint replacement but the value return from Find_angle is NaN.

Am I missing something in the process? Please any help in this regard will be helpful.

Vector3 V1 = new Vector3(100,40,90);
Vector3 v2 = new Vector3(160,60,90);
public MainWindow()
{
    InitializeComponent();

    Vector3.Normalize(V1);
    Vector3.Normalize(v2);

    float Result = this.find_angle(V1,v2);
    MessageBox.Show(Result.ToString());
}
public float find_angle(Vector3 va, Vector3 vb)
{
    float dot_pro=Vector3.Dot(va, vb);
    double angle = Math.Acos(dot_pro);

    angle = angle * 180 / Math.PI;

    return (float)(angle);
}

Upvotes: 2

Views: 6359

Answers (3)

gustavodidomenico
gustavodidomenico

Reputation: 4681

I am not familiar with it but you should divide the product of the vectors by the size of them before applying the acos.

Example:

double len_prod = va.Len * vb.Len;
double angle = Math.Acos(dot_pro / len_prod);

Upvotes: 0

EdgarT
EdgarT

Reputation: 1088

If you are using Kinect SDK to get the skeletal tracking, the you can use this:

    /// <summary>
    /// Return the angle between 3 Joints
    /// Regresa el ángulo interno dadas 3 Joints
    /// </summary>
    /// <param name="j1"></param>
    /// <param name="j2"></param>
    /// <param name="j3"></param>
    /// <returns></returns>
    public static double AngleBetweenJoints(Joint j1, Joint j2, Joint j3)
    {
        double Angulo = 0;
        double shrhX = j1.Position.X - j2.Position.X;
        double shrhY = j1.Position.Y - j2.Position.Y;
        double shrhZ = j1.Position.Z - j2.Position.Z;
        double hsl = vectorNorm(shrhX, shrhY, shrhZ);
        double unrhX = j3.Position.X - j2.Position.X;
        double unrhY = j3.Position.Y - j2.Position.Y;
        double unrhZ =j3.Position.Z - j2.Position.Z;
        double hul = vectorNorm(unrhX, unrhY, unrhZ);
        double mhshu = shrhX * unrhX + shrhY * unrhY + shrhZ * unrhZ;
        double x = mhshu / (hul * hsl);
        if (x != Double.NaN) 
        {
            if (-1 <= x && x <= 1)
            {
                double angleRad = Math.Acos(x);
                Angulo = angleRad *(180.0 / Math.PI);
            }
            else
                Angulo = 0;


        }
        else
            Angulo = 0;


        return Angulo;

    }


    /// <summary>
    /// Euclidean norm of 3-component Vector
    /// </summary>
    /// <param name="x"></param>
    /// <param name="y"></param>
    /// <param name="z"></param>
    /// <returns></returns>
    private static double vectorNorm(double x, double y, double z)
    {

        return Math.Sqrt(Math.Pow(x, 2) + Math.Pow(y, 2) + Math.Pow(z, 2));

    }

This method use 3 joints to get an angle.

enter image description here

Upvotes: 1

Kinected
Kinected

Reputation: 441

Get the X and Y's of the joint you want, then get a joint on either side of it. Then see how to calculate the angle for How do I calculate angle from two coordinates?

Basically do:

float x1 = joint1.X;
float y1 = joint1.Y;

float x2 = joint2.X;
float y2 = joint2.Y;

float angleRadians;

float diffX = x2 - x1;
float diffY = y2 - y1;

float atan2Result = (float)Math.Atan2(diffX, diffY);
angleRadians = atan2Result / 2;
if (angleRadians < 0.0f)
    angleRadians += (float)Math.PI;

float tempCosine = (float)Math.Cos(angleRadians);
float tempSine = ((float)Math.Sin(angleRadians) * -1);

EDIT

You might want to see Kinect sideways skeleton tracking for the capabilities of joint tracking

Upvotes: 2

Related Questions