PCL 生成圆柱面点云
目录
- 一、算法原理
- 二、代码实现
- 三、结果展示
本文由CSDN点云侠原创。博客长期更新,本文最近更新时间为:2025年6月15日。
一、算法原理
圆柱面参数方程(局部坐标系):
x = r cos θ , y = r sin θ , z = h x = r \cos\theta,\quad y = r \sin\theta,\quad z = h x=rcosθ,y=rsinθ,z=h
其中:
- r r r 为圆柱半径
- θ ∈ [ 0 , 2 π ) \theta \in [0, 2\pi) θ∈[0,2π) 为旋转角度
- h ∈ [ 0 , H ] h \in [0, H] h∈[0,H] 为高度
二、代码实现
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/common/transforms.h>
#include <pcl/ModelCoefficients.h>void CreatCylinder(pcl::ModelCoefficients::Ptr& coefCylinder,pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud, int Num = 1200, float height = 1.0)
{if (coefCylinder->values.size() != 7 || coefCylinder->values[6] <= 0){std::cerr << "参数输入错误!!!" << std::endl;return;}//先构建轴线为Z轴的圆柱点云float inter = 2.0 * M_PI / Num;Eigen::VectorXf vectorx(Num), vectory(Num);vectorx.setLinSpaced(Num, 0, Num - 1);vectory = vectorx;Eigen::RowVector3f axis(coefCylinder->values[3], coefCylinder->values[4], coefCylinder->values[5]);float length = axis.norm();cout << length << endl;float x0, y0, z0, r0;x0 = coefCylinder->values[0];y0 = coefCylinder->values[1];z0 = coefCylinder->values[2];r0 = coefCylinder->values[6];pcl::PointCloud<pcl::PointXYZ>::Ptr cylinder(new pcl::PointCloud<pcl::PointXYZ>);for (float z = 0.0; z <= height; z += 0.05){for (size_t i = 0; i < Num; ++i) {pcl::PointXYZ point;point.x = r0 * cosf(vectorx[i] * inter);point.y = r0 * sinf(vectory[i] * inter);point.z = z;cylinder->points.push_back(point);}}//点云旋转 Z轴转到axisEigen::RowVector3f Z(0.0, 0.0, 0.1);//Eigen::Vector3f axis(coefCylinder->values[3], coefCylinder->values[4], coefCylinder->values[5]);Eigen::Matrix4f Rotate = Eigen::Matrix4f::Identity();Rotate.block<3, 3>(0, 0) = Eigen::Quaternionf::FromTwoVectors(Z, axis).toRotationMatrix();Rotate.block<3, 1>(0, 3) = Eigen::Vector3f(coefCylinder->values[0], coefCylinder->values[1], coefCylinder->values[2]);//旋转pcl::transformPointCloud(*cylinder, *cloud, Rotate);}int main()
{pcl::ModelCoefficients::Ptr cylinder(new pcl::ModelCoefficients);pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);cylinder->values.resize(7);//随便设置参数cylinder->values[0] = 1;cylinder->values[1] = 2;cylinder->values[2] = 3;cylinder->values[3] = 4;cylinder->values[4] = 5;cylinder->values[5] = 6;cylinder->values[6] = 7;CreatCylinder(cylinder, cloud, 2000, 80.0);cout << cloud->size() << endl;//--------------------------------------可视化--------------------------pcl::visualization::PCLVisualizer viewer;//创建的点云和直接addCylinder函数创建的圆柱面面片进行比对viewer.addPointCloud<pcl::PointXYZ>(cloud, "cloud1");//viewer.addCylinder(*cylinder, "cylinder");viewer.addCoordinateSystem();while (!viewer.wasStopped()){viewer.spinOnce(100);}return 0;
}