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 的世界位置被"抵消掉",回到原点
相关推荐
Kagol41 分钟前
TinyVue 支持 Skills 啦!现在你可以让 AI 使用 TinyVue 组件搭建项目
前端·agent·ai编程
柳杉43 分钟前
从零打造 AI 全球趋势监测大屏
前端·javascript·aigc
simple_lau44 分钟前
Cursor配置MasterGo MCP:一键读取设计稿生成高还原度前端代码
前端·javascript·vue.js
睡不着先生1 小时前
如何设计一个真正可扩展的表单生成器?
前端·javascript·vue.js
天蓝色的鱼鱼1 小时前
模块化与组件化:90%的前端开发者都没搞懂的本质区别
前端·架构·代码规范
明君879971 小时前
Flutter 如何给图片添加多行文字水印
前端·flutter
leolee181 小时前
Redux Toolkit 实战使用指南
前端·react.js·redux
bluceli2 小时前
React Hooks最佳实践:写出优雅高效的组件代码
前端·react.js
IT_陈寒2 小时前
JavaScript代码效率提升50%?这5个优化技巧你必须知道!
前端·人工智能·后端
IT_陈寒2 小时前
Java开发必知的5个性能优化黑科技,提升50%效率不是梦!
前端·人工智能·后端