PCL入門根據向量做點雲旋轉

如果已知旋轉前某個向量n1(x1,y1,z1)和旋轉後的向量n2(x2,y2,z2)實際上已知了三個點,(0,0,0) (x1,y1,z1) (x2,y2,z2) 那麼可以求出他們構成的平面的法向量,也就是同時垂直於n1和n2的這個向量,並且經過n1和n2的交點,也就是原點。這個向量就是他們的旋轉軸。

那麼已知三點怎麼求平面的法向量呢,我們可以代入公式

其中x3,y3,z3我們設爲原點,那麼就是0,0,0.

void MatrixRotation::calculate_axis()
{
  float x1,x2,y1,y2,z1,z2;
  x1=normal_start_.normal_x,x2=normal_end_.normal_x;
  y1=normal_start_.normal_y,y2=normal_end_.normal_y;
  z1=normal_start_.normal_z,z2=normal_end_.normal_z;
  float x3,y3,z3; 
  x3=y3=z3=0;
  axis_.normal_x=(y2-y1)*(z3-z1)-(y3-y1)*(z2-z1);
  axis_.normal_y=(z2-z1)*(x3-x1)-(z3-z1)*(x2-x1);
  axis_.normal_z=(x2-x1)*(y3-y1)-(x3-x1)*(y2-y1);
  //normalize
  float square_sum=axis_.normal_x*axis_.normal_x+
                    axis_.normal_y*axis_.normal_y+
                    axis_.normal_z*axis_.normal_z;
  square_sum=sqrt(square_sum);
  axis_.normal_x/=square_sum;
  axis_.normal_y/=square_sum;
  axis_.normal_z/=square_sum;
}


求出了法向量之後帶入羅德里格斯旋轉公式,求出旋轉矩陣,

{\displaystyle R={\begin{bmatrix}\cos \theta +u_{x}^{2}\left(1-\cos \theta \right)&u_{x}u_{y}\left(1-\cos \theta \right)-u_{z}\sin \theta &u_{x}u_{z}\left(1-\cos \theta \right)+u_{y}\sin \theta \\u_{y}u_{x}\left(1-\cos \theta \right)+u_{z}\sin \theta &\cos \theta +u_{y}^{2}\left(1-\cos \theta \right)&u_{y}u_{z}\left(1-\cos \theta \right)-u_{x}\sin \theta \\u_{z}u_{x}\left(1-\cos \theta \right)-u_{y}\sin \theta &u_{z}u_{y}\left(1-\cos \theta \right)+u_{x}\sin \theta &\cos \theta +u_{z}^{2}\left(1-\cos \theta \right)\end{bmatrix}}.}

void MatrixRotation::matrix_tansform(pcl::PointCloud<PointT>::Ptr cloud)
{
  Eigen::Matrix4f transform = Eigen::Matrix4f::Identity();
  float x,y,z;
  x=axis_.normal_x;y=axis_.normal_y;z=axis_.normal_z;
  transform (0,0)=cos(theta_)+(1-cos(theta_))*x*x;
  transform (0,1)=(1-cos(theta_))*x*y-sin(theta_)*z;
  transform (0,2)=(1-cos(theta_))*x*z+sin(theta_)*y;
  transform (1,0)=(1-cos(theta_))*x*y+sin(theta_)*z;
  transform (1,1)=cos(theta_)+(1-cos(theta_))*y*y;
  transform (1,2)=(1-cos(theta_))*y*z-sin(theta_)*x;
  transform (2,0)=(1-cos(theta_))*x*z-sin(theta_)*y;
  transform (2,1)=(1-cos(theta_))*y*z+sin(theta_)*x;
  transform (2,2)=cos(theta_)+(1-cos(theta_))*z*z;
  pcl::transformPointCloud (*cloud, *cloud, transform);
}

其中,theta是需要旋轉的角度,這個公式很簡單,搜索求向量夾角就可以了,我這裏不再贅述,直接使用了pcl的方法求的,最後使用pcl的旋轉,實際上就是現有矩陣乘以旋轉矩陣。這樣就能得到旋轉後的圖像了。

完整代碼我會上傳到github上,敬請期待。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章