2014-12-13 41 views
1

当我们想要将骨骼绘制到XNA中(使用KnectSDK和C#)时,必须计算两个关节之间的差异并在它们之间绘制骨骼。这是绘制骨骼的功能:DrawBone使用Kinect的角度变量

private void DrawBone(JointCollection joints, JointType startJoint, JointType endJoint) 
    { 
     Vector2 start = this.mapMethod(joints[startJoint].Position); 
     Vector2 end = this.mapMethod(joints[endJoint].Position); 
     Vector2 diff = end - start; 
     Vector2 scale = new Vector2(1.0f, diff.Length()/this.boneTexture.Height); 

     float angle = (float)Math.Atan2(diff.Y, diff.X) - MathHelper.PiOver2; 

     Color color = Color.LightGreen; 
     if (joints[startJoint].TrackingState != JointTrackingState.Tracked || 
      joints[endJoint].TrackingState != JointTrackingState.Tracked) 
     { 
      color = Color.Gray; 
     } 

     this.SharedSpriteBatch.Draw(this.boneTexture, start, null, color, angle, this.boneOrigin, scale, SpriteEffects.None, 1.0f); 
    } 

我只是想了解计算角度的方式和角度公式是如何工作的

感谢

回答

2

这里是计算两个之间的角度代码(说明如下代码):

public class Angles 
    { 
    public double AngleBetweenTwoVectors(Vector3D vectorA, Vector3D vectorB) 
     { 
      double dotProduct = 0.0; 
      dotProduct = Vector3D.DotProduct(vectorA, vectorB); 

      return (double)Math.Acos(dotProduct)/Math.PI*180; 
     } 

     public double[] GetVector(Skeleton skeleton) 
     { 
      Vector3D ShoulderCenter = new Vector3D(skeleton.Joints[JointType.ShoulderCenter].Position.X, skeleton.Joints[JointType.ShoulderCenter].Position.Y, skeleton.Joints[JointType.ShoulderCenter].Position.Z); 
      Vector3D RightShoulder = new Vector3D(skeleton.Joints[JointType.ShoulderRight].Position.X, skeleton.Joints[JointType.ShoulderRight].Position.Y, skeleton.Joints[JointType.ShoulderRight].Position.Z); 
      Vector3D LeftShoulder = new Vector3D(skeleton.Joints[JointType.ShoulderLeft].Position.X, skeleton.Joints[JointType.ShoulderLeft].Position.Y, skeleton.Joints[JointType.ShoulderLeft].Position.Z); 
      Vector3D RightElbow = new Vector3D(skeleton.Joints[JointType.ElbowRight].Position.X, skeleton.Joints[JointType.ElbowRight].Position.Y, skeleton.Joints[JointType.ElbowRight].Position.Z); 
      Vector3D LeftElbow = new Vector3D(skeleton.Joints[JointType.ElbowLeft].Position.X, skeleton.Joints[JointType.ElbowLeft].Position.Y, skeleton.Joints[JointType.ElbowLeft].Position.Z); 
      Vector3D RightWrist = new Vector3D(skeleton.Joints[JointType.WristRight].Position.X, skeleton.Joints[JointType.WristRight].Position.Y, skeleton.Joints[JointType.WristRight].Position.Z); 
      Vector3D LeftWrist = new Vector3D(skeleton.Joints[JointType.WristLeft].Position.X, skeleton.Joints[JointType.WristLeft].Position.Y, skeleton.Joints[JointType.WristLeft].Position.Z); 

      /* ShoulderCenter.Normalize(); 
      RightShoulder.Normalize(); 
      LeftShoulder.Normalize(); 
      RightElbow.Normalize(); 
      LeftElbow.Normalize(); 
      RightWrist.Normalize(); 
      LeftWrist.Normalize(); 

      if (skeleton.Joints[JointType.ShoulderCenter].TrackingState == JointTrackingState.Tracked) { 

      } 
      */ 

      double AngleRightElbow = AngleBetweenTwoVectors(RightElbow - RightShoulder, RightElbow - RightWrist); 
      double AngleRightShoulder = AngleBetweenTwoVectors(RightShoulder - ShoulderCenter, RightShoulder - RightElbow); 
      double AngleLeftElbow = AngleBetweenTwoVectors(LeftElbow - LeftShoulder, LeftElbow - LeftWrist); 
      double AngleLeftShoulder = AngleBetweenTwoVectors(LeftShoulder - ShoulderCenter, LeftShoulder - LeftElbow); 

      double[] Angles = {AngleRightElbow, AngleRightShoulder, AngleLeftElbow, AngleLeftShoulder}; 
      return Angles; 
     } 
} 

首先我们来看看方法GetVector(Skeleton skeleton)。在这种方法中,我们首先定义我们的Vector3D(针对您选择的关节)。然后我们调用方法AngleBetweenTwoVectors并给它两个参数。

但注意。如果我们只是给它的关节矢量,我们不会得到正确的角度。我们首先必须从矢量中减去周围的矢量(我们想从中得到矢量的矢量)。然后我们将这两个向量传递给方法AngleBetweenTwoVectors

在这种方法中,我们首先必须计算点积。有关点积的更多信息,请点击here。使用点积可以计算出角度。为此,我们只需要使用arcos()方法。

我挣扎着的另一件事:组件。 您需要导入:

using System.Windows.Media; 
using Microsoft.Kinect; 
using Microsoft.Kinect.Toolkit.Fusion; 
using System.Windows.Media.Media3D; 

要获得[...] Toolkit.Fusion组装进入“添加引用”,然后点击“浏览”。然后,您将引导到MicrosoftSDK/Kinect/Developer Toolkit v1.8.0/Assemblies中的汇编目录。导入程序集并将其添加到项目中。