分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

作者:朱金灿
来源:http://blog.csdn.net/clever101/


         这里讲述的二维图形是指诸如三角形、多边形围绕某一中心点进行指定角度的旋转。二维图形其实是由一系列的离散点组成的,离散点放在特定的坐标系就是向量。因此二维图形的旋转的基础就是向量的旋转。


     首先考虑一个向量 p = (x,y) , 那么它写成坐标的形式就是x+iy,这个就是P点在复平面的坐标.

问题: 假设现在有一个角度d,并且使向量p沿逆时针方向旋转d角度并且不改变其模的大小.请问旋转后 的向量p'是什么呢?


问题分析:


简单举例.....


     对于一个向量p (1,0),使它向逆时针旋转90度,并且不改变其模的大小,我们会很清楚的画出,这个变化后的向量就是p' (0,1),我们把它们都恢复的一般形式,原向量(1,0) --- 1 + i * 0, 新向量(0,1) --- 0 + i * 1,我们不难发现把原来的向量p的一般形式乘以一个i,然后整理就会得到新的向量p'的坐标一般形式....进一步想象,i是什么呢? i = cos(90) + i*sin(90);那也就是说可以得出这样一个结论:

对于一个向量p : x + i * y 来说,如果向逆时针旋转d角度的话,新的向量p'应该是向量p的一般表达式(x+i*y)乘以cos(d)+i*sin(d) ,然后整理得出一个结果,将i的系数看成p'的复数部分,将其他部分看成p'的整数部分,由于又要保证它的大小不改变,所以我们只要保证乘的向量的模大小要为1,恰巧cos(d)+i*sin(d)全部满足.

所以说对于p = (x,y)这个向量向逆时针旋转且大小不改变所得到的向量如下:

p: (x,y) --------> p': ( x*cos(d)-y*sin(d) , x*sin(d)+y*cos(d) )


如果是向顺时针旋转则:

p: (x,y) --------> p': ( x*cos(-d)-y*sin(-d) , x*sin(-d)+y*cos(-d) )


     现在我们明白了向量旋转的原理,你可以看到上面的向量旋转是围绕原点(0,0)进行得,我们现在要实现的是围绕某一中心点进行旋转,该怎么做呢?很简单,就是将要旋转的点平移到以中心点位原点的坐标系,旋转完成之后再平移回来(为了方便绘制)。


      明白了原理,于是编程实现。下面是主要实现代码:

  1. double const PI = 3.1415926;  
  2. /*! @struct  
  3. * @brief 二维点结构体 
  4. * 
  5. *    
  6. */  
  7. struct stPoint  
  8. {  
  9.      stPoint(CPoint &point)  
  10.      {  
  11.         m_CoorX = static_cast<double>(point.x);  
  12.         m_CoorY = static_cast<double>(point.y);  
  13.      }  
  14.      stPoint(double x,double y)  
  15.      {  
  16.         m_CoorX = x;  
  17.         m_CoorY = y;  
  18.      }  
  19.        
  20.      /*! 
  21.      *  @brief 执行和MFC的CPoint类的转换 
  22.      * 
  23.      *  /return 转换后的点 
  24.      */  
  25.      operator CPoint const ()  
  26.      {  
  27.          return CPoint(static_cast<long>(m_CoorX),static_cast<long>(m_CoorY));  
  28.      }  
  29.      stPoint operator - (stPoint &OtherPt)  
  30.      {  
  31.          return stPoint(m_CoorX-OtherPt.m_CoorX,m_CoorY-OtherPt.m_CoorY);  
  32.      }  
  33.      stPoint operator + (stPoint &OtherPt)  
  34.      {  
  35.          return stPoint(m_CoorX+OtherPt.m_CoorX,m_CoorY+OtherPt.m_CoorY);  
  36.      }  
  37.      double m_CoorX;  
  38.      double m_CoorY;  
  39. };  
  40. /*! 
  41. *  @brief 计算x*sin(d)+y*cos(d) 
  42. * 
  43. *  @param [in]Left 左点 
  44. *  @param [in]Right 右点 
  45. *  /return 计算结果 
  46. */  
  47. double VectorMulti(stPoint &Left,stPoint &Right)  
  48. {  
  49.     return (Left.m_CoorX*Right.m_CoorY+Left.m_CoorY*Right.m_CoorX);  
  50. }  
  51. /*! 
  52. *  @brief 计算x*cos(d)-y*sin(d) 
  53. * 
  54. *  @param [in]Left 左点 
  55. *  @param [in]Right 右点 
  56. *  /return 计算结果 
  57. */  
  58. double CrossProduct(stPoint &Left,stPoint &Right)  
  59. {  
  60.     return (Left.m_CoorX*Right.m_CoorX-Left.m_CoorY*Right.m_CoorY);  
  61. }  
  62. /*! 
  63. *  @brief 计算( x*cos(d)-y*sin(d) , x*sin(d)+y*cos(d) ) 
  64. * 
  65. *  @param [in]point 待旋转的点 
  66. *  @param [in]Right 转换点 
  67. *  /return 旋转后的点 
  68. */  
  69. stPoint PointMulti(stPoint &point,stPoint &TranPt)  
  70. {  
  71.     return stPoint(CrossProduct(point,TranPt),VectorMulti(point,TranPt));  
  72. }  
  73. /*! 
  74. *  @brief 对二维图形的单个点进行变换 
  75. * 
  76. *  @param [in][out]point 待旋转的点 
  77. *  @param [in]nAngle 旋转角度 
  78. *  @param [in]RotateCenter 旋转中心点 
  79. *  /return  
  80. */  
  81. void PointRotate(stPoint &point,int nAngle,stPoint &RotateCenter)  
  82. {  
  83.      // 平移到以中心点位原点的坐标系  
  84.      point = point - RotateCenter;  
  85.      // 角度转弧度  
  86.      double radian = static_cast<double>(nAngle)/180.0*PI;  
  87.      stPoint RotatePt(cos(radian),sin(radian));  
  88.      point = PointMulti(point,RotatePt);  
  89.      // 平移回来  
  90.      point = point + RotateCenter;  
  91. }  
double const PI = 3.1415926;/*! @struct * @brief 二维点结构体**   */struct stPoint{     stPoint(CPoint &point)  {        m_CoorX = static_cast<double>(point.x);  m_CoorY = static_cast<double>(point.y);  }  stPoint(double x,double y)  {        m_CoorX = x;        m_CoorY = y;  }       /*!  *  @brief 执行和MFC的CPoint类的转换  *  *  /return 转换后的点  */  operator CPoint const ()  {   return CPoint(static_cast<long>(m_CoorX),static_cast<long>(m_CoorY));  }  stPoint operator - (stPoint &OtherPt)  {         return stPoint(m_CoorX-OtherPt.m_CoorX,m_CoorY-OtherPt.m_CoorY);  }  stPoint operator + (stPoint &OtherPt)  {   return stPoint(m_CoorX+OtherPt.m_CoorX,m_CoorY+OtherPt.m_CoorY);  }  double m_CoorX;  double m_CoorY;};/*!*  @brief 计算x*sin(d)+y*cos(d)**  @param [in]Left 左点*  @param [in]Right 右点*  /return 计算结果*/double VectorMulti(stPoint &Left,stPoint &Right){ return (Left.m_CoorX*Right.m_CoorY+Left.m_CoorY*Right.m_CoorX);}/*!*  @brief 计算x*cos(d)-y*sin(d)**  @param [in]Left 左点*  @param [in]Right 右点*  /return 计算结果*/double CrossProduct(stPoint &Left,stPoint &Right){ return (Left.m_CoorX*Right.m_CoorX-Left.m_CoorY*Right.m_CoorY);}/*!*  @brief 计算( x*cos(d)-y*sin(d) , x*sin(d)+y*cos(d) )**  @param [in]point 待旋转的点*  @param [in]Right 转换点*  /return 旋转后的点*/stPoint PointMulti(stPoint &point,stPoint &TranPt){ return stPoint(CrossProduct(point,TranPt),VectorMulti(point,TranPt));}/*!*  @brief 对二维图形的单个点进行变换**  @param [in][out]point 待旋转的点*  @param [in]nAngle 旋转角度*  @param [in]RotateCenter 旋转中心点*  /return */void PointRotate(stPoint &point,int nAngle,stPoint &RotateCenter){  // 平移到以中心点位原点的坐标系  point = point - RotateCenter;  // 角度转弧度  double radian = static_cast<double>(nAngle)/180.0*PI;     stPoint RotatePt(cos(radian),sin(radian));     point = PointMulti(point,RotatePt);  // 平移回来     point = point + RotateCenter;} 


效果图:

旋转前:


二维图形旋转的实现


旋转后:


二维图形旋转的实现


相关源码下载:


二维图形旋转实现的相关代码


参考文献:


1. 神奇的向量旋转









           

给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow

二维图形旋转的实现

相关文章: