www.pudn.com > 人体步态跟踪识别bate版.rar > IK.cpp


// IK.cpp: implementation of the CIK class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "humantrack.h" 
#include "IK.h" 
#include "math.h" 
#include "dpoint2d.h" 
#include "Position.h" 
#include "dibapi.h" 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
CIK::CIK() 
{ 
} 
 
CIK::~CIK() 
{ 
 
} 
/** 
*   Calculate the included of link1 and link2 
* 
*   len1     : the length of link1 
*   len2     : the length of link2  
*   distance : the distance of the endpoints of link1 and link2 
*/ 
double CIK::IK_1D(double len1, double len2, double distance) 
 { 
 
 return acos((len1*len1 + len2*len2- distance*distance) / (2*len1*len2)); 
} 
 
/** 
*   if unsolvable, then return null 
* 
*      x-------x-------x 
*   point1   point   point2 
* 
*   link1    : the link from point1 to point 
*   link2    : the link from point2 to point 
*   len1     : the length of link1 
*   len2     : the length of link2 
*   distance : the distance between point1 and point2 
*   nVector  : the vector from point1 to the projection of point 
*              on the vector from point1 to point2 
*   hVector  : the vector from the projection of point on the vector 
*              from point1 to point2 to point 
*   flag     : true -> the vector from point1 to point2 X hVector >= 0 
*/ 
CDPoint2D CIK::IK_2D(CDPoint2D point1, double len1,CDPoint2D point2, double len2,bool flag)  
{ 
 
      double distance = point1.distance(point2); 
      len1 = abs(len1); 
      len2 = abs(len2); 
 
      CDPoint2D point ; 
 
      if(abs(len1 - len2)<= distance && (distance <= (len1 + len2)) && distance != 0)  
	  { 
 
         /** 
          *  theta : the included of link1 and link2 
          */ 
         double theta  = IK_1D(len1, len2, distance); 
 
         /** 
          *   lnVector : the length of nVector 
          *   a*b*sin(theta) = c*h 
          */ 
         double lnVector = len1 * len2 * sin(theta) / distance; 
 
         /** 
          *   lhVector : the length of hVector 
          */ 
         double lhVector = sqrt(len1*len1 - lnVector*lnVector); 
 
         /** 
          *   calculate the nVector 
          */ 
         double nVectorX = (point1.y - point2.y) * lnVector / distance; 
         double nVectorY = (point2.x - point1.x) * lnVector / distance; 
 
         /** 
          *   calculate the nVector 
          */ 
         double hVectorX = (point2.x - point1.x) * lhVector / distance; 
         double hVectorY = (point2.y - point1.y) * lhVector / distance; 
 
         if(!flag)  
		 { 
 
            nVectorX *= -1; 
            nVectorY *= -1; 
         } 
 
         if(cos((len1*len1 + distance*distance- len2*len2)/(2*len1*distance)) < 0) 
		 { 
 
            hVectorX *= -1; 
            hVectorY *= -1; 
         } 
 
       CDPoint2D point(point1.x + hVectorX + nVectorX,point1.y + hVectorY + nVectorY); 
      } 
 
      return point; 
   } 
 
CDPoint2D CIK::IK_2D(CDPoint2D point1, double len1,CDPoint2D point2, double len2)  
{ 
 
      return IK_2D(point1, len1, point2, len2, true); 
   } 
 
CPosition CIK::IK_3D(CPosition point1, double len1,CPosition point2, double len2,double dx, double dy, double dz) 
 { 
 
      double distance = point1.distance(point2); 
      len1 = abs(len1); 
      len2 = abs(len2); 
 
      CPosition point; 
 
      if(abs(len1 - len2) <= distance && (distance <= (len1 + len2)) && distance != 0) 
	  { 
 
    /** 
   *  theta : the included of link1 and link2 
   */ 
         double theta  = IK_1D(len1, len2, distance); 
 
         /** 
          *   lnVector : the length of nVector 
          *   a*b*sin(theta) = c*h 
          */ 
         double lnVector = len1 * len2 * sin(theta) / distance; 
 
         /** 
          *   lhVector : the length of hVector 
          */ 
         double lhVector = sqrt(len1*len1 - lnVector*lnVector); 
 
         double vx = point2.x - point1.x; // x of the vector of point1 to point2 
         double vy = point2.y - point1.y; // y of the vector of point1 to point2 
         double vz = point2.z - point1.z; // z of the vector of point1 to point2 
         /** 
          *   calculate the nVector => nVector = ((p1->p2) x dVector) x (p1->p2) 
          */ 
         double nVectorX = vz*vz*dx - vz*vx*dz - vy*vx*dy + vy*vy*dx; 
         double nVectorY = vx*vx*dy - vx*vy*dx - vz*vy*dz + vz*vz*dy; 
         double nVectorZ = vy*vy*dz - vy*vz*dy - vx*vz*dx + vx*vx*dz; 
 
         double l = sqrt(nVectorX*nVectorX + nVectorY*nVectorY + nVectorZ*nVectorZ); 
 
         nVectorX = nVectorX * lnVector / l; 
         nVectorY = nVectorY * lnVector / l; 
         nVectorZ = nVectorZ * lnVector / l; 
 
         /** 
          *   calculate the nVector 
          */ 
         double hVectorX = vx * lhVector / distance; 
         double hVectorY = vy * lhVector / distance; 
         double hVectorZ = vz * lhVector / distance; 
 
         if((len1*len1 + distance*distance - len2*len2)/(2*len1*distance) < 0)  
		 { 
 
            hVectorX *= -1; 
            hVectorY *= -1; 
            hVectorZ *= -1; 
         } 
 
         theta = ::DoubleModule((atan2(vy, vx)+2*PI),(2*PI)); 
 
        CPosition point(point1.x + hVectorX + nVectorX,point1.y + hVectorY + nVectorY,point1.z + hVectorZ + nVectorZ, theta); 
      } 
 
      return point; 
}