|

楼主 |
发表于 2025-4-11 15:40:11
|
显示全部楼层
可视化模拟截面圆锥面(增强函数)
在 visualizeCone(...) 函数中增加 截面圆生成逻辑:
void visualizeCone(const pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud,
const Eigen::Vector3d& vertex,
const Eigen::Vector3d& direction,
double slope = 0.5,
double height = 10.0) {
auto viewer = boost::make_shared<pcl::visualization::PCLVisualizer>("Cone Fitting Viewer");
viewer->setBackgroundColor(0, 0, 0);
// 1. 点云
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_color(cloud, 255, 255, 255);
viewer->addPointCloud(cloud, cloud_color, "cloud");
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "cloud");
// 2. 顶点(红色)
pcl::PointXYZ vtx(vertex[0], vertex[1], vertex[2]);
viewer->addSphere(vtx, 0.1, 1.0, 0.0, 0.0, "vertex_sphere");
viewer->addText3D("Vertex", vtx, 0.2, 1.0, 0.0, 0.0);
// 3. 轴线箭头(绿色)
Eigen::Vector3d axis = direction.normalized();
Eigen::Vector3d end = vertex + axis * height;
viewer->addArrow(
pcl::PointXYZ(end[0], end[1], end[2]),
pcl::PointXYZ(vertex[0], vertex[1], vertex[2]),
0.0, 1.0, 0.0, false, "axis_arrow");
// 4. 拟合锥面轮廓(用截面圆模拟)
// 构造锥面横截面圆的局部正交基
Eigen::Vector3d ortho1 = axis.unitOrthogonal();
Eigen::Vector3d ortho2 = axis.cross(ortho1);
int num_circles = 30;
int num_circle_points = 50;
for (int i = 1; i <= num_circles; ++i) {
double z = height * i / static_cast<double>(num_circles);
double radius = slope * z;
Eigen::Vector3d center = vertex + axis * z;
pcl::PointCloud<pcl::PointXYZ>::Ptr circle(new pcl::PointCloud<pcl::PointXYZ>);
for (int j = 0; j < num_circle_points; ++j) {
double angle = 2 * M_PI * j / static_cast<double>(num_circle_points);
Eigen::Vector3d pt = center + radius * (std::cos(angle) * ortho1 + std::sin(angle) * ortho2);
circle->points.emplace_back(pt[0], pt[1], pt[2]);
}
std::string circle_id = "circle_" + std::to_string(i);
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> circle_color(circle, 100, 100, 255);
viewer->addPointCloud<pcl::PointXYZ>(circle, circle_color, circle_id);
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, circle_id);
}
// 启动视图
viewer->addCoordinateSystem(1.0);
viewer->initCameraParameters();
while (!viewer->wasStopped()) {
viewer->spinOnce(100);
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
✅ 如何调用?
你需要在主程序中传入 slope 参数(也就是拟合结果的 k = tan(θ)):
Eigen::Vector3d v(vertex[0], vertex[1], vertex[2]);
Eigen::Vector3d d(direction[0], direction[1], direction[2]);
visualizeCone(cloud, v, d, slope[0], 10.0);
🎯 最终视觉效果:
🎯 点云(白色)
🔺 顶点(红球)
➤ 方向轴线(绿色箭头)
🌀 拟合圆锥轮廓(多个蓝色环形截面,真实模拟锥形外轮廓) |
|