Eigen::Isometry3d入门

本文介绍了如何在3D中通过Eigen库实现欧式变换,包括旋转变换和平移操作,以及两种不同的矩阵设置方法:直接赋值和右乘/前传操作。重点讲解了左乘与右乘的区别及其在初始化和变换顺序中的应用。

本文为入门笔记,详细请看大佬文章,写的非常具体。
关于矩阵的左乘右乘详情请看知乎大佬-Lpip Sam,和知乎大佬-小兔纸的大魔王很详细。

欧式变换也称为等距变换(Isometry Transform),可以看作是维持任意两点距离不变的仿射变换。
( R o t a t e t r a n s l a t i o n 0 T 1 ) \left( \begin{matrix} Rotate &translation \\ 0^T & 1 \\ \end{matrix} \right) (Rotate0Ttranslation1)

0.初始化

共两种方法,第一种使用较为频繁。

	//设置旋转向量V
	Eigen::AngleAxisd V(3.1415926 / 4, Eigen::Vector3d(1, 0, 1).normalized());
	//设置平移向量
	Eigen::Vector3d translation(1, 3, 4);
	
	//将T初始化为单位阵,再做其他操作。
	//虽然称为3D,实质上为4*4矩阵。
	Eigen::Isometry3d T= Isometry3d::Identity();

1.两种求欧式变换矩阵

	//设置欧式变换矩阵——方式1
	//此种方式和下一种方式输出相同。
	//a.translate(b)等价于aXb,描述的是在世界坐标系下的平移(虽然b在设置时为只含有3个元素列向量,猜想内部可能会有操作时其为下面这种形式)。
	//形式为 0	0	0	1
	//      0	0	0	3
	//      0	0	0	4
	//      0	0	0	0
	//此操作相当于将translation中的数值放入欧式变换矩阵translation位置(注意!!!此种效果的前提T为单位矩阵)
	//结果为 1	0	0	1
	//      0	1	0	3
	//      0	0	1	4
	//      0	0	0	1
	T.translate(translation);
	//a.rotate(b)等价于aXb,描述的是在世界坐标系下的旋转。
	T.rotate(V);
	//结果为 0.853553	 -0.5	0.146447		1
	//           0.5	0.707	    -0.5		3
	//      0.146447	  0.5	0.853553		4
	//      	   0	    0	       0		1
	//matrix()返回变换对应的矩阵,T输出时用此函数。
	std::cout << T.matrix() << std::endl;

/*----------------------------------------------------------------------

------------------------------------------------------------------------*/

	//设置欧式变换矩阵——方式2
	//凡是前面带pre的函数,相当于右乘。
	//a.rotate(b)等价于aXb,描述的是在世界坐标系下的旋转。
	//结果为 0.853553	 -0.5	0.146447		0
	//           0.5	0.707	    -0.5		0
	//      0.146447	  0.5	0.853553		0
	//      	   0	    0	       0		1
	T.rotate(V);
	//我们的目的是为了形成文章开头欧式变换的矩阵,
	//变换顺序必须是先平移,再旋转,也就是单位矩阵E X 平移矩阵T X 旋转矩阵R。
	//按照R右乘T也就是T X R,实际和方式1相同T左乘R(T X R)这样理解就可以,
	//但是根据查看源码,只有在mode==Projective时为右乘,否则为T+translation,
	//然而translation为含有3个元素的列向量,这也印证了之前的猜想,有内部机制使translation转换成下面的形式
	//形式为 0	0	0	1
	//      0	0	0	3
	//      0	0	0	4
	//      0	0	0	0
	T.pretranslate(translation);
	//结果为 0.853553	 -0.5	0.146447		1
	//           0.5	0.707	    -0.5		3
	//      0.146447	  0.5	0.853553		4
	//      	   0	    0	       0		1
	//matrix()返回变换对应的矩阵,T输出时用此函数。
	std::cout << T.matrix() << std::endl;
<think>我们正在讨论Eigen库中的Isometry3d类。Isometry3d用于表示三维空间中的刚体变换(旋转和平移),即等距变换(保持距离不变)。它实际上是一个4x4的矩阵,但只包含旋转和平移,没有缩放和剪切。 主要特点: 1. 它是一个仿射变换,但只包含等距部分(旋转和平移)。 2. 在内存中,它存储为一个4x4矩阵,但只使用其中3x4的部分(前3行是旋转矩阵,最后一列的前3个是平移向量,最后一行是[0,0,0,1])。 3. 使用Isometry3d可以高效地进行点变换和变换组合(通过矩阵乘法)。 常用操作: - 初始化:可以设置为单位变换,或者通过旋转矩阵和平移向量初始化。 - 变换点:使用`*`运算符(重载了,可以作用于点或向量)。 - 组合变换:使用`*`运算符组合两个变换(注意顺序:从右向左)。 注意:在Eigen中,变换点(Vector3d)时,点会被视为齐次坐标下的点(即添加一个1),而向量(Vector3d)会被视为齐次坐标下的向量(即添加一个0),因此平移对向量不起作用。 下面我们通过示例代码来说明。 示例1:创建Isometry3d变换 示例2:使用Isometry3d变换点 示例3:组合变换 注意:在Eigen中,Isometry3d通常使用列优先存储,并且乘法顺序是从右向左(即T1 * T2表示先应用T2,再应用T1)。 我们将编写几个简单的示例代码。</think>### Eigen库中Isometry3d类的使用指南 Isometry3dEigen库中用于表示**三维刚体变换(旋转+平移)**的类,本质是一个4×4的齐次变换矩阵,其形式为: $$ \begin{bmatrix} R & t \\ 0 & 1 \end{bmatrix} $$ 其中$R$是3×3旋转矩阵,$t$是3×1平移向量[^1]。 #### 基础用法示例 ```cpp #include <Eigen/Geometry> // 创建单位变换 Eigen::Isometry3d T = Eigen::Isometry3d::Identity(); // 设置平移分量 (x, y, z) T.translation() = Eigen::Vector3d(1.0, 2.0, 3.0); // 设置旋转分量 (绕Z轴旋转45度) T.rotate(Eigen::AngleAxisd(M_PI/4, Eigen::Vector3d::UnitZ())); // 变换点:p' = R*p + t Eigen::Vector3d p(1, 0, 0); Eigen::Vector3d p_transformed = T * p; // 结果 ≈ (1.707, 0.707, 3.0) // 变换组合:T_final = T1 * T2 Eigen::Isometry3d T2 = Eigen::Isometry3d::Identity(); T2.translate(Eigen::Vector3d(0, 0, 1)); Eigen::Isometry3d T_final = T * T2; // 先T2后T ``` #### 关键操作 1. **创建变换**: ```cpp // 从旋转矩阵和平移向量创建 Eigen::Matrix3d R = Eigen::AngleAxisd(angle, axis).toRotationMatrix(); Eigen::Vector3d t(1, 2, 3); Eigen::Isometry3d T(R); T.translation() = t; ``` 2. **逆变换**: ```cpp Eigen::Isometry3d Tinv = T.inverse(); // 数学求逆 ``` 3. **与其他类型互转**: ```cpp // 转换为4x4矩阵 Eigen::Matrix4d matrix = T.matrix(); // 从四元数创建 Eigen::Quaterniond q = Eigen::Quaterniond::Identity(); T.rotate(q); ``` #### 实际应用场景 1. **机器人运动学**: ```cpp // 机械臂关节变换 Eigen::Isometry3d joint1_transform; joint1_transform.translate(Eigen::Vector3d(0, 0, 0.5)); joint1_transform.rotate(Eigen::AngleAxisd(q_angle, Eigen::Vector3d::UnitZ())); ``` 2. **点云配准**: ```cpp // 应用变换到点云 for(auto& point : pointcloud) { point = T * point; // 刚体变换 } ``` 3. **相机位姿表示**: ```cpp // 相机到世界坐标系的变换 Eigen::Isometry3d camera_pose; camera_pose.translation() = camera_position; camera_pose.rotate(camera_orientation); ``` #### 注意事项 1. 乘法顺序:`T1 * T2`表示**先应用T2再应用T1** 2. 变换点时会自动添加齐次坐标的1(向量添加0) 3. 相比`Affine3d`,`Isometry3d`强制约束变换类型,避免误用 > 完整文档见:[Eigen::Isometry3d Class Reference](https://eigen.tuxfamily.org/dox/classEigen_1_1Isometry3d.html)[^1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值