You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

THREE.js中如何从BoxGeometry立方体上选中指定的面?

Three.js立方体指定面选取与面球碰撞检测实现方案

1. 立方体指定面选取方法

你创建的立方体用的是BoxGeometry,可以通过以下两种方式精准定位目标面:

方案一:通过固定面索引直接获取

Three.js的BoxGeometry生成的三角面有固定的索引规则,每个立方体共12个三角面(每个矩形面由2个三角面组成),索引对应关系如下:

  • 正X面:索引0、1
  • 负X面:索引2、3
  • 正Y面:索引4、5
  • 负Y面:索引6、7
  • 正Z面:索引8、9
  • 负Z面:索引10、11
    你可以直接通过索引提取目标面的顶点数据,示例代码如下:
// 你原有的创建立方体代码
const hand1geo = new THREE.BoxGeometry(2, 0.01, 0.2);
const material_sidehand = new THREE.MeshBasicMaterial({ color: 0x3cc1b7 });
const sidehand = new THREE.Mesh(hand1geo, material_sidehand);

// 获取几何体顶点属性
const positionAttr = hand1geo.getAttribute('position');
// 示例:选取正Y面对应的两个三角面索引
const targetTriIndices = [4,5];
const faceVertices = [];
// 提取目标面顶点并转换为世界坐标
targetTriIndices.forEach(triIdx => {
  for(let i = 0; i < 3; i++) {
    const vertexIdx = triIdx * 3 + i;
    const vec = new THREE.Vector3(
      positionAttr.getX(vertexIdx),
      positionAttr.getY(vertexIdx),
      positionAttr.getZ(vertexIdx)
    );
    vec.applyMatrix4(sidehand.matrixWorld);
    faceVertices.push(vec);
  }
});
// 生成目标面对应的无限平面对象,用于后续碰撞检测
const targetPlane = new THREE.Plane().setFromCoplanarPoints(faceVertices[0], faceVertices[1], faceVertices[2]);

方案二:多材质标记目标面

如果需要可视化区分目标面,或者需要灵活切换目标面,可以给立方体6个面分配独立材质,通过材质索引定位目标面:

// 材质顺序对应:正X、负X、正Y、负Y、正Z、负Z
const cubeMaterials = [
  new THREE.MeshBasicMaterial({color: 0x3cc1b7}),
  new THREE.MeshBasicMaterial({color: 0x3cc1b7}),
  new THREE.MeshBasicMaterial({color: 0xff0000}), // 给目标面(正Y面)设置特殊颜色标记
  new THREE.MeshBasicMaterial({color: 0x3cc1b7}),
  new THREE.MeshBasicMaterial({color: 0x3cc1b7}),
  new THREE.MeshBasicMaterial({color: 0x3cc1b7}),
];
const sidehand = new THREE.Mesh(hand1geo, cubeMaterials);

2. 面与球体碰撞检测实现

拿到目标面对应的Plane对象后,结合Three.js内置的碰撞检测方法即可实现需求:

// 构造球体的碰撞体,需传入球体世界坐标下的球心和半径
const sphereCollider = new THREE.Sphere(sphereMesh.position, sphereRadius);
// 第一步:检测球体是否和目标面对应的无限平面相交
const isPlaneIntersect = sphereCollider.intersectsPlane(targetPlane);

if (isPlaneIntersect) {
  // 第二步:判断交点是否在立方体目标面的有限范围内,排除平面其他位置的误判
  const collisionPoint = new THREE.Vector3();
  targetPlane.projectPoint(sphereCollider.center, collisionPoint);
  // 碰撞点转换到立方体局部坐标
  collisionPoint.applyMatrix4(sidehand.matrixWorld.clone().invert());
  // 以正Y面为例,判断交点是否在面的矩形范围内(你的立方体参数x范围±1,z范围±0.1)
  if (Math.abs(collisionPoint.x) <= 1 && Math.abs(collisionPoint.z) <= 0.1) {
    // 此处写碰撞触发后的逻辑
    console.log('目标面与球体发生碰撞');
  }
}

面与球体示意

Surface and Ball

内容的提问来源于stack exchange,提问作者hellooooo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 05:12:01