“为什么DirectX里表示三维坐标要建一个4*4的矩阵?”

2016年01月27日 14:10 0 点赞 0 评论 更新于 2025-11-21 19:45

前言

本文标题源自知乎上的同名问题:为什么DirectX里表示三维坐标要建一个4*4的矩阵? - 编程。正如Milo Yip大神所说,这个标题存在问题,矩阵的作用是表示变换,而非坐标。在了解矩阵的作用后,我们需要思考为何变换要使用4×4的矩阵,而非3×3的矩阵,这是否多此一举?下面我们来深入探讨这个话题。

怎么平移一个三维空间中的点

在三维空间中平移一个点,方法很简单,只需将该点坐标的每个分量(x, y, z)与对应轴上的平移距离相加。

例如,点p1(x1, y1, z1)在X轴、Y轴以及Z轴上分别平移Δx、Δy、Δz后到达新的点p2(x2, y2, z2),则可通过以下公式确定p2的坐标:

x2 = x1 + Δx
y2 = y1 + Δy
z2 = z1 + Δz

接下来,我们看看另一种变换:旋转。

再来旋转一个点

旋转相较于平移更为复杂,描述一个旋转需要明确以下几个方面:旋转轴、旋转方向和旋转角度。

这里假设点p需要绕Z轴顺时针旋转β度。

设点P1(x1, y1, z1)绕Z轴顺时针旋转β度后到达点P2(x2, y2, z2)。假设原点到P1的距离为L,且P1和Y轴之间的夹角为α,根据三角函数公式可得P1点的坐标:

x1 = L·sinα
y1 = L·cosα

由于是绕Z轴旋转,z坐标不变,暂不考虑。

同样根据三角函数公式,可计算出P2的坐标:

x2 = L·sin(α + β)
y2 = L·cos(α + β)

回忆中学几何数学中两角和与差的公式:

cos(α + β) = cosα·cosβ - sinα·sinβ
cos(α - β) = cosα·cosβ + sinα·sinβ
sin(α + β) = sinα·cosβ + cosα·sinβ
sin(α - β) = sinα·cosβ - cosα·sinβ

结合P1的坐标表示形式,可将P2的坐标变换形式:

x2 = L·(sinα·cosβ + cosα·sinβ) = cosβ·x1 + sinβ·y1
y2 = L·(cosα·cosβ - sinα·sinβ) = cosβ·y1 - sinβ·x1
z2 = z1

由此,已知P1点坐标和旋转角度β,就可根据上述公式求出P2点坐标的各个分量。结合上一小节平移点的公式,似乎不使用矩阵,仅通过两组表达式就能实现坐标变换。但实际情况并非如此简单。

带来便捷的矩阵

理论上,通过数学公式可以实现坐标变换。然而,当变换较为复杂时,直接使用数学表达式进行运算会非常繁琐。因此,在实际应用中,常使用矩阵(由m × n个标量组成的长方形数组)来表示平移、旋转和缩放等线性变换。

两个变换矩阵A和B的积P = AB,变换矩阵P相当于A和B所代表的变换。例如,若A为旋转矩阵,B为平移矩阵,则矩阵P可实现旋转和平移变换。需注意,矩阵乘法不符合交换律,即AB和BA不相等。

我们仍未解答为何三维空间需要4×4矩阵来实现变换,下面分别看看3×3矩阵和4×4矩阵的使用情况。

3×3矩阵和旋转

先看一个矩阵乘以三维矢量的算式,矩阵为3×3矩阵,右侧是点P1的坐标,左侧是点P2的坐标。根据表达式可求出x2、y2、z2的值:

x2 = a·x1 + b·y1 + c·z1
y2 = d·x1 + e·y1 + f·z1
z2 = g·x1 + h·y1 + i·z1

将旋转表达式与该矩阵等式对比:

x2 = a·x1 + b·y1 + c·z1
x2 = cosβ·x1 + sinβ·y1
y2 = d·x1 + e·y1 + f·z1
y2 = cosβ·y1 - sinβ·x1
z2 = g·x1 + h·y1 + i·z1
z2 = z1

通过对比可得:a = cosβ,b = sinβ,c = 0;d = -sinβ,e = cosβ,f = 0;g = 0,h = 0,i = 1。

这表明,通过这个3×3的变换矩阵,可实现三维空间的旋转变换。那为何还需要4×4矩阵呢?

搞不定的平移,4×4矩阵来救场

我们已用3×3矩阵实现了旋转变换,若它是完美的变换解决方案,应也适用于其他变换,如平移。下面通过对比矩阵等式和数学表达式来探究它是否能满足平移需求。

x2 = a·x1 + b·y1 + c·z1
x2 = x1 + Δx
y2 = d·x1 + e·y1 + f·z1
y2 = y1 + Δy
z2 = g·x1 + h·y1 + i·z1
z2 = z1 + Δz

对比发现,平移表达式中带有常量Δx,而旋转表达式和矩阵等式中都没有与之对应的常量。因此,无法用3×3矩阵表示平移,需使用4×4矩阵。但新问题随之而来,三维坐标如何与4×4矩阵相乘?

齐次坐标

为解决三维矢量和4×4矩阵相乘的问题,我们为三维矢量添加了第四个分量,使三维矢量(x, y, z)变为四维的(x, y, z, w),这种由4个分量组成的矢量称为齐次坐标。

齐次坐标(x, y, z, w)等价于三维坐标(x/w, y/w, z/w),当w分量的值为1时,该齐次坐标可当作三维坐标使用,其所表示的坐标就是以x、y、z为坐标值的点。

为与4×4矩阵相乘,P1点坐标变为(x1, y1, z1, 1),矩阵等式变为:

x2 = a·x1 + b·y1 + c·z1 + d
x2 = x1 + Δx
y2 = e·x1 + f·y1 + g·z1 + h
y2 = y1 + Δy
z2 = i·x1 + j·y1 + k·z1 + l
z2 = z1 + Δz
1 = m·x1 + n·y1 + o·z1 + p

通过对比可得:a = 1,b = 0,c = 0,d = Δx;e = 0,f = 1,g = 0,h = Δy;i = 0,j = 0,k = 1,l = Δz;m = 0,n = 0,o = 0,p = 1。

这样,我们就得到了4×4的平移矩阵。

总结

在介绍矩阵乘法时提到,两个变换矩阵A和B的积P = AB,相当于A和B所代表的变换。在游戏编程中,常需将一连串的变换预先计算为单一矩阵,因此不能同时存在3×3矩阵和4×4矩阵。将3×3矩阵拓展为4×4矩阵相对容易,通过一个4×4矩阵可整合平移矩阵和旋转矩阵。

作者信息

洞悉

洞悉

共发布了 3994 篇文章