
目录一、原理介绍1. 问题定义2. 计算方法二、代码实现三、结果展示一、原理介绍1. 问题定义给定包含n nn个点的三维点云集合P { p 0 , p 1 , . . . , p n − 1 } P \{p_0, p_1, ..., p_{n-1}\}P{p0,p1,...,pn−1}点云的最大距离定义为所有点对之间欧氏距离的全局最大值d m a x max { ∥ p i − p j ∥ 2 ∣ 0 ≤ i , j n } d_{max} \max\{\|p_i - p_j\|_2 \mid 0 \le i, j n\}dmaxmax{∥pi−pj∥2∣0≤i,jn}对应的两个点p i p_ipi、p j p_jpj即为距离最远的点对。2. 计算方法getMaxSegment采用暴力枚举法求解核心思想是遍历所有不重复的点对逐一计算空间距离并记录最大值与对应端点。为了提升计算效率算法做了两处关键的工程优化利用距离对称性减少循环次数点对( ( i , j ) ) ((i,j))((i,j))与( ( j , i ) ) ((j,i))((j,i))距离相同因此内层循环从i ii开始遍历仅计算j ≥ i j \geq ij≥i的点对计算量直接减半。平方距离比较最后统一开方比较距离大小时平方距离的大小关系与真实欧氏距离完全一致。算法全程先比较平方距离仅在最终返回结果时做一次开方运算大幅减少sqrt函数的调用开销。算法整体时间复杂度为O ( n 2 ) O(n^2)O(n2)空间复杂度为( O ( 1 ) ) (O(1))(O(1))仅使用有限变量记录最大值与索引。二、代码实现#includeiostream#includepcl/io/pcd_io.h#includepcl/point_types.h#includepcl/common/distances.h#includeboost/thread/thread.hpp#includepcl/visualization/pcl_visualizer.husingnamespacestd;intmain(intargc,char**argv){// 加载原始点云pcl::PointCloudpcl::PointXYZ::Ptrcloud(newpcl::PointCloudpcl::PointXYZ);if(pcl::io::loadPCDFilepcl::PointXYZ(temp//vault_raw_34_convex.pcd,*cloud)-1){PCL_ERROR(加载点云失败请检查文件路径是否正确\n);return-1;}pcl::PointXYZ pmin,pmax;// 计算点云中距离最大的两个端点返回最大距离doublemax_distancepcl::getMaxSegment(*cloud,pmin,pmax);cout点云集合中的最大距离为max_distance 米endl;// -------------------------- 保存最远两点为PCD文件 --------------------------// 创建只包含两个最远点的新点云pcl::PointCloudpcl::PointXYZ::Ptrextreme_points_cloud(newpcl::PointCloudpcl::PointXYZ);extreme_points_cloud-push_back(pmin);// 第一个端点extreme_points_cloud-push_back(pmax);// 第二个端点// 显式设置点云属性规范写法push_back 也会自动维护extreme_points_cloud-width2;extreme_points_cloud-height1;extreme_points_cloud-is_densetrue;// 保存为PCD文件string save_pathtemp//max_distance_points.pcd;intsave_resultpcl::io::savePCDFileBinary(save_path,*extreme_points_cloud);if(save_result0){cout已将距离最大的两个点成功保存到save_pathendl;}else{cerr保存PCD文件失败错误码save_resultendl;return-1;}// -------------------------- 结果可视化 --------------------------boost::shared_ptrpcl::visualization::PCLVisualizerviewer(newpcl::visualization::PCLVisualizer(Viewer));viewer-setBackgroundColor(0,0,0);viewer-setWindowName(getMaxSegment);pcl::visualization::PointCloudColorHandlerCustompcl::PointXYZsingle_color(cloud,0,0,255);// 蓝色viewer-addPointCloudpcl::PointXYZ(cloud,single_color,sample cloud);// 绘制最远两点之间的箭头和标注viewer-addArrowpcl::PointXYZ(pmin,pmax,0,255,0,true,arrow,0);viewer-addText3D(Point1,pmin,0.05,255,0,0);viewer-addText3D(Point2,pmax,0.05,255,0,0);while(!viewer-wasStopped()){viewer-spinOnce(100);boost::this_thread::sleep(boost::posix_time::microseconds(100000));}return0;}三、结果展示