第四节:二维平移变换——从向量到矩阵的进化

各位同学,今天我们聊一个看似简单、但却是整个坐标变换基石的话题——二维平移变换。

你可能觉得,平移嘛,不就是把点从A挪到B吗?加个坐标不就完了?

嗯,没错。但问题在于——当你后面遇到旋转、缩放、甚至三维变换时,这种「加法思维」会把你坑得很惨。

我当年刚入行做机器人运动学仿真时,就吃过这个亏。当时我天真地把平移和旋转分开处理,结果代码里全是if-else判断,调试到凌晨三点才发现是坐标系没统一。后来我才明白——平移变换,必须用矩阵乘法来表达。

好,咱们一步步来。

4.1 平移向量的概念

先看一个最简单的场景。

假设二维平面上有一个点 P(x, y),你想把它向右移动 tx 个单位,向上移动 ty 个单位。新位置 P' 的坐标就是:

P'.x = P.x + tx
P'.y = P.y + ty

这个 (tx, ty) 就是平移向量。

说白了,平移向量描述的是「从哪到哪」的位移。它只有大小和方向,没有起点——这也是向量和点的本质区别。

我的小经验: 在写代码时,我习惯把平移向量单独定义成一个结构体,而不是直接用两个散装变量。这样后面做向量加法、点乘什么的都方便。

4.2 问题来了——为什么需要齐次坐标?

好,现在问题来了。

平移是加法,旋转和缩放是乘法。如果你在一个变换序列里既有平移又有旋转,你就得来回切换加法/乘法模式。

你想想看,这多麻烦?

更关键的是——矩阵乘法可以复合,加法不行。如果你想把多个变换合并成一个矩阵,平移的加法就格格不入。

那怎么办?

解决方案就是——引入齐次坐标。

什么叫齐次坐标?

很简单:把一个二维点 (x, y) 表示成三维向量 (x, y, 1)。多出来的那个维度,我们叫它 w 分量,通常取 1。

为什么是 1?

因为这样平移就能写成矩阵乘法了。你看:

| 1  0  tx |   | x |   | x + tx |
| 0  1  ty | * | y | = | y + ty |
| 0  0  1  |   | 1 |   |   1    |

看到了吗?平移变成了矩阵乘法。完美统一。

核心思想: 齐次坐标让平移、旋转、缩放全部可以用矩阵乘法表示。这是计算机图形学和机器人学里最优雅的设计之一。

4.3 平移矩阵的推导

我们来手推一下平移矩阵。

假设点 P(x, y) 平移后得到 P'(x', y'),满足:

x' = x + tx
y' = y + ty

我们想找一个 3×3 矩阵 M,使得:

| x' |   | ?  ?  ? |   | x |
| y' | = | ?  ?  ? | * | y |
| 1  |   | ?  ?  ? |   | 1 |

根据第一行:x' = 1·x + 0·y + tx·1

所以第一行是 [1, 0, tx]

根据第二行:y' = 0·x + 1·y + ty·1

所以第二行是 [0, 1, ty]

第三行:1 = 0·x + 0·y + 1·1

所以第三行是 [0, 0, 1]

于是平移矩阵就是:

T(tx, ty) = | 1  0  tx |
            | 0  1  ty |
            | 0  0  1  |

就这么简单。

我曾经踩过的坑: 注意矩阵乘法的顺序!如果你先旋转再平移,和先平移再旋转,结果完全不同。我当年在机械臂逆运动学里搞反了顺序,仿真出来的手臂直接穿模了……记住:变换矩阵是从右往左读的。

4.4 代码实现

下面我用 Python 实现一个简单的二维平移变换。代码不长,但结构清晰。

import numpy as np

def translation_matrix(tx, ty):
    """
    生成二维平移矩阵(齐次坐标形式)
    :param tx: x方向平移量
    :param ty: y方向平移量
    :return: 3x3 平移矩阵
    """
    return np.array([
        [1, 0, tx],
        [0, 1, ty],
        [0, 0, 1]
    ])

def apply_transform(point, matrix):
    """
    对点应用变换矩阵
    :param point: (x, y) 二维点
    :param matrix: 3x3 变换矩阵
    :return: (x', y') 变换后的点
    """
    # 转为齐次坐标
    p_homogeneous = np.array([point[0], point[1], 1])
    # 矩阵乘法
    p_transformed = matrix @ p_homogeneous
    # 转回二维坐标
    return (p_transformed[0], p_transformed[1])

# 示例:将点 (2, 3) 向右平移 5,向上平移 4
point = (2, 3)
T = translation_matrix(5, 4)
new_point = apply_transform(point, T)

print(f"原始点: {point}")
print(f"平移后: {new_point}")
# 输出: 原始点: (2, 3)
#       平移后: (7.0, 7.0)

这段代码我建议你亲手跑一遍。注意看 matrix @ p_homogeneous 这一行——这就是齐次坐标的威力,所有变换统一成矩阵乘法。

4.5 本章知识结构图

下面我用一张 SVG 图来总结本章的核心逻辑。你一看就明白了。

二维平移变换知识结构 平移向量 (tx, ty) 描述位移的大小和方向 问题:加法 vs 乘法 平移是加法,旋转是乘法 齐次坐标 (x, y, 1) 平移矩阵 T(tx, ty) | 1 0 tx | | x | | x+tx | | 0 1 ty | * | y | = | y+ty | 代码实现(Python + NumPy) translation_matrix(tx, ty) → apply_transform(point, matrix) 从概念到实现

这张图从左到右、从上到下展示了本章的完整逻辑链:从平移向量的概念出发,引出齐次坐标的必要性,然后推导平移矩阵,最后落地到代码实现。你学完这一章,应该能闭着眼写出平移矩阵。

4.6 小结

好,咱们总结一下今天的内容:

  • 平移向量就是 (tx, ty),描述位移。
  • 齐次坐标把二维点升维到 (x, y, 1),让平移变成矩阵乘法。
  • 平移矩阵是 3×3 的单位矩阵加上平移量。
  • 代码实现用 NumPy 一行矩阵乘法搞定。

我个人觉得,齐次坐标是计算机图形学里最优雅的数学技巧之一。它让所有变换统一成矩阵乘法,后面的旋转、缩放、甚至投影变换,都建立在同样的框架上。

下一节我们会讲旋转。到时候你会发现——有了齐次坐标这个武器,旋转矩阵的推导会顺畅得多。

好,今天就到这里。代码记得自己跑一遍,有问题随时交流。

一句话记住本章: 平移不是加法,是矩阵乘法——用齐次坐标,一切皆可乘。
可可精品资料库