旋转、平移、缩放……这些"变换"都能用矩阵表示。本章讲透"矩阵就是变换"这个核心思想,这是理解 Eigen 几何模块(第 32 章)的钥匙。
21.1 矩阵 = 变换
一个惊人的事实:矩阵乘法 = 对向量做变换。
一个向量 v 被矩阵 A 乘一下(A·v),就变成了另一个向量——相当于对 v 做了一次"变换"(移动、旋转、缩放、扭曲……)。
v ──(A 作用)──→ A·v所以"学矩阵"其实是"学变换"。下面看几种基本变换。
21.2 缩放
对角矩阵表示缩放:把坐标各分量分别放大。
[ 2 0 ] [ x ] [ 2x ] [ 0 3 ] · [ y ] = [ 3y ]这个矩阵把 x 方向放大 2 倍,y 方向放大 3 倍。
y | · (2x, 3y) | / |/ · (x, y) └────────── x21.3 旋转
二维平面绕原点旋转角度 θ,用旋转矩阵:
R(θ) = [ cosθ -sinθ ] [ sinθ cosθ ]绕 Z 轴旋转 θ(三维里最常用):
Rz(θ) = [ cosθ -sinθ 0 ] [ sinθ cosθ 0 ] [ 0 0 1 ]例:绕 Z 轴转 90°(θ=90°,cos=0,sin=1):
[ 0 -1 0 ] [ 1 ] [ 0 ] [ 1 0 0 ] · [ 0 ] = [ 1 ] ← X 轴上的点 (1,0,0) 转到了 Y 轴 (0,1,0) [ 0 0 1 ] [ 0 ] [ 0 ]这就是"旋转矩阵"——用矩阵乘法实现旋转。
21.4 平移(需要齐次坐标)
平移(整体移动)是"加上一个向量",不是线性变换,普通 3×3 矩阵表达不了。于是引入齐次坐标:多加一维。
二维点 (x, y) 写成齐次坐标 (x, y, 1),用 3×3 矩阵做平移:
[ 1 0 tx ] [ x ] [ x + tx ] [ 0 1 ty ] [ y ] = [ y + ty ] [ 0 0 1 ] [ 1 ] [ 1 ]三维点 (x, y, z) 写成 (x, y, z, 1),用 4×4 矩阵做平移:
[ 1 0 0 tx ] [ x ] [ x + tx ] [ 0 1 0 ty ] [ y ] = [ y + ty ] [ 0 0 1 tz ] [ z ] [ z + tz ] [ 0 0 0 1 ] [ 1 ] [ 1 ]这就是为什么 3D 图形里到处都是4×4 矩阵——它能把旋转、缩放、平移统一表示。
21.5 组合变换:矩阵相乘 = 变换叠加
想"先旋转再平移"?把两个变换矩阵相乘,就得到"复合变换":
先做 B 再做 A = A · B (注意顺序:从右往左执行)因为 (A·B)·v = A·(B·v):先对 v 做 B,再对结果做 A。
矩阵乘法的意义之一,就是"变换的组合"。
21.6 刚体变换:保持形状的变换
刚体变换= 旋转 + 平移。它不改变物体的形状、大小、角度(只改变位置和朝向)。
- 刚体的运动(机器人的移动、相机的运动)都是刚体变换
- 用 Eigen 的
Isometry3d表示(第 32 章)
21.7 在 Eigen 里做变换
先睹为快(第 32 章详解):
#include<Eigen/Dense>#include<Eigen/Geometry>#include<iostream>intmain(){constdoublePI=3.14159265358979;// 绕 Z 轴旋转 90°Eigen::AngleAxisdrot(PI/2,Eigen::Vector3d::UnitZ());Eigen::Matrix3d R=rot.toRotationMatrix();Eigen::Vector3dp(1,0,0);// X 轴上的点Eigen::Vector3d p2=R*p;// 旋转std::cout<<"旋转后 = "<<p2.transpose()<<std::endl;// (0,1,0)return0;}实际输出:
旋转后 = 1.61554e-15 1 0别被
1.61554e-15吓到:数学上这个数是 0,但计算机用二进制表示π/2的余弦时不可能精确为 0,于是留下了 1e-15 量级的"浮点残渣"。判断两个浮点数是否相等,永远用"差值小于某个容差"(如 1e-9),不要用==。第 29、30、36 章的残差、行列式都会出现这种现象。
21.8 小结
- 矩阵乘法 = 对向量做变换。
- 缩放:对角矩阵;旋转:旋转矩阵;平移:齐次坐标 + 4×4 矩阵。
- 矩阵相乘 = 变换叠加(从右往左)。
- 刚体变换 = 旋转 + 平移,用
Isometry3d表示。
🎉 第二部分完成!
你现在掌握了理解 Eigen 所需的全部线性代数基础:向量、矩阵、矩阵运算、方程组、行列式、逆矩阵、特征值、几何变换。
第三部分,正式进入 Eigen 库——你会发现前面学的数学和 C++ 全都用上了。
练习题
- 写出绕 Z 轴旋转 90° 的旋转矩阵,用它旋转点 (1,0,0)。
- 写出把点 (x,y,z) 平移 (1,2,3) 的 4×4 齐次矩阵。
- 解释:为什么"先旋转后平移"和"先平移后旋转"结果不同。
- 用自己的话解释"矩阵就是变换"。
- 什么是刚体变换?举一个实际例子。