Vector 使用3个给定的三维点计算角度

Vector 使用3个给定的三维点计算角度,vector,xna,microsoft-metro,windows-runtime,kinect,Vector,Xna,Microsoft Metro,Windows Runtime,Kinect,我正在为metro应用程序在winrt上进行kinect实验。 我正试图获得肘部的角度 通常我会做以下事情 Vector3D handLeftVector = new Vector3D(HandLeftX, HandLeftY, HandLeftZ); handLeftVector.Normalize(); Vector3D ElbowLeftEVector = new Vector3D(ElbowLeftX, ElbowLeftY, ElbowLeftZ); ElbowLeftEVector

我正在为metro应用程序在winrt上进行kinect实验。 我正试图获得肘部的角度

通常我会做以下事情

Vector3D handLeftVector = new Vector3D(HandLeftX, HandLeftY, HandLeftZ);
handLeftVector.Normalize();

Vector3D ElbowLeftEVector = new Vector3D(ElbowLeftX, ElbowLeftY, ElbowLeftZ);
ElbowLeftEVector.Normalize();

Vector3D ShoulderLeftVector = new Vector3D(ShoulderLeftX, ShoulderLeftY, ShoulderLeftZ);
ShoulderLeftVector.Normalize();

Vector3D leftElbowV1 = ShoulderLeftVector - ElbowLeftEVector;
Vector3D leftElbowV2 = handLeftVector - ElbowLeftEVector;
double leftElbowAngle = Vector3D.AngleBetween(leftElbowV1, leftElbowV2);
但是,winrt中没有Vector3D对象

我决定复制Vector3D方法,如下所示。然而,结果似乎并不像预期的那样。我在哪里犯了错误吗

double leftElbowV1X = ShoulderLeftX - ElbowLeftX;
double leftElbowV1Y = ShoulderLeftY - ElbowLeftY;
double leftElbowV1Z = ShoulderLeftZ - ElbowLeftZ;

double leftElbowV2X = handLeftX - ElbowLeftX;
double leftElbowV2Y = handLeftY - ElbowLeftY;
double leftElbowV2Z = handLeftZ - ElbowLeftZ;

double product = leftElbowV1X * leftElbowV2X + leftElbowV1Y * leftElbowV2Y + leftElbowV1Z * leftElbowV2Z;

double magnitudeA = Math.Sqrt(Math.Pow(leftElbowV1X, 2) + Math.Pow(leftElbowV1Y, 2) + Math.Pow(leftElbowV1Z, 2));
double magnitudeB = Math.Sqrt(Math.Pow(leftElbowV2X, 2) + Math.Pow(leftElbowV2Y, 2) + Math.Pow(leftElbowV2Z, 2));
magnitudeA = Math.Abs(magnitudeA);
magnitudeB = Math.Abs(magnitudeB);

double cosDelta = product / (magnitudeA * magnitudeB);
double angle = Math.Acos(cosDelta) *180.0 / Math.P;
是否有必要使其正常化


我已经设法解决了这个问题,但是我在想是否有更有效的方法。

不确定这是否有帮助,但这是我使用的一些旧角度代码,以度为单位返回:

float AngleBetween(Vector3 from, Vector3 dest)  {
    float len = from.magnitude *  dest.magnitude;
    if(len < Mathf.Epsilon) len = Mathf.Epsilon;

    float f = Vector3.Dot(from,dest) / len;
    if(f>1.0f)f=1.0f;
    else if ( f < -1.0f) f = -1.0f;

    return Mathf.Acos(f) * 180.0f / (float)Math.PI;
}
float AngleBetween(Vector3 from,Vector3 dest){
float len=from.magnet*dest.magnet;
如果(len1.0f)f=1.0f;
否则,如果(f<-1.0f)f=-1.0f;
返回Mathf.Acos(f)*180.0f/(浮点)Math.PI;
}

显然,它使用的是特定于API的语法,但我认为方法很清楚。

如果您使用ILSpy()对
Vector3D
代码进行反编译,您应该能够获得正确的代码。感谢ILSpy,它帮助我确认我的dotproduct是正确的,但是我仍然不确定我的代码的哪一部分是错误的。请注意,我忘记了将rad转换为degAs。根据我的记忆,首先对两个向量进行规格化,然后取规格化向量的点积,除以它们之间的距离(差向量的大小)最后得到这个除法的ACO,作为两个向量之间的角度…不同的语法,但大致如下:
v1Norm=v1.normalize();v2Norm=v2.normalize();浮动角度=acos(v1Norm.dot(v2Norm)/dist(v1Norm,v2Norm))