Three.js 坐标系完全入门:从“你在哪”到“你爸在哪”都讲清楚了

当你打开 Three.js 写 3D 场景时,第一个要搞懂的问题就是:

一个物体到底摆在哪里?

别小看这个问题。你觉得一个立方体在世界坐标 (3,0,0),结果它移动后出现在奇怪的位置,十次里有九次是因为------

👉 你忘了它有个"爸爸"。

今天我们就用一个超通俗的方式,把 Three.js 的坐标讲清楚。看完这篇文章,你会明白:

  • 世界坐标(World Coordinates)和本地坐标(Local Coordinates)到底怎么回事?
    • 世界坐标,基准点为固定原点(0,0,0),描述物体在整个场景中的绝对位置
    • 局部/本地坐标,基准点为物体自身的几何中心(中心点),描述子物体相对于父物体的位置
  • 子对象相对于父对象的坐标是怎么计算的?
  • 为什么把 cube 放进 parentCube 后,位置就"变了"?
  • 实战代码是如何运行的?

准备好了吗?开始!


🧱 1. 世界坐标:整个世界的"绝对地址"

在 Three.js 中,有一个你永远逃不掉的概念:

世界坐标(World Coordinates)就是所有物体的绝对位置。

比如:

js 复制代码
cube.position.set(3, 0, 0);
scene.add(cube);

意思很简单:

cube 在世界的 x=3 的位置。

就像你告诉朋友:"我在北京"。

无论你爸在哪,你都在北京。

👨‍👦 2. 本地坐标:相对于"父元素"的位置

但如果你写了:

js 复制代码
const parentCube = new THREE.Mesh(geometry, parentMaterial);
parentCube.add(cube);

事情就不一样了。

cube 就有了一个"爸爸" parentCube。

此时你再写:

js 复制代码
cube.position.set(3, 0, 0);
scene.add(parentCube);

这句话就变成:

cube 在 parentCube 的局部空间中,相对于父物体,往 x 正方向移动 3。

也就是说:

  • parentCube 就像一个坐标参照系
  • cube 相当于在这个内部空间里移动。

这就好比你说:

"我离我爸三米远。"

但你爸在北京,你也就实际上还是在北京附近

⚙️ 3. 回到你的示例:它到底发生了什么?

你写的代码如下:

js 复制代码
const cube = new THREE.Mesh(geometry, material);

const parentCube = new THREE.Mesh(geometry, parentMaterial);
parentCube.add(cube);
parentCube.position.set(-3, 0, 0);

// cube.position.x = 1;
// cube 的坐标是相对于 parentCube 的,所以在页面上可以看到 cube 相对于 parentCube(父元素)向右移动到了原点坐标处
cube.position.set(3, 0, 0);

让我们逐步理解发生了什么。

🟦 第一步:parentCube 放在世界坐标 (-3,0,0)

这意味着:

"爸爸站在世界左边 3 单位的位置。"

🟦 第二步:cube 相对"爸爸"往右移动 3 个单位

cube.position.set(3,0,0) 的意思是:

cube 在父对象内部向右移动 3。

也就是说:

👉 cube 的世界坐标 = 父对象世界坐标 + 自己的本地坐标

计算一下:

  • 父对象在世界: (-3, 0, 0)
  • cube 在本地: (+3, 0, 0)

所以 cube 在世界中的真实位置:

js 复制代码
世界位置 = (-3) + 3 = 0

------刚好回到了世界原点!🎯

这就是你看到:

cube "看起来回到了原点"。

🎯 4. 一个超形象的比喻:三.js 坐标 = 现实世界的"你"和"你爸"

  • 世界坐标:你住在北京就是北京,这是全世界都懂的绝对坐标。
  • 本地坐标:你说"我离我爸三米远",那你得先知道你爸在哪。
  • 父对象移动时,子对象跟着被整体移动:因为你爸挪窝了,你当然也跟着挪了。

这就是 parent.add(child) 的意义:

你把 child 的命运交给了 parent。


🧪 5. 实战代码:一眼看懂坐标关系

完整例子如下:

js 复制代码
// 父立方体
const parentCube = new THREE.Mesh(geometry, parentMaterial);
scene.add(parentCube);
parentCube.position.set(-3, 0, 0);

// 子立方体
const cube = new THREE.Mesh(geometry, material);
parentCube.add(cube);

// cube 不是在世界坐标移动,而是在父坐标系中移动
cube.position.set(3, 0, 0);

运行后你会看到:

  • parentCube 在世界左边 (-3,0,0)
  • cube 在 parentCube 内部向右移动 3( cube 的参考点变成了 parentCube)
  • 所以 cube 的世界位置被"抵消掉",回到原点
相关推荐
Carry34510 分钟前
不清楚的 .gitignore
前端·git
张鑫旭16 分钟前
AI时代2025年下半年学的这些Web前端特性有没有用?
前端·ai编程
pinkQQx17 分钟前
H5唤醒APP技术方案入门级介绍
前端
Lefan20 分钟前
UniApp 隐私合规神器!一键搞定应用市场审核难题 - lf-auth 隐私合规助手
前端
Null15521 分钟前
浏览器唤起桌面端应用(进阶篇)
前端·浏览器
Jing_Rainbow23 分钟前
【Vue-2/Lesson62(2025-12-10)】模块化与 Node.js HTTP 服务器开发详解🧩
前端·vue.js·node.js
风度前端1 小时前
用了都说好的 uniapp 路由框架
前端
冴羽1 小时前
2026 年 Web 前端开发的 8 个趋势!
前端·javascript·vue.js
码银1 小时前
ruoyi的前端(vue)新增的时候给字典设置默认值 但不能正常
前端
凌览2 小时前
别再死磕 Nginx!http-proxy-middleware 低配置起飞
前端·后端