PCL 生成三棱锥点云

目录

一、算法原理

  针对正三棱锥(四面体)表面均匀点云的生成,采用基于重心坐标的随机采样方法。对于任意三角形,其顶点为 A , B , C A,B,C A,B,C,随机点 P P P由如下凸组合定义:

P = ( 1 − ξ 1 − ξ 2 )   A + ξ 1   B + ξ 2   C P=(1 - \xi_1 - \xi_2)\,\mathbf{A} + \xi_1\,\mathbf{B} + \xi_2\,\mathbf{C} P=(1−ξ1−ξ2)A+ξ1B+ξ2C

其中 ξ 1 , ξ 2 \xi_1, \xi_2 ξ1,ξ2 服从标准二维单纯形 { ξ 1 ≥ 0 ,    ξ 2 ≥ 0 ,    ξ 1 + ξ 2 ≤ 1 } \{\xi_1 \ge 0,\; \xi_2 \ge 0,\; \xi_1+\xi_2 \le 1\} {ξ1≥0,ξ2≥0,ξ1+ξ2≤1} 上的均匀分布。实际计算时,首先生成两个独立的均匀随机变量 U , V ∼ U 0 , 1 U, V \sim \mathcal{U}0,1 U,V∼U0,1,仅当 U + V ≤ 1 U+V \le 1 U+V≤1 时接受该数对;否则拒绝并重新采样。这一拒绝机制确保了点集在三角形区域内呈均匀分布。

  将该过程分别应用于三棱锥的四个三角面------底面与三个侧面------即可得到该多面体表面的稠密点云。各面独立采样,互不影响,整体点云在表面积上具有无偏均匀性。

二、代码实现

cpp 复制代码
#include <vector>
#include <random>
#include <iostream>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>


// 生成三棱锥点云
pcl::PointCloud<pcl::PointXYZ>::Ptr generatePyramidCloud() 
{
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);

    // 定义三棱锥的四个顶点
    std::vector<pcl::PointXYZ> vertices = 
    {
        pcl::PointXYZ(0.0f, 0.0f, 0.0f),    // 底面三角形顶点1
        pcl::PointXYZ(1.0f, 0.0f, 0.0f),    // 底面三角形顶点2
        pcl::PointXYZ(0.5f, 0.866f, 0.0f),  // 底面三角形顶点3
        pcl::PointXYZ(0.5f, 0.288f, 1.0f)   // 顶点
    };

    // 在三个面上生成随机点
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_real_distribution<> dis(0.0, 1.0);

    // 生成底面三角形内部点
    for (int i = 0; i < 20000; ++i) 
    {
        float r1 = dis(gen);
        float r2 = dis(gen);

        if (r1 + r2 <= 1.0f)
        {
            pcl::PointXYZ p;
            p.x = (1 - r1 - r2) * vertices[0].x + r1 * vertices[1].x + r2 * vertices[2].x;
            p.y = (1 - r1 - r2) * vertices[0].y + r1 * vertices[1].y + r2 * vertices[2].y;
            p.z = 0.0f;
            cloud->points.push_back(p);
        }
        else 
        {
            i--; // 重新生成
        }
    }

    // 生成三个侧面的点
    for (int face = 0; face < 3; ++face) 
    {
        int v1 = face;
        int v2 = (face + 1) % 3;
        int v3 = 3; // 顶点

        for (int i = 0; i < 20000; ++i) 
        {
            float r1 = dis(gen);
            float r2 = dis(gen);

            if (r1 + r2 <= 1.0f) 
            {
                pcl::PointXYZ p;
                p.x = (1 - r1 - r2) * vertices[v1].x + r1 * vertices[v2].x + r2 * vertices[v3].x;
                p.y = (1 - r1 - r2) * vertices[v1].y + r1 * vertices[v2].y + r2 * vertices[v3].y;
                p.z = (1 - r1 - r2) * vertices[v1].z + r1 * vertices[v2].z + r2 * vertices[v3].z;
                cloud->points.push_back(p);
            }
            else
            {
                i--;
            }
        }
    }


    cloud->width = cloud->points.size();
    cloud->height = 1;
    cloud->is_dense = true;

    return cloud;
}


int main() 
{
    // 生成模拟三棱锥点云
    std::cout << "生成三棱锥点云..." << std::endl;
    pcl::PointCloud<pcl::PointXYZ>::Ptr pyramid_cloud = generatePyramidCloud();
    std::cout << "点云数量: " << pyramid_cloud->size() << " 个点" << std::endl;

    // 保存模拟点云
    pcl::io::savePCDFileBinary("pyramid_cloud.pcd", *pyramid_cloud);
    std::cout << "已保存模拟点云到: pyramid_cloud.pcd" << std::endl;

    
    // 可视化
    pcl::visualization::PCLVisualizer viewer("Pyramid");
    viewer.setBackgroundColor(0.1, 0.1, 0.1);

    // 添加原始点云
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_color(pyramid_cloud, 100, 100, 100);
    viewer.addPointCloud(pyramid_cloud, cloud_color, "pyramid_cloud");
    viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "pyramid_cloud");


    std::cout << "\n按q退出可视化窗口..." << std::endl;
    viewer.spin();

    return 0;
}

三、结果展示

相关推荐
dyxal14 分钟前
eˣ 的泰勒展开式:从“化繁为简”到“万物统一”的微积分之美
算法
BetterFlow_CFD21 分钟前
COMSOL声学仿真基础知识(二)
开发语言·算法·matlab
ShineWinsu32 分钟前
对于Linux:http的解析
linux·网络·c++·网络协议·http·请求·响应
choumin10 小时前
创建型模式——工厂方法模式
c++·设计模式·工厂方法模式·创建型模式
云小逸10 小时前
【SVN 详细使用指南:从入门到团队协作】
c++·svn
徐小夕12 小时前
花了一周,3亿tokens,我开源了一款 Word 文档智能审查平台,文稿自动质检+可视化分析,告别低效人工审核
前端·算法·github
可编程芯片开发13 小时前
UPFC统一潮流控制器的simulink建模与仿真
算法
小小仙子13 小时前
矢量网络分析仪如何测试S参数的?
人工智能·算法·机器学习
中微极客15 小时前
降维算法75倍加速:从PCA到稀疏字典学习的工程实践
人工智能·学习·算法