从零到深入理解几何变换:前端工程师的数学指南

314 阅读5分钟

前言

几何变换是前端工程师在 CSS、Canvas 或 WebGL 中不可避免会遇到的知识,但它的数学原理常常令人望而却步。作为一名前端工程师,我也曾迷惑于这些抽象的公式和矩阵。然而,这些数学工具并不复杂,它们背后有着非常直观的逻辑。

这篇文章的目标是从零开始,让你一步步理解几何变换的原理和应用,即使你没有任何线性代数基础,也能毫无压力地学会如何用它处理二维和三维的几何变换。


1. 认识向量和它的基本运算

1.1 什么是向量?

向量是一个描述位置或方向的数学工具。一个向量可以表示为:

v=[xy]\mathbf{v} = \begin{bmatrix} x \\ y \end{bmatrix}

在二维空间中,[x,y][x, y] 分别是 xx轴yy轴上的分量。例如,向量 [34]\begin{bmatrix} 3 \\ 4 \end{bmatrix} 表示从原点到点 (3,4)(3, 4) 的方向和距离。

1.2 向量的加法与减法

向量的加减法是基于分量分别相加或相减。例如:

[23]+[14]=[2+13+4]=[37]\begin{bmatrix} 2 \\ 3 \end{bmatrix} + \begin{bmatrix} 1 \\ 4 \end{bmatrix} = \begin{bmatrix} 2+1 \\ 3+4 \end{bmatrix} = \begin{bmatrix} 3 \\ 7 \end{bmatrix}

几何意义:两个向量相加相当于将它们首尾相连,然后找到终点。


2. 认识矩阵和它的基本运算

2.1 什么是矩阵?

矩阵是一个工具,用来描述复杂的变换。一个二维矩阵通常表示为:

M=[abcd]M = \begin{bmatrix} a & b \\ c & d \end{bmatrix}

其中每个数字 a,b,c,da,b,c,d 都有几何意义,表示变换时不同方向的影响。

2.2 矩阵与向量的乘法

矩阵乘法将变换作用在向量上,公式如下:

[abcd][xy]=[ax+bycx+dy]\begin{bmatrix} a & b \\ c & d \end{bmatrix} \cdot \begin{bmatrix} x \\ y \end{bmatrix} = \begin{bmatrix} a \cdot x + b \cdot y \\ c \cdot x + d \cdot y \end{bmatrix}

几何意义:矩阵乘法改变了向量的长度和方向。

2.3 为什么矩阵这样定义?

矩阵的这种运算方式源于线性变换的需求,保证变换后的向量仍然保持比例关系,并符合直观几何逻辑。


3. 平移:如何用数学表示点的移动?

3.1 什么是平移?

平移是将点 [x,y][x,y] 沿某个方向移动。例如:

[xy]+[txty]=[x+txy+ty]\begin{bmatrix} x \\ y \end{bmatrix} + \begin{bmatrix} t_x \\ t_y \end{bmatrix} = \begin{bmatrix} x + t_x \\ y + t_y \end{bmatrix}

3.2 平移的矩阵表示

平移不能直接用普通矩阵表示,需要将向量扩展为齐次坐标

[xy1]\begin{bmatrix} x \\ y \\ 1 \end{bmatrix}

平移矩阵为:

T=[10tx01ty001]T = \begin{bmatrix} 1 & 0 & t_x \\ 0 & 1 & t_y \\ 0 & 0 & 1 \end{bmatrix}

然后计算:

T[xy1]=[x+txy+ty1]T \cdot \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} = \begin{bmatrix} x + t_x \\ y + t_y \\ 1 \end{bmatrix}

4. 旋转:如何让点绕原点旋转?

4.1 旋转的公式

[x,y][x, y] 围绕原点逆时针旋转角度 θθ后的新坐标为:

x=xcos(θ)ysin(θ)y=xsin(θ)+ycos(θ)x′=x⋅cos(θ)−y⋅sin(θ) \\ y′=x⋅sin⁡(θ)+y⋅cos⁡(θ)

推导(使用极坐标):

x=rsin(θ+θrot)y=rsin(θ+θrot)x′ =r\sin(\theta + \theta_{\text{rot}}) \\ y′=rsin(θ+θrot​)

4.2 矩阵表示

旋转矩阵为:

R=[cos(θ)sin(θ)sin(θ)cos(θ)]R = \begin{bmatrix} \cos(\theta) & -\sin(\theta) \\ \sin(\theta) & \cos(\theta) \end{bmatrix}

计算公式:

R[xy]=[xy]R \cdot \begin{bmatrix} x \\ y \end{bmatrix} = \begin{bmatrix} x' \\ y' \end{bmatrix}

4.3 几何意义

旋转矩阵重新定义了 xx轴yy轴方向,使向量投影到新轴上,从而完成旋转。


5. 缩放:如何调整点的大小?

5.1 缩放的公式

[x,y][x, y]按比例 sx,sys_x, s_y 缩放后的新坐标为:

x=xsx,y=ysyx′=x⋅s_x,y′=y⋅s_y

5.2 矩阵表示

缩放矩阵为:

S=[sx00sy]S = \begin{bmatrix} s_x & 0 \\ 0 & s_y \end{bmatrix}

计算公式:

S[xy]=[xy]S \cdot \begin{bmatrix} x \\ y \end{bmatrix} = \begin{bmatrix} x' \\ y' \end{bmatrix}

6. 综合变换:平移、旋转和缩放的组合

6.1 综合变换矩阵

将平移、旋转、缩放结合:

M=TRSM=T⋅R⋅S

然后对点计算:

v=Mv\mathbf{v'} = M \cdot \mathbf{v}

7 CSS中translate参数matrix()matrix3d()的解释

在 CSS 的 transform 属性中,matrix()matrix3d() 函数直接使用矩阵来描述平移、旋转、缩放、倾斜等变换。矩阵的知识在其中被用作底层数学工具,以下是详细说明:

7.1. 基本矩阵知识

在 2D 变换中,CSS 使用 3x3 矩阵来表示变换:

[acebdf001]\begin{bmatrix} a & c & e \\ b & d & f \\ 0 & 0 & 1 \end{bmatrix}

其中:

  • a,b,c,da, b, c, d:与旋转、缩放、倾斜相关。
  • e,fe, f:与平移相关。

matrix(a, b, c, d, e, f) 对应这 6 个值。

在 3D 变换中,CSS 使用 4x4 矩阵,扩展到 matrix3d()

7.2. 平移

在平移中,矩阵表示如下:

[10tx01ty001]\begin{bmatrix} 1 & 0 & t_x \\ 0 & 1 & t_y \\ 0 & 0 & 1 \end{bmatrix}

对应的 CSS 表达式为:

transform: matrix(1, 0, 0, 1, tx, ty);
  • txt_x​:沿 x 轴的平移量。
  • tyt_y​:沿 y 轴的平移量。

例如,平移 50px 到右边,30px 到下方:

transform: matrix(1, 0, 0, 1, 50, 30);

7.3. 旋转

在旋转中,矩阵表示为:

[cos(θ)sin(θ)0sin(θ)cos(θ)0001]\begin{bmatrix} \cos(\theta) & -\sin(\theta) & 0 \\ \sin(\theta) & \cos(\theta) & 0 \\ 0 & 0 & 1 \end{bmatrix}

对应的 CSS 表达式为:

transform: matrix(cosθ, sinθ, -sinθ, cosθ, 0, 0);

例如,旋转 45 度 (π/4):

transform: matrix(0.707, 0.707, -0.707, 0.707, 0, 0);

(注意:CSS 中角度通常用度数而非弧度,需先转为弧度。)


7.4. 缩放

在缩放中,矩阵表示为:

[sx000sy0001]\begin{bmatrix} s_x & 0 & 0 \\ 0 & s_y & 0 \\ 0 & 0 & 1 \end{bmatrix}

对应的 CSS 表达式为:

transform: matrix(sx, 0, 0, sy, 0, 0);
  • sxs_x​:x 轴的缩放比例。
  • sys_y​:y 轴的缩放比例。

例如,将元素沿 x 轴缩放 2 倍,y 轴缩放 1.5 倍:

transform: matrix(2, 0, 0, 1.5, 0, 0);

7.5. 综合变换

多个变换(如平移、旋转、缩放)可以结合起来表示为一个矩阵,通过矩阵乘法完成。

例如,先缩放再旋转,最后平移:

总变换矩阵=TRS{总变换矩阵} = T \cdot R \cdot S

在 CSS 中手动计算结果,或者逐步设置:

transform: matrix(0.707, 0.707, -0.707, 0.707, 50, 30);

7.6. 3D 变换

在 3D 变换中,矩阵扩展为 4x4 矩阵。matrix3d() 函数可以表达 3D 变换,例如:

[abcdefghijklmnop]\begin{bmatrix} a & b & c & d \\ e & f & g & h \\ i & j & k & l \\ m & n & o & p \end{bmatrix}

每个元素在 3D 空间中有对应含义。

示例:3D 平移、旋转、缩放的矩阵变换可以通过 matrix3d() 表达。


8. 动态使用矩阵

你可以结合 JavaScript 动态计算矩阵并设置:

const element = document.querySelector('.box');
const angle = Math.PI / 4; // 45 degrees
const scale = 2;
const tx = 50, ty = 30;

const cos = Math.cos(angle);
const sin = Math.sin(angle);

// 计算矩阵值
const a = cos * scale;
const b = sin * scale;
const c = -sin * scale;
const d = cos * scale;

// 设置 transform
element.style.transform = `matrix(${a}, ${b}, ${c}, ${d}, ${tx}, ${ty})`;

通过矩阵的方式,你可以精确控制变换的每一步。这对于复杂动画、特效以及精确的几何变换非常有用!


9. 结语

理解几何变换背后的数学原理,是前端工程师突破技术瓶颈的重要一步。这不仅可以让你更深入地理解 Canvas 和 WebGL 的工作原理,还能在复杂的动画和 3D 渲染中游刃有余。希望这篇文章能帮你重拾数学的魅力,成为更加全面的工程师! 😊