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     };

        

  • 相关阅读:
    选择前端编辑器
    由看书引发的一些思考
    不是真饿的时候吃些饱腹感强的东西
    微信浏览网页骗局
    辣椒你还吃着吗
    观影感悟
    python中函数加括号与不加括号
    视频流媒体服务器直播点播平台可以接入其他平台播放视频吗?
    视频直播点播流媒体服务器报accept4 () failed (24: Too many open files)错误解决方法
    视频直播点播流媒体服务器报worker_connections are not enough错误解决方法
  • 原文地址:https://www.cnblogs.com/luofeiju/p/12016761.html
Copyright © 2011-2022 走看看