Skip to content

数学基元

目的与范围

本文档描述了构成 Three.js 基础层的数学基元类。这些类为 3D 图形计算提供了基本的数据结构和操作,包括向量、矩阵、四元数、包围体和空间查询。数学基元在整个库中用于变换、光线投射、碰撞检测和几何计算。

关于这些基元如何与场景图对象集成,请参阅 场景图与 Object3D。关于它们在光线投射系统中的使用,请参阅 光线投射与对象拾取

架构概述

数学基元作为 Three.js 中最低级别的计算层,提供高级系统所依赖的不可变数学操作。所有数学基元类都遵循一致的 API 模式:按组件构造、返回 this 的可链式调用变异方法、以及用于只读操作的独立输出参数。

SVG
100%

向量类

Vector2

Vector2 表示具有 xy 分量的 2D 向量,用于 UV 坐标、屏幕位置和 2D 几何操作。该类为 xy 分别提供了 widthheight 别名。

关键操作:

OperationMethodDescription
Arithmeticadd(), sub(), multiply(), divide()Component-wise operations
ScalaraddScalar(), multiplyScalar(), divideScalar()Uniform scaling
Lengthlength(), lengthSq(), normalize()Magnitude operations
DistancedistanceTo(), distanceToSquared()Euclidean distance
Interpolationlerp(), lerpVectors()Linear interpolation
Clampingclamp(), clampScalar(), clampLength()Constraint operations

Vector3

Vector3 是最常用的向量类,表示 3D 点、方向和位移。它支持 3D 几何的综合操作,包括叉积、投影以及通过矩阵和四元数的变换。

变换方法:

applyMatrix3(m)          - Multiply by 3x3 matrix
applyMatrix4(m)          - Multiply by 4x4 matrix with perspective division
applyQuaternion(q)       - Rotate by quaternion
applyEuler(euler)        - Rotate by Euler angles
applyAxisAngle(axis, angle) - Rotate around axis

坐标系转换:

setFromSpherical(s)              - From spherical coordinates (radius, phi, theta)
setFromSphericalCoords(r, φ, θ)  - Direct spherical conversion
setFromCylindrical(c)            - From cylindrical coordinates
setFromCylindricalCoords(r, θ, y) - Direct cylindrical conversion

矩阵提取:

setFromMatrixPosition(m)  - Extract translation from Matrix4
setFromMatrixScale(m)     - Extract scale from Matrix4
setFromMatrixColumn(m, i) - Extract column i from Matrix4

The implementation uses a reusable _quaternion instance src/math/Vector3.js1257 to avoid allocations during transformations like applyEuler() src/math/Vector3.js388-392

Vector4

Vector4 表示用于 4D 变换和着色器操作的齐次坐标 (x, y, z, w)。w 分量默认为 1,以启用正确的透视除法。与 Vector2 一样,它为 zw 分量提供了 widthheight 别名。

变换类


Matrix4

Matrix4 表示以列优先顺序存储在 elements 数组 src/math/Matrix4.js82-89 中的 4×4 变换矩阵。构造函数和 set() 方法为方便起见接受行优先参数,但内部存储为列优先以兼容 GPU。

分解图示:

SVG
100%

关键变换工厂方法:

MethodPurpose
makeTranslation(x, y, z)Pure translation matrix
makeRotationX/Y/Z(θ)Axis-aligned rotation
makeRotationAxis(axis, angle)Arbitrary axis rotation
makeRotationFromEuler(euler)Rotation from Euler angles (6 orders)
makeRotationFromQuaternion(q)Rotation from quaternion
makeScale(x, y, z)Non-uniform scaling
makeShear(xy, xz, yx, yz, zx, zy)Shear transformation
makePerspective(...)Perspective projection matrix
makeOrthographic(...)Orthographic projection matrix

组合与分解:

compose(position, quaternion, scale)     - Build TRS matrix
decompose(position, quaternion, scale)   - Extract TRS components

The compose() method src/math/Matrix4.js1000-1034 directly computes the matrix elements from quaternion components, avoiding intermediate matrix multiplications for performance.

Matrix3

Matrix3 表示 3×3 矩阵,主要用于法线变换和纹理坐标变换。与 Matrix4 一样,它使用列优先存储 src/math/Matrix3.js62-68 和行优先输入。

getNormalMatrix(matrix4) 方法 src/math/Matrix3.js367-386 提取上 3×3 矩阵,转置并求逆,以生成一个在非均匀缩放下正确变换表面法线的法线变换矩阵。

Quaternion

Quaternion 表示为 4 分量单位向量 (x, y, z, w) 的旋转,其中 w 是标量分量。Three.js 期望四元数保持归一化以确保正确行为。该类提供静态方法 slerpFlat()multiplyQuaternionsFlat() src/math/Quaternion.js60-163,用于在不分配对象的情况下对扁平数组进行操作,用于动画系统。

旋转转换方法:

setFromEuler(euler)              - Convert from Euler angles
setFromAxisAngle(axis, angle)    - Convert from axis-angle
setFromRotationMatrix(m)         - Extract from Matrix4 upper 3x3
setFromUnitVectors(vFrom, vTo)   - Rotation between two directions

setFromEuler() 实现 src/math/Quaternion.js301-373 处理所有六种旋转顺序 (XYZ, YXZ, ZXY, ZYX, YZX, XZY),并进行了优化的三角函数计算。

插值:

slerp(q, t)        - Spherical linear interpolation
rotateTowards(q, step) - Rotation with angular step limit

Euler

Euler 表示为三个角度 (x, y, z) 的旋转,单位为弧度,并具有指定的旋转顺序。默认顺序为 'XYZ' src/math/Euler.js35,存储在 DEFAULT_ORDER 静态常量中。

旋转顺序: XYZ, YXZ, ZXY, ZYX, YZX, XZY

该类使用 getter/setter 属性 src/math/Euler.js59-127,在修改时调用 _onChangeCallback(),从而在 Object3D 变换中使用欧拉角时实现自动更新。

转换方法:

setFromRotationMatrix(m, order)   - Extract from Matrix4
setFromQuaternion(q, order)       - Convert from Quaternion

空间查询类

包围体

SVG
100%

Box3

Box3 表示具有 minmax Vector3 角点的轴对齐包围盒 (AABB)。空盒子表示为 min = (+∞, +∞, +∞) 和 max = (−∞, −∞, −∞) src/math/Box3.js14

构造方法:

MethodSource
setFromArray(array)Flat array of xyz coordinates
setFromBufferAttribute(attribute)BufferAttribute position data
setFromPoints(points)Array of Vector3
setFromObject(object, precise)Object3D hierarchy bounds
setFromCenterAndSize(center, size)Center point and dimensions

expandByObject() 方法 src/math/Box3.js298-380 处理两种模式:

相交测试:

containsPoint(point)         - Point containment
containsBox(box)            - Box containment
intersectsBox(box)          - Box-box intersection
intersectsSphere(sphere)    - Box-sphere intersection
intersectsPlane(plane)      - Box-plane intersection
intersectsTriangle(triangle) - Box-triangle intersection (SAT)

三角形相交 src/math/Box3.js521-572 使用分离轴定理 (SAT),具有 13 个潜在分离轴。

Sphere

Sphere 表示由 center Vector3 和 radius 数值定义的包围球。默认半径 -1 表示空球 src/math/Sphere.js20

包围球生成:

setFromPoints(points, optionalCenter) - Ritter's algorithm for approximate bounds

Ritter 算法实现 src/math/Sphere.js65-134 迭代扩展球体以包含所有点。

相交测试:

containsPoint(point)         - Point containment
intersectsSphere(sphere)    - Sphere-sphere intersection
intersectsBox(box)          - Sphere-box intersection
intersectsPlane(plane)      - Sphere-plane intersection

Ray

Ray 表示具有 origin 和归一化 direction Vector3 的无限射线。射线被 Raycaster 类用于拾取和相交测试。

核心操作:

at(t, target)                            - Point at distance t
closestPointToPoint(point, target)       - Nearest point on ray
distanceToPoint(point)                   - Distance to point
distanceSqToSegment(v0, v1, ...)        - Distance to line segment

相交方法:

intersectBox(box, target)               - Ray-box intersection
intersectSphere(sphere, target)         - Ray-sphere intersection
intersectPlane(plane, target)           - Ray-plane intersection
intersectTriangle(a, b, c, backfaceCulling, target) - Ray-triangle (Möller-Trumbore)

The triangle intersection src/math/Ray.js234-315 implements the Möller-Trumbore algorithm, computing barycentric coordinates for texture interpolation.

Plane

Plane 表示 Hessian 法线形式的无限平面,具有单位 normal Vector3 和标量 constant。平面方程为:normal · point + constant = 0

操作:

distanceToPoint(point)           - Signed distance (negative = back)
distanceToSphere(sphere)         - Signed distance to sphere
projectPoint(point, target)      - Orthogonal projection
intersectLine(line, target)      - Line-plane intersection

coplanarPoint() 方法 src/math/Plane.js187-191 通过将法线乘以 -constant 返回平面上的一个点。

Frustum

Frustum 表示视锥体,作为六个 Plane 对象存储在 planes 数组 src/math/Frustum.js23-30 中。规范平面顺序为:right、left、bottom、top、near、far。

构造:

setFromProjectionMatrix(m, coordinateSystem)

这从投影矩阵 src/math/Frustum.js44-124 中提取六个视锥体平面,并对 WebGL 和 WebGPU 坐标系统进行特殊处理。

剔除测试:

intersectsObject(object)         - Object3D visibility
intersectsSprite(sprite)         - Sprite visibility
intersectsSphere(sphere)         - Sphere-frustum intersection
intersectsBox(box)               - Box-frustum intersection
containsPoint(point)             - Point containment

intersectsObject() 方法 src/math/Frustum.js126-165 首先测试包围球,然后可选择执行更精确的盒子测试。

Triangle

Triangle 表示具有三个 Vector3 角点 (a, b, c) 的几何三角形。它为整个库中使用的三角形操作提供静态实用方法。

静态实用方法:

MethodPurpose
getNormal(a, b, c, target)Compute face normal
getBarycoord(point, a, b, c, target)Barycentric coordinates
containsPoint(point, a, b, c)Point-in-triangle test
getInterpolation(point, p1, p2, p3, v1, v2, v3, target)Barycentric interpolation
getInterpolatedAttribute(attr, i1, i2, i3, barycoord, target)Attribute interpolation
isFrontFacing(a, b, c, direction)Backface culling test

这些静态方法被光线投射 src/objects/Mesh.js440-493 使用,用于计算相交细节,包括 UV 坐标、法线和面索引。

实例方法:

getArea()                    - Triangle area (half cross product magnitude)
getMidpoint(target)          - Centroid
getPlane(target)             - Plane containing triangle
closestPointToPoint(p, target) - Nearest point on triangle

集成模式

Object3D 变换管线

SVG
100%

Object3D 保持同步的欧拉角和四元数表示 src/core/Object3D.js100-200。当 rotation 被修改时,quaternion 通过回调自动更新,反之亦然。matrixupdateMatrix() 期间从 position、quaternion 和 scale 重新计算。

光线投射集成

SVG
100%

光线投射系统使用多阶段剔除方法 src/objects/Mesh.js226-270:

  1. 包围球测试 在世界空间 src/objects/Mesh.js236-251
  2. 包围盒测试 在局部空间 src/objects/Mesh.js260-264
  3. 逐三角形相交 使用 Möller-Trumbore src/math/Ray.js234-315

内存管理模式

所有数学基元类都遵循一致的内存管理模式以最小化分配:

输出参数模式:

// BAD: Creates new object on each call
const center = box.getCenter();

// GOOD: Reuses existing object
const center = new Vector3();
box.getCenter(center);

计算派生值的方法接受用于输出的 target 参数 src/math/Box3.js219-222。这可以在动画循环等性能关键路径中实现无分配操作。

单例重用模式:

// Module-level reusable instances
const _vector = /*@__PURE__*/ new Vector3();
const _matrix = /*@__PURE__*/ new Matrix4();

内部实现使用模块作用域的临时对象 src/math/Vector3.js1256-1257 进行中间计算,避免方法内的重复分配。