Threejs 坐标定义

局部坐标和世界坐标

局部坐标(Local Coordinates)

局部坐标是相对于对象自身的坐标系。每个对象都有自己的局部坐标系,其中原点位于对象的中心,轴通常是沿着对象的主要方向(例如,X轴、Y轴、Z轴)。

局部原点:对象的原点。
轴方向:通常与对象的方向有关。
在局部坐标系中,变换(如平移、旋转和缩放)是相对于对象自身进行的。

世界坐标(World Coordinates)

世界坐标是相对于整个场景的全局坐标系。世界坐标系是场景的参考坐标系,其中原点通常是场景的中心,轴方向是固定的(例如,X轴向右,Y轴向上,Z轴向前或向后)。

世界原点:场景的中心点。
轴方向:通常是固定的,X、Y、Z轴。
父子对象中的坐标关系

父子对象关系

在Three.js中,父对象和子对象之间形成了层次结构。子对象的变换是相对于其父对象的局部坐标系进行的。这意味着:

子对象继承父对象的变换:父对象的变换(位置、旋转、缩放)会影响子对象的最终位置。
变换叠加:子对象的变换会叠加到父对象的变换上。

局部坐标与世界坐标的转换

从局部坐标转换为世界坐标

将一个对象的局部坐标转换为世界坐标需要考虑所有父对象的变换。Three.js提供了localToWorld方法来进行这种转换。

const localPosition = new THREE.Vector3(1, 0, 0);
const worldPosition = object.localToWorld(localPosition.clone());
console.log('World Position:', worldPosition);

在上面的代码中,localPosition是相对于对象的局部坐标,通过localToWorld方法转换成了世界坐标worldPosition。

从世界坐标转换为局部坐标

将世界坐标转换为对象的局部坐标可以使用worldToLocal方法。这个过程需要考虑从世界坐标系到对象局部坐标系的逆变换。

const worldPosition = new THREE.Vector3(10, 0, 0);
const localPosition = object.worldToLocal(worldPosition.clone());
console.log('Local Position:', localPosition);

在这个例子中,worldPosition是世界坐标,通过worldToLocal方法转换为localPosition,即相对于对象的局部坐标。

实际应用示例

1. 父子对象关系

假设我们有一个父对象和一个子对象,父对象在世界坐标系中的位置是(5, 5, 5),子对象在父对象局部坐标系中的位置是(2, 0, 0)。

// 创建父对象
const parentObject = new THREE.Object3D();
parentObject.position.set(5, 5, 5); // 设置父对象的位置

// 创建子对象
const childGeometry = new THREE.BoxGeometry(1, 1, 1);
const childMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const childObject = new THREE.Mesh(childGeometry, childMaterial);
childObject.position.set(2, 0, 0); // 相对于父对象的局部位置

// 添加子对象到父对象
parentObject.add(childObject);

// 添加父对象到场景
scene.add(parentObject);

在这个示例中,子对象的最终世界坐标是父对象位置和子对象位置的和,即(7, 5, 5)。

2. 转换子对象的世界坐标

如果我们想将子对象从世界坐标移动到新的父对象,同时保持其世界坐标不变,我们可以进行如下操作:

复制代码
// 获取子对象的当前世界位置
const currentWorldPosition = new THREE.Vector3();
childObject.getWorldPosition(currentWorldPosition);

// 创建一个新的父对象
const newParentObject = new THREE.Object3D();
newParentObject.position.set(10, 10, 10); // 新父对象的位置

// 将子对象添加到新的父对象
newParentObject.add(childObject);

// 将新的父对象添加到场景
scene.add(newParentObject);

// 将世界坐标转换为新的局部坐标
const newLocalPosition = newParentObject.worldToLocal(currentWorldPosition.clone());

// 更新子对象的局部坐标
childObject.position.copy(newLocalPosition);

在这个示例中,我们将子对象从一个父对象移到另一个父对象,并保持其在世界坐标中的位置不变。

3. 动态更新对象的局部和世界坐标

有时候,我们需要动态更新对象的位置和变换。这可以通过手动调整局部坐标来实现,以便于保持其在世界坐标系中的预期位置。

复制代码
// 动态调整子对象的位置
const newWorldPosition = new THREE.Vector3(20, 20, 20); // 目标世界位置

// 将世界坐标转换为新的局部坐标
const newLocalPosition = parentObject.worldToLocal(newWorldPosition.clone());

// 更新子对象的局部位置
childObject.position.copy(newLocalPosition);

在这个示例中,子对象被动态调整到目标世界位置newWorldPosition。

4. 检查和调试坐标变换

为了调试和确认对象的变换是否正确,可以打印对象的局部和世界坐标来检查。

复制代码
// 获取局部坐标
console.log('Local Position:', childObject.position);

// 获取世界坐标
const worldPosition = new THREE.Vector3();
childObject.getWorldPosition(worldPosition);
console.log('World Position:', worldPosition);

// 获取局部变换矩阵
console.log('Local Matrix:', childObject.matrix);

// 获取世界变换矩阵
console.log('World Matrix:', childObject.matrixWorld);

通过这些日志信息,可以方便地检查和验证对象的变换是否符合预期。

总结

  • 局部坐标:相对于对象自身的坐标系,用于定义对象的局部位置、旋转和缩放。
  • 世界坐标:相对于场景的全局坐标系,表示对象在整个场景中的位置。
  • 父子对象:子对象的变换是相对于其父对象的局部坐标系进行的,父对象的变换会影响到所有子对象。
  • 坐标转换:使用localToWorld和worldToLocal方法在局部和世界坐标之间进行转换,以满足复杂场景需求。
  • 8
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

熠熠仔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值