如何在three.js中原地缩放对象(保持原有位置不变)
解决方案:球体缩放时点始终固定在表面的实现调整
问题根源
你当前的实现将点的位移直接写入了CircleGeometry的顶点数据中,对Mesh执行scale操作时,会对几何体的所有顶点坐标做等比缩放:原本位于球表面的顶点坐标(vector.x, vector.y, vector.z)缩放后会变为(vector.x * r, vector.y * r, vector.z * r),径向距离直接缩小为原来的r倍,自然会缩进球体内部。
修正逻辑
Three.js中几何体应当保留局部原点在(0,0,0),位移、旋转、缩放操作通过Mesh的实例属性控制,这样缩放只会作用于几何体本身的形状尺寸,不会影响点的空间位置。
修正后的实现代码
初始化部分
const dotGeometry = new three.CircleGeometry(2, 5) const vector = new three.Vector3() vector.setFromSphericalCoords(radius, point.phi, point.theta) // 仅调整几何体朝向,不做位移,保留局部原点在(0,0,0) dotGeometry.lookAt(vector) const dot = new three.Mesh(dotGeometry, dotMaterial) // 位移放到Mesh的position属性上,缩放操作不会修改position的值 dot.position.copy(vector) scene.add(dot)
动画部分分两种场景适配
场景1:仅缩放点的显示尺寸,球体半径固定
原有动画逻辑无需调整,缩放仅会改变点本身的大小,点的位置始终固定在球体表面:// 渲染函数中的动画逻辑 const fi = 3 * time * 0.001 const r = Math.abs(Math.asin(Math.sin(fi))) dot.scale.set(r, r, r)场景2:球体本身同步缩放,半径随r变为
原半径 * r
需要同步更新点的径向位置,保证和球体缩放后的半径匹配:// 渲染函数中的动画逻辑 const fi = 3 * time * 0.001 const r = Math.abs(Math.asin(Math.sin(fi))) dot.scale.set(r, r, r) // 同步更新点的径向长度,和球体当前半径匹配 dot.position.setLength(radius * r)
优化提示
如果需要渲染大量球面点,推荐使用InstancedMesh批量实例化渲染,避免每个点创建独立Mesh带来的性能损耗。
内容的提问来源于stack exchange,提问作者maticzav
相关产品推荐
相关产品推荐

