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 的世界位置被"抵消掉",回到原点
相关推荐
可达鸭小栈15 小时前
易语言实现CSS像素文字生成器:无需字体文件渲染汉字
前端·css
fox_lht15 小时前
DBeaver的LightGrid 类所有函数详细分析
前端
钛态15 小时前
前端TypeScript高级技巧:让你的代码更安全
前端·vue·react·web
光影少年15 小时前
前端在页面渲染优化和组件优化经验?
前端·vue.js·react.js·前端框架
yqcoder16 小时前
CSS 迷思破解:`:nth-child` vs `:nth-of-type`
前端·css
时寒的笔记16 小时前
某陆飞11期_webpack案例
前端·webpack·node.js
漫游的渔夫16 小时前
前端开发者做多步 Agent:别让 AI 边想边乱跑,用 Plan-Act-Observe 稳住 4 步任务
前端·人工智能·typescript
一锤捌拾16 小时前
V8引擎精品漫游指南--Ignition篇(下 一) 动态执行前的事情
前端·javascript
遇见~未来17 小时前
第六篇_CSS进阶_深入浏览器与工程化
前端·css·rust
Cache技术分享17 小时前
397. Java 文件操作基础 - 创建常规文件与临时文件
前端·后端