如何在THREE.JS中获取不规则3D对象的真实中心?
THREE.js 获取不规则3D对象真实中心的解决办法
首先得明确:你用Box3().setFromObject().getCenter()得到的是**轴对齐包围盒(AABB)**的中心,这个盒子是能完全包裹物体的最小矩形框,对于不规则形状,它的中心肯定和物体本身的几何/视觉中心不一致——这就是问题所在,简单形状的包围盒中心刚好和自身中心重合,所以没毛病。
下面给你两种实用的解决办法:
1. 计算几何体的几何中心(顶点平均法)
这是最常用的方式,通过计算所有顶点的坐标平均值,得到物体的真实几何中心:
// 计算单个BufferGeometry的几何中心 function getGeometryCenter(geometry) { const center = new THREE.Vector3(); const posAttr = geometry.getAttribute('position'); let totalX = 0, totalY = 0, totalZ = 0; const vertexNum = posAttr.count; for (let i = 0; i < vertexNum; i++) { totalX += posAttr.getX(i); totalY += posAttr.getY(i); totalZ += posAttr.getZ(i); } center.set(totalX / vertexNum, totalY / vertexNum, totalZ / vertexNum); return center; } // 调用示例:假设你的不规则物体是irregularMesh const localCenter = getGeometryCenter(irregularMesh.geometry);
如果你的物体是Group(包含多个子网格),需要遍历所有子物体的几何体,累加所有顶点坐标再求平均:
// 计算Group的整体几何中心 function getGroupCenter(group) { const center = new THREE.Vector3(); let totalX = 0, totalY = 0, totalZ = 0; let totalVertices = 0; group.traverse(child => { if (child.isMesh) { const posAttr = child.geometry.getAttribute('position'); const vertexNum = posAttr.count; totalVertices += vertexNum; for (let i = 0; i < vertexNum; i++) { totalX += posAttr.getX(i); totalY += posAttr.getY(i); totalZ += posAttr.getZ(i); } } }); center.set(totalX / totalVertices, totalY / totalVertices, totalZ / totalVertices); return center; }
2. 转换到世界空间(如果物体有变换)
上面计算的是几何体本地空间的中心,如果你的物体做了旋转、缩放、平移,需要把本地中心转换到世界空间,得到场景中的真实位置:
const worldCenter = localCenter.clone(); irregularMesh.localToWorld(worldCenter);
补充说明
如果你的场景需要考虑质量中心(比如物理模拟),那得给不同区域的顶点设置权重(比如根据材质密度、面的面积)再做加权平均,但绝大多数视觉需求下,用顶点平均的几何中心就足够了。
内容的提问来源于stack exchange,提问作者Renan Bolsoni
相关产品推荐
相关产品推荐

