Skip to content

向量的概念与表示

如果你学过 Canvas 2D 编程,一定写过这样的代码:

javascript
const x = 100;
const y = 200;
ctx.fillRect(x, y, 50, 50);

这里的 (100, 200) 表示矩形的位置。如果要让矩形移动,你可能会写:

javascript
x += velocityX;
y += velocityY;

velocityXvelocityY 表示速度,也就是每帧的位移。你有没有想过,位置、速度、位移这三个概念有什么共同点?

它们都可以用向量来表示。

什么是向量

首先要问一个问题:什么是向量?

向量是既有大小又有方向的量。

这个定义听起来有点抽象。让我们用更直观的方式理解:

  • 标量(Scalar):只有大小,没有方向。例如温度 25°C,质量 5kg,时间 10 秒。
  • 向量(Vector):既有大小又有方向。例如速度"向东 10 米/秒",力"向上 50 牛顿"。

在 3D 图形学中,向量可以理解为空间中的一个箭头

  • 箭头的长度表示向量的大小(也叫长度
  • 箭头的指向表示向量的方向

想象一个从原点 (0, 0, 0) 指向点 (1, 2, 3) 的箭头,这就是一个向量。

向量的三种用途

向量在 3D 图形学中有三种主要用途:

1. 表示位置(点)

向量可以表示空间中的一个点。例如 (3, 5, 2) 表示 x=3, y=5, z=2 的位置。

在这种情况下,向量是从原点 (0, 0, 0) 指向目标点的箭头。

2. 表示方向

向量可以表示一个方向。例如相机的朝向、光线的方向、物体的前进方向。

表示方向时,向量的长度通常是 1(称为单位向量),只保留方向信息。

3. 表示位移

向量可以表示从一个点到另一个点的移动。例如物体的速度、力的作用方向。

如果一个物体在位置 A(1, 2, 3),速度是 v(0.1, 0, 0.2),那么下一帧的位置就是 A + v = (1.1, 2, 3.2)

向量的数学表示

向量有两种常见的数学表示方式:

行向量表示

使用圆括号和逗号:

$$ \mathbf{v} = (x, y, z) $$

例如:$\mathbf{v} = (1, 2, 3)$

列向量表示

使用矩阵形式:

$$ \mathbf{v} = \begin{bmatrix} x \ y \ z \end{bmatrix} $$

例如:

$$ \mathbf{v} = \begin{bmatrix} 1 \ 2 \ 3 \end{bmatrix} $$

在本书中,我们主要使用行向量表示,因为它更简洁。但你需要知道,在矩阵运算中,列向量表示更常用(这将在后续章节中看到)。

从 2D 到 3D

如果你熟悉 2D 图形编程,那么 2D 向量你已经很熟悉了:

javascript
const position2D = { x: 100, y: 200 };

这是一个 2D 向量,只有 x 和 y 两个分量。

3D 向量只是在此基础上增加了 z 轴:

javascript
const position3D = { x: 100, y: 200, z: 50 };

z 轴表示深度:

  • z 值越大,物体越靠近观察者(屏幕外)
  • z 值越小,物体越远离观察者(屏幕内)

在 3D 图形学中,我们使用右手坐标系作为约定:

  • x 轴:向右为正
  • y 轴:向上为正
  • z 轴:向外(朝向你)为正

记忆方法:伸出右手,拇指指向 x 轴正方向,食指指向 y 轴正方向,中指指向 z 轴正方向。

向量的分量

向量的 x、y、z 称为向量的分量(Component)。

对于向量 $\mathbf{v} = (3, 5, 2)$:

  • x 分量是 3(沿 x 轴移动 3 个单位)
  • y 分量是 5(沿 y 轴移动 5 个单位)
  • z 分量是 2(沿 z 轴移动 2 个单位)

分量是标量(普通数字),而向量是由这些分量组合而成的。

一个有趣的事实:向量可以看作是三个轴向分量的叠加。向量 (3, 5, 2) 可以分解为:

$$ \mathbf{v} = 3 \cdot (1, 0, 0) + 5 \cdot (0, 1, 0) + 2 \cdot (0, 0, 1) $$

其中 (1, 0, 0)(0, 1, 0)(0, 0, 1) 是三个基向量(Base Vector),分别代表 x、y、z 轴的单位方向。

代码实现:Vector3 类

现在让我们用 JavaScript 实现一个基础的 Vector3 类。

为什么要用 class 而不是简单的对象字面量?因为后续我们会为向量添加各种运算方法(加减乘除、点积叉积等),使用 class 可以更好地组织代码。

javascript
class Vector3 {
  constructor(x = 0, y = 0, z = 0) {
    this.x = x;
    this.y = y;
    this.z = z;
  }

  toString() {
    return `Vector3(${this.x}, ${this.y}, ${this.z})`;
  }
}

这是一个非常简单的实现:

  • constructor 接收三个参数 x、y、z,默认值都是 0
  • 将参数存储为实例属性
  • toString 方法用于调试输出

使用示例:

javascript
// 创建一个表示位置的向量
const position = new Vector3(10, 20, 5);
console.log(position.toString()); // Vector3(10, 20, 5)

// 创建一个零向量
const zero = new Vector3();
console.log(zero.toString()); // Vector3(0, 0, 0)

// 创建一个表示方向的向量(向右上方)
const direction = new Vector3(1, 1, 0);
console.log(direction.toString()); // Vector3(1, 1, 0)

为什么默认值设为 0?因为零向量 (0, 0, 0) 在图形学中有特殊意义:

  • 作为位置:表示原点
  • 作为方向:表示无方向
  • 作为速度:表示静止

这个设计与 Three.js 的 Vector3 保持一致,Three.js 是业界最流行的 3D 库之一。

小结

在本章中,我们学习了:

  • 向量的定义:既有大小又有方向的量
  • 向量的几何意义:空间中的箭头
  • 向量的三种用途:位置、方向、位移
  • 向量的表示方式:行向量 (x, y, z) 和列向量
  • 从 2D 到 3D:增加 z 轴,使用右手坐标系
  • 向量的分量:x、y、z 分别表示在三个轴上的投影
  • 代码实现:创建了 Vector3 类的基础结构

现在我们知道了向量是什么,下一章将学习如何对向量进行运算——加法、减法和数乘。这些运算是所有复杂变换的基础。


练习

  1. 创建一个向量表示点 (5, 10, 15)
  2. 创建一个向量表示"向右"的方向(提示:只有 x 分量不为 0)
  3. 创建一个向量表示"沿 45° 角向右上方"的方向(提示:x 和 y 分量相等且为正)

试着在浏览器控制台中运行上面的 Vector3 类代码,完成这三个练习。

向量的概念与表示 has loaded