首页 / three.js / API 文档
Vector3
先看结论
三维向量,同时用作点的坐标、方向与法线,是场景里出现频率最高的数据类型。
new THREE.Vector3(x, y, z) → Vector3
构造参数
| 参数 | 默认 | 说明 |
|---|---|---|
x | 0 | 横向分量 |
y | 0 | 纵向分量,three.js 默认 Y 轴朝上 |
z | 0 | 前后分量,朝向观察者一侧为正 |
属性
| 属性 | 说明 |
|---|---|
x / y / z | 三个分量,可直接读写 |
isVector3 | 只读标记,用于类型判断 |
常用方法
| 方法 | 说明 |
|---|---|
set(x, y, z) | 就地赋值,返回自身,可链式调用 |
copy(v) / clone() | 前者就地复制,后者返回新对象 |
add(v) / addVectors(a, b) | 相加;带 Vectors 后缀的版本不消耗中间对象 |
sub(v) / subVectors(a, b) | 相减,常用于求两点间的方向 |
multiplyScalar(s) | 按标量缩放 |
dot(v) / cross(v) | 点积与叉积,叉积会就地改写自身 |
length() / lengthSq() / normalize() | 模长、模长平方、单位化 |
distanceTo(v) / distanceToSquared(v) | 两点距离;只做比较时用平方版本省一次开方 |
lerp(v, t) / lerpVectors(a, b, t) | 线性插值,t 取 0 到 1 |
applyMatrix4(m) | 乘 4×4 矩阵,含平移 |
applyQuaternion(q) / applyAxisAngle(axis, angle) | 按四元数或绕轴旋转 |
project(camera) / unproject(camera) | 世界坐标与裁剪空间坐标互转,结果为归一化设备坐标 |
setFromMatrixPosition(m) | 取矩阵的平移分量 |
setFromSphericalCoords(r, phi, theta) | 球坐标转直角坐标,phi 从 +Y 轴起算,theta 绕 Y 轴 |
fromArray(arr, offset) / toArray(arr, offset) | 与 Float32Array 互转,写几何体属性时使用 |
equals(v) | 逐分量比较,浮点误差不会自动容差 |
基本用法
const a = new THREE.Vector3(1, 2, 3);
const b = new THREE.Vector3(4, 0, -2);
// 中点
const mid = new THREE.Vector3().addVectors(a, b).multiplyScalar(0.5);
// 方位与距离
const offset = new THREE.Vector3().subVectors(b, a);
const dist = offset.length();
const dir = offset.normalize(); // 注意:normalize 会改写 offset
mesh.position.copy(mid);
mesh.lookAt(b);
normalize()、add()、cross() 都直接改写自身并返回自身,
这是 three.js 一贯的风格。需要保留原值的场合,先 clone()。
经纬度转球面坐标
经纬度是角度,场景坐标是直角坐标,两者之间需要一次换算。 球面近似下,把经度当绕 Y 轴的方位角、纬度当从赤道起算的高度角即可:
const R = 6371000; // 地球平均半径,单位米
function lonLatToVector3(lon, lat, radius) {
const phi = THREE.MathUtils.degToRad(90 - lat);
const theta = THREE.MathUtils.degToRad(lon);
return new THREE.Vector3(
radius * Math.sin(phi) * Math.cos(theta),
radius * Math.cos(phi),
radius * Math.sin(phi) * Math.sin(theta)
);
}
const beijing = lonLatToVector3(116.39, 39.9, 1);
这段换算只解决了球面上的位置,不涉及投影带、基准面与椭球改正。 three.js 没有地理坐标系统,坐标系的原点、轴向与单位都由使用者自己定义, 并在整个项目里保持一致。
投影与拾取
// 世界坐标 → 屏幕坐标(结果 x、y 在 -1 到 1,z 为深度)
const ndc = new THREE.Vector3(12, 0, 8).project(camera);
const px = (ndc.x * 0.5 + 0.5) * canvas.clientWidth;
// 屏幕坐标 → 世界坐标:给一个 NDC 深度再反投影
const world = new THREE.Vector3(ndc.x, ndc.y, ndc.z).unproject(camera);
project 依赖相机的投影矩阵与世界矩阵,调用前要确保相机矩阵已更新,
通常在渲染之后或 camera.updateMatrixWorld() 之后取用。
单位自己定,three.js 不管。把 1 个单位当成米、十米还是一度都可以, 但一旦确定就不能混用。半径 6371000 的地球与 100 米见方的建筑放在同一场景里, 浮点精度会明显不足。
经纬志(2026)。《Vector3》。https://www.jingweizhi.com/three/api/vector3.html(访问日期 2026-11-03)。