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

在旋转球体表面放置对象出现偏移问题求助

问题:旋转球体表面放置对象时偏移异常

每次在旋转的球体(Moon)表面放置对象,球体旋转程度越高,对象偏移越明显。尝试将对象偏移回鼠标位置但无效,不知如何解决。

放置对象的代码:

function placeObj(event) {
    if (event.button == 0) {
        switch(placeObj) {
            case null:
                Mouse.x = (event.offsetX / window.innerWidth) * 2 - 1;
                Mouse.y = -(event.offsetY / window.innerHeight) * 2 + 1;
                var Intersects = raycast(Mouse, [Moon]) // Returns the intersects

                if (Intersects.length > 0) {
                    let intersectSelect = Intersects[0];
                    let intersectObj = intersectSelect.object;
                    if (intersectObj.name == "Sphere") {
                        var fbxLoader = new FBXLoader();
                        var cube = new THREE.Mesh(
                            new THREE.BoxGeometry(0.2, 0.2, 0.02),
                            new THREE.MeshBasicMaterial(),
                        )

                        Moon.add(cube);
                        cube.position.copy(intersectSelect.point);
                        cube.lookAt(Intersects[0].face.normal);
                    }
                }
                break;
            
            default:
                break;
        }
    }
}

动画循环代码:

function animate() {
    Controls.update();
    requestAnimationFrame( animate );

    if (!stopRotation) {
        Moon.rotation.y += 0.0001;
    }

    renderer.render( Scene, camera );
}

问题现象演示:

旋转球体放置对象偏移


解决方案

问题根源:你直接使用世界空间的交点坐标intersectSelect.point设置cube位置,但cube是Moon的子对象,子对象的position属性对应父对象(Moon)的本地空间坐标。当Moon旋转时,本地空间与世界空间产生偏移,直接赋值世界坐标就会导致位置错位。

修改方法:将世界空间的交点坐标转换为Moon的本地空间坐标,再赋值给cube的position:

// 替换原代码中cube.position.copy(intersectSelect.point);这部分
const localPoint = new THREE.Vector3();
localPoint.copy(intersectSelect.point);
Moon.worldToLocal(localPoint); // 把世界坐标转成Moon的本地坐标

cube.position.copy(localPoint);

另外,cube.lookAt(Intersects[0].face.normal)也需要调整:face.normal是世界空间的法线,同样需要转换为Moon本地空间,或者直接让cube朝向Moon中心(确保表面贴合):

// 让cube背面朝向Moon中心,贴合球体表面
cube.lookAt(Moon.position);

修改后,无论Moon怎么旋转,放置的对象都会准确落在鼠标点击的球体表面位置。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 23:08:11