news 2026/10/9 15:15:03

第 37 章 · 综合项目二:3D 点云与刚体变换

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
第 37 章 · 综合项目二:3D 点云与刚体变换

第二个实战项目:处理 3D 点云,做旋转和平移。这是计算机图形学、机器人、SLAM 的基础。本项目综合运用:vector、几何模块、刚体变换。

37.1 什么是点云

点云(point cloud)是一堆三维点的集合。激光雷达扫描、3D 扫描仪输出的就是点云。机器人、自动驾驶靠处理点云来"看"世界。

在 Eigen 里,一个点就是一个Vector3d,点云就是std::vector<Vector3d>。

37.2 项目目标

完成两个任务:

  1. 构造点云:生成一个立方体的 8 个顶点
  2. 变换点云:绕 Z 轴旋转 90°,再平移,观察点云的变化
  3. 统计点云:计算质心(平均点)

37.3 完整代码

#include<Eigen/Dense>#include<Eigen/Geometry>#include<iostream>#include<vector>intmain(){constdoublePI=3.14159265358979;// ---- 任务 1:构造立方体的 8 个顶点 ----std::vector<Eigen::Vector3d>cloud;for(intx=0;x<=1;x++)for(inty=0;y<=1;y++)for(intz=0;z<=1;z++)cloud.push_back(Eigen::Vector3d(x,y,z));std::cout<<"点云有 "<<cloud.size()<<" 个点"<<std::endl;// ---- 任务 2:变换(绕 Z 转 90° 再平移)----Eigen::Isometry3d T=Eigen::Isometry3d::Identity();T.rotate(Eigen::AngleAxisd(PI/2,Eigen::Vector3d::UnitZ()));T.pretranslate(Eigen::Vector3d(10,0,0));std::cout<<"变换前 -> 变换后:"<<std::endl;for(constauto&p:cloud){Eigen::Vector3d p2=T*p;std::cout<<" "<<p.transpose()<<" -> "<<p2.transpose()<<std::endl;}// ---- 任务 3:计算质心 ----Eigen::Vector3d centroid=Eigen::Vector3d::Zero();for(constauto&p:cloud){centroid+=p;}centroid/=cloud.size();std::cout<<"质心 = "<<centroid.transpose()<<std::endl;// (0.5, 0.5, 0.5)return0;}

编译运行:存成ch37.cpp,按附录 C.3 的命令:

g++-std=c++17-O2-I"你的Eigen目录"ch37.cpp-och37.exe ./ch37.exe

实际输出:

点云有 8 个点 变换前 -> 变换后: 0 0 0 -> 10 0 0 0 0 1 -> 10 0 1 0 1 0 -> 9 1.61554e-15 0 0 1 1 -> 9 1.61554e-15 1 1 0 0 -> 10 1 0 1 0 1 -> 10 1 1 1 1 0 -> 9 1 0 1 1 1 -> 9 1 1 质心 = 0.5 0.5 0.5

1.61554e-15是 0 的浮点残渣(第 21 章末尾讲过),不用管它。

37.4 运行结果解读

  • 立方体 8 个顶点是 (0/1, 0/1, 0/1) 的所有组合
  • 绕 Z 转 90°:X 轴方向转到 Y 轴((1,0,0) → (0,1,0))
  • 平移 (10,0,0):所有点 X 坐标 +10
  • 质心:8 个顶点的平均 = (0.5, 0.5, 0.5)

37.5 拓展练习

拓展 1:计算点云的包围盒

包围盒(bounding box)= 各方向上的最小值和最大值,用来快速判断点云占了多大空间。

接着第 37.3 节的程序做:把下面几行粘贴到ch37.cpp里打印质心那一行之后、return 0;之前(此处的cloud就是前面构造好的 8 个顶点):

// 包围盒 = 所有坐标的最小值和最大值Eigen::Vector3d minPt=cloud[0],maxPt=cloud[0];for(constauto&p:cloud){minPt=minPt.cwiseMin(p);// 逐元素取最小maxPt=maxPt.cwiseMax(p);// 逐元素取最大}std::cout<<"包围盒:"<<minPt.transpose()<<" 到 "<<maxPt.transpose()<<std::endl;

重新编译运行,最后一行新增:

包围盒:0 0 0 到 1 1 1

立方体的 8 个顶点正好落在 0 和 1 上,所以包围盒是 (0,0,0) 到 (1,1,1)。注意这段用的是原始点云(未变换),如果换成T * p的结果,包围盒会跟着平移走。

拓展 2:两点云配准(ICP 的思想)

机器人里常要做点云配准:找变换 T 使两个点云对齐。经典算法 ICP 的核心就是:

  1. 对每个点找最近对应点
  2. 用最小二乘求最优刚体变换
  3. 迭代直到收敛

这综合了本项目的刚体变换和第 36 章的最小二乘,是值得深入的方向。

37.6 学完这个项目你掌握了什么

  • 用vector<Eigen::Vector3d>表示点云
  • 用Isometry3d做刚体变换
  • 用cwiseMin/cwiseMax做逐元素运算
  • 用循环 + 归约做统计(质心)

这些正是机器人、SLAM、3D 图形领域天天在用的操作。

37.7 小结

  • 点云 =vector<Vector3d>。
  • 刚体变换 = 旋转 + 平移,用Isometry3d。
  • 质心、包围盒等统计都可用 Eigen 简洁实现。
  • 点云配准(ICP)是更深入的实战方向。

练习题

  1. 生成一个 2×2×2 的网格点云(步长 0.5),打印点数。
  2. 对点云做一次刚体变换,观察变化。
  3. 计算点云的质心和包围盒。
  4. 用cwiseMin/cwiseMax实现包围盒计算。
  5. 思考:怎么判断两个点云是否"对齐"?
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/9 15:14:22

HarmonyOS 7 AccessToken:权限触发链校验与审核证据归档【鸿蒙心迹】

有一次做提交前自查&#xff0c;权限声明看起来没有问题&#xff1a;module.json5 里写了相机权限&#xff0c;页面也有隐私说明&#xff0c;测试机器上拍照流程通了。可一旦换成从未授权的新用户&#xff0c;问题就冒出来&#xff1a;他打开首页时为什么已经出现权限对话框&am…

作者头像 李华
网站建设 2026/10/9 15:05:23

北理工数据库上机实验包:五阶能力闭环实战指南

简介&#xff1a;本资源是北京理工大学计算机学院“数据库原理与设计”课程配套上机实验材料&#xff0c;面向高校计算机专业本科生及数据库初学者&#xff0c;聚焦关系数据库理论落地与SQL工程实践能力培养。压缩包共12个文件&#xff0c;含4个核心SQL脚本&#xff08;覆盖建库…

作者头像 李华
网站建设 2026/10/9 15:04:55

蓝屏分析工具Bluescreenview:从Minidump转储到驱动定位实战

简介&#xff1a;Bluescreenview蓝屏分析工具面向Windows系统维护人员、IT运维及普通用户&#xff0c;用于解析系统蓝屏时生成的DMP文件&#xff0c;快速定位错误代码、停止消息与驱动程序等关键信息&#xff0c;降低故障排查门槛。资源包共3个文件&#xff0c;以html页面、ins…

作者头像 李华
网站建设 2026/10/9 15:04:19

金融客服大模型落地工程指南:从解决方案PPT到可执行路径

简介&#xff1a;这份PPT面向金融科技从业者、银行客服系统架构师及AI解决方案设计人员&#xff0c;聚焦AI大模型在金融客服场景的落地难题&#xff0c;如人工成本高、多语言支持不足、服务效率低与知识更新滞后等。资源包共1个PPT文件&#xff0c;约1.11MB&#xff0c;以图文并…

作者头像 李华
网站建设 2026/10/9 15:01:44

ThinkPHP6网盘系统源码实战:分片上传与文件管理后端搭建

简介&#xff1a;这份源码资源面向PHP Web开发初学者与进阶学习者&#xff0c;提供一套基于ThinkPHP6框架构建的网盘系统完整实现&#xff0c;可用于理解文件上传、下载、管理等核心业务逻辑&#xff0c;也适合作为教育平台的教学案例或课程设计参考。压缩包共633个文件&#x…

作者头像 李华
网站建设 2026/10/9 15:01:18

微信朋友圈功能测试全攻略:从用例设计到自动化与安全验证

“如何测微信的朋友圈&#xff1f;”是我在面试测试工程师时最喜欢丢出去的一道题。它不像“如何测试一个登录框”那样已经被讲烂了&#xff0c;也不像“如何测试电梯”那样需要纯逻辑发散&#xff0c;它卡在一个很微妙的位置&#xff1a;几乎每个面试者都刷过朋友圈、发过朋友…

作者头像 李华