第二章 数学预备知识:向量、矩阵、齐次坐标与仿射变换
各位同学,咱们开始上课。
做NURBS插补,说白了就是跟数学打交道。你想想看,一条曲线在空间里怎么走、刀具怎么动、速度怎么控制——这些背后全是数学。我当年刚入行时,觉得搞数控嘛,会写G代码就行了。结果第一次调五轴联动的程序,被一个旋转矩阵卡了三天。嗯,从那以后我就老老实实把线性代数捡起来了。
这一章,咱们把基础打牢。别嫌简单,后面所有的高级算法都建立在这些概念之上。
2.1 向量:空间中的箭头
向量是什么?你可以把它想象成一个箭头。有大小,有方向。
在数控系统里,我们常用三维向量表示位置、速度、加速度。比如刀具中心点的位置:
// 三维位置向量
P = (x, y, z)
// 速度向量
V = (vx, vy, vz)
向量的基本运算,我建议你闭着眼睛都能写出来:
- 加法:对应分量相加。比如两个位移叠加。
- 数乘:向量乘以一个标量,改变长度不改变方向。
- 点积:结果是一个数。几何意义是一个向量在另一个方向上的投影长度。
- 叉积:结果是一个向量。垂直于原来两个向量所在的平面。
避坑指南:我曾经在计算刀轴矢量时,把点积和叉积搞混了。结果刀路直接扎进工件里。记住——点积出标量,叉积出向量。方向用右手定则判断。
在实际项目中,向量最常用的场景是单位化。比如你要控制刀具沿某个方向移动,必须先把方向向量归一化,再乘以进给速度。否则速度会忽快忽慢。
// 向量单位化
double length = sqrt(vx*vx + vy*vy + vz*vz);
double ux = vx / length;
double uy = vy / length;
double uz = vz / length;
2.2 矩阵:变换的瑞士军刀
矩阵这东西,刚接触时觉得抽象。但你把它看成一种「变换规则」就好理解了。
一个3×3矩阵,可以把一个三维向量映射到另一个三维向量。旋转、缩放、错切——全都能干。
矩阵乘法是核心操作。注意:矩阵乘法不满足交换律。A×B和B×A通常不一样。我见过不少新手在这里栽跟头。
| 变换类型 | 矩阵形式 | 说明 |
|---|---|---|
| 绕X轴旋转θ | [1, 0, 0; 0, cosθ, -sinθ; 0, sinθ, cosθ] | 右手定则,拇指指向X正方向 |
| 绕Y轴旋转θ | [cosθ, 0, sinθ; 0, 1, 0; -sinθ, 0, cosθ] | 注意sinθ的符号 |
| 绕Z轴旋转θ | [cosθ, -sinθ, 0; sinθ, cosθ, 0; 0, 0, 1] | 最常用的旋转 |
| 缩放(sx, sy, sz) | [sx, 0, 0; 0, sy, 0; 0, 0, sz] | 均匀缩放时sx=sy=sz |
个人经验:我习惯把矩阵乘法写成「左乘」的形式。即变换矩阵×向量。这样阅读代码时,从左往右读就是变换的顺序。比如:Rz × Ry × Rx × P,先绕X转,再绕Y,最后绕Z。
2.3 齐次坐标:为什么需要多一个维度?
这个问题我问过很多人。答案很简单:为了统一处理平移和旋转。
你想想看,用3×3矩阵可以表示旋转和缩放,但平移不行。平移是加法,不是乘法。这就导致变换不统一,代码写起来很别扭。
齐次坐标的解决方案:给三维向量加一个维度w。通常w=1表示点,w=0表示方向向量。
// 三维点P = (x, y, z) 的齐次坐标
Ph = (x, y, z, 1)
// 三维方向向量V = (vx, vy, vz) 的齐次坐标
Vh = (vx, vy, vz, 0)
这样一来,平移也能用矩阵乘法表示了:
// 平移矩阵 (tx, ty, tz)
[1, 0, 0, tx]
[0, 1, 0, ty]
[0, 0, 1, tz]
[0, 0, 0, 1 ]
注意:齐次坐标的w分量在计算后要归一化。即把(x, y, z, w)除以w,得到(x/w, y/w, z/w, 1)。我见过有人忘记这一步,结果坐标全乱了。
2.4 仿射变换:数控系统的灵魂
仿射变换,说白了就是「线性变换+平移」。在数控系统里,几乎所有坐标变换都是仿射变换。
常见的仿射变换包括:
- 平移:移动工件坐标系原点
- 旋转:绕某个轴转动
- 缩放:改变尺寸
- 镜像:关于某个平面对称
- 错切:让形状倾斜
用齐次坐标表示,一个仿射变换就是4×4矩阵:
// 通用仿射变换矩阵
[a11, a12, a13, tx]
[a21, a22, a23, ty]
[a31, a32, a33, tz]
[0, 0, 0, 1 ]
左上角的3×3子矩阵负责旋转和缩放,右上角的3×1向量负责平移。
核心要点:在NURBS插补中,我们经常需要把曲线从工件坐标系变换到刀具坐标系。这个变换就是仿射变换。你只需要一个4×4矩阵,就能搞定所有位置和姿态的转换。
2.5 知识体系总览
下面这张图,是我自己总结的本章知识结构。建议你保存下来,后面学累了就回来看看。
2.6 实战:一个简单的坐标变换
咱们来点实际的。假设工件坐标系下有一个点P=(10, 20, 30),现在要把工件绕Z轴旋转45度,然后沿X方向平移5个单位。求变换后的坐标。
// 齐次坐标表示
P = (10, 20, 30, 1)
// 绕Z轴旋转45度
cos45 = 0.7071
sin45 = 0.7071
Rz = [
cos45, -sin45, 0, 0,
sin45, cos45, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
]
// 沿X平移5
Tx = [
1, 0, 0, 5,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
]
// 先旋转再平移
T = Tx × Rz
P_new = T × P
// 结果:P_new = (-9.142, 24.142, 30, 1)
我的习惯:写代码时,我会把变换矩阵按「从右往左读」的顺序组织。比如上面的例子,先旋转(Rz)再平移(Tx),矩阵就是Tx×Rz。这样代码逻辑和数学表达一致,不容易出错。
好了,这一章的内容就这些。向量、矩阵、齐次坐标、仿射变换——这四个概念是NURBS插补的数学基石。后面讲曲线求值、插补算法时,你会反复用到它们。
记住:数学不是用来背的,是用来用的。多动手算几遍,自然就熟了。