zoukankan      html  css  js  c++  java
  • 罗德里格斯公式

        在三维空间中,给定一固定旋转轴,任意初始向量绕旋转轴旋转任意角度,可表示为 ,其中,v 表示旋转前向量, 表示旋转后向量,R 表示旋转矩阵,该矩阵参数与固定旋转轴坐标,旋转角度有关。下面使用图示推导旋转矩阵 R:

        

        如上图所示,单位向量 为固定旋转轴,原向量 v 旋转  后为 

        分解原向量 ,向量 v 与向量 k(或者 ) 的夹角为 ,该值已知;

        向量  构成直角三角形,则有:

        向量叉乘 ,其方向垂直于 构成的平面,w 的模长为  ,则有  ,且两向量正交;

        以上向量  构成三维空间已知正交向量基, 可表示:,在 向量构成平面上, 旋转  后为:

        ,由于 ,进一步化简为:

        

        定义向量 ,其方向与 平行,其模长为 ,则 

        引入向量 的叉积矩阵 ,叉积运算可转换为矩阵运算 

        改写  线性组合 ,引入叉积矩阵 K得:

        

        则旋转矩阵 

        以下给出代码实现:

     1     void GetRotateMatrix(Matrix<float>& Q, Vector<float>& axis, float theta)
     2     {
     3         // 使用罗德里格斯公式(Rodriguez formula)
     4 
     5         // 构造单位向量
     6         float len = sqrt(axis.data[0] * axis.data[0] +
     7             axis.data[1] * axis.data[1] + axis.data[2] * axis.data[2]);
     8         axis.data[0] = axis.data[0] / len;
     9         axis.data[1] = axis.data[1] / len;
    10         axis.data[2] = axis.data[2] / len;
    11         
    12         // 构造叉积矩阵K
    13         Matrix<float> K(3, 3);
    14         *(K.data + 0) = 0.;
    15         *(K.data + 1) = -axis.data[2];
    16         *(K.data + 2) = axis.data[1];
    17         *(K.data + K.step * 1 + 0) = axis.data[2];
    18         *(K.data + K.step * 1 + 1) = 0.;
    19         *(K.data + K.step * 1 + 2) = -axis.data[0];
    20         *(K.data + K.step * 2 + 0) = -axis.data[1];
    21         *(K.data + K.step * 2 + 1) = axis.data[0];
    22         *(K.data + K.step * 2 + 2) = 0.;
    23 
    24         // 求K^2
    25         Matrix<float> K_Temp; K_Temp = K;
    26         Matrix<float> K_2; K_2 = K;
    27         K_2.Multiply(K, K_Temp);
    28 
    29         // 求变换矩阵Q(Q = I + (1 - cos(theta))K^2 + sin(theta)K)
    30         K.ScalarMultiply(sin(theta));
    31         K_2.ScalarMultiply(1. - cos(theta));
    32         K_Temp.SetIdentity();
    33 
    34         Q.SetZero();
    35         Q.Add(K);
    36         Q.Add(K_2);
    37         Q.Add(K_Temp);
    38 
    39         // 得到旋转矩阵后,使用旋转矩阵Q将任意点沿axis轴旋转theta幅度
    40     }

        

      1     template<typename TYPE> struct  Matrix
      2     {
      3         int rows;
      4         int cols;
      5         int step;
      6 
      7         TYPE* data;
      8 
      9         Matrix()
     10         {
     11             rows = cols = step = 0;
     12             data = 0;
     13         }
     14 
     15         Matrix(int _rows, int _cols)
     16         {
     17             rows = _rows; 
     18             cols = _cols;
     19             step = _cols;
     20             data = (TYPE*)malloc(sizeof(TYPE) * rows * cols);
     21             memset(data, 0, sizeof(TYPE) * rows * cols);
     22         }
     23         
     24         ~Matrix()
     25         {
     26             if(!data) free(data);
     27         }
     28 
     29         void operator = (Matrix<TYPE>& _mat)
     30         {
     31             rows = _mat.rows;
     32             cols = _mat.cols;
     33             step = _mat.step;
     34 
     35             if(data) free(data);
     36             data = (TYPE*)malloc(sizeof(TYPE) * rows * cols);
     37             memcpy(data, _mat.data, sizeof(TYPE) * rows * cols);
     38         }
     39 
     40         bool Add(Matrix<TYPE>& src1)
     41         {
     42             if (src1.rows != rows || src1.cols != cols)
     43                 return false;
     44 
     45             for (int r = 0; r < rows; ++r)
     46                 for (int c = 0; c < cols; ++c)
     47                 {
     48                     *(data + r * step + c) += *(src1.data + r * src1.step + c);
     49                 }
     50         }
     51 
     52         void ScalarMultiply(double scalar)
     53         {
     54             for (int r = 0; r < rows; ++r)
     55                 for (int c = 0; c < cols; ++c)
     56                 {
     57                     *(data + r * step + c) = *(data + r * step + c) * scalar;
     58                 }
     59         }
     60 
     61         void SetZero()
     62         {
     63             memset(data, 0, sizeof(TYPE) * rows * cols);
     64         }
     65 
     66         void SetIdentity()
     67         {
     68             memset(data, 0, sizeof(TYPE) * rows * cols);
     69 
     70             int m = cols < rows ? cols : rows;
     71             for(int i = 0; i < m; ++i)
     72                 *(data + i * step + i) = 1;
     73         }
     74 
     75         void ExchangeRows(int i, int j)
     76         {
     77             if(i < rows && j < rows)
     78             {
     79                 TYPE* temp = (TYPE*)malloc(sizeof(TYPE) * rows);
     80                 memcpy(temp, data + i * step, sizeof(TYPE) * rows);
     81                 memcpy(data + i * step , data + j * step, sizeof(TYPE) * rows);
     82                 memcpy(data + j * step, temp, sizeof(TYPE) * rows);
     83                 free(temp);
     84             }
     85         }
     86 
     87         bool Transpose(Matrix<TYPE>& dst)
     88         {
     89             if(rows != dst.cols || cols != dst.rows || !data || !dst.data)
     90                 return false;
     91 
     92             for(int r = 0; r < rows; ++r)
     93             {
     94                 TYPE* src_data = data + r * step;
     95                 TYPE* dst_data = dst.data + r;
     96 
     97                 for(int c = 0; c < cols; ++c)
     98                 {
     99                     *dst_data = *src_data;
    100 
    101                     ++src_data;
    102                     dst_data += dst.step;
    103                 }
    104             }
    105 
    106             return true;
    107         }
    108 
    109     
    110         bool Multiply(Matrix<TYPE>& src1, Matrix<TYPE>& src2)
    111         {
    112             if(src1.cols != src2.rows || rows != src1.rows || cols != src2.cols) 
    113                 return false;
    114 
    115             for(int r = 0; r < rows; ++r)
    116             {
    117                 for(int c = 0; c < cols; ++c)
    118                 {
    119                     double value = 0.;
    120                     for (int i = 0; i < src1.cols; ++i)
    121                     {
    122                         value += (*(src1.data + r * src1.step + i)) * (*(src2.data + i * src2.step + c));
    123                     }
    124                     *(data + r * step + c) = value;
    125                 }
    126             }
    127 
    128             return true;
    129 
    130         }
    131 
    132     };

        

  • 相关阅读:
    HDU 3681 Prison Break 越狱(状压DP,变形)
    POJ 2411 Mondriaan's Dream (状压DP,骨牌覆盖,经典)
    ZOJ 3471 Most Powerful (状压DP,经典)
    POJ 2288 Islands and Bridges (状压DP,变形)
    HDU 3001 Travelling (状压DP,3进制)
    POJ 3311 Hie with the Pie (状压DP)
    POJ 1185 炮兵阵地 (状压DP,轮廓线DP)
    FZU 2204 7
    POJ 3254 Corn Fields (状压DP,轮廓线DP)
    ZOJ 3494 BCD Code (数位DP,AC自动机)
  • 原文地址:https://www.cnblogs.com/luofeiju/p/12016761.html
Copyright © 2011-2022 走看看