Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Three.js接地和摄像头转动问题_Javascript_Three.js - Fatal编程技术网

Javascript Three.js接地和摄像头转动问题

Javascript Three.js接地和摄像头转动问题,javascript,three.js,Javascript,Three.js,喜欢这个网站吗 我想点击这个标记,让这个标记转到屏幕中央。 现在知道标记经纬度了,点击后怎么转?我不明白。有趣的问题,我试着让矩阵得到正确的方向,但结果有点奇怪。我选择了另一种使用球坐标系的方法,现在可以了 我们需要得到两个点坐标,一个是球面上最靠近摄像机的点,我们将其记为p(摄像机到球面中心的线与球面相交)。另一点是我们点击球面的地方,我们注意到它是Q 我们使用raycaster获得p和Q笛卡尔坐标。并将笛卡尔坐标转换为球坐标(通常描述为(r,θ,φ)) 然后,我们计算从Q到p的角位移。并将位

喜欢这个网站吗

我想点击这个标记,让这个标记转到屏幕中央。
现在知道标记经纬度了,点击后怎么转?我不明白。

有趣的问题,我试着让矩阵得到正确的方向,但结果有点奇怪。我选择了另一种使用球坐标系的方法,现在可以了

我们需要得到两个点坐标,一个是球面上最靠近摄像机的点,我们将其记为p(摄像机到球面中心的线与球面相交)。另一点是我们点击球面的地方,我们注意到它是Q

我们使用
raycaster
获得pQ笛卡尔坐标。并将笛卡尔坐标转换为球坐标(通常描述为(r,θ,φ))

然后,我们计算从Qp的角位移。并将位移作为球体旋转的补充

以下是我的片段:

    //get the point coordinates which a line from camera to sphere center intersect with the sphere 
    var vector = new THREE.Vector3().copy(sphere.position);
    vector = vector.unproject(camera);
    var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());
    var intersects = raycaster.intersectObjects([sphere],true);
    var intersected_point = new THREE.Vector3().copy(intersects[0].point);

    //calculate the intersected point spherical coordinates
    var radius = sphere.children[0].geometry.parameters.radius;
    var heading = Math.atan2(intersects[0].point.x,intersects[0].point.z);
    var pitch = Math.asin(-(intersects[0].point.y)/radius);

    document.addEventListener("click",OnDocumentClick,false);

    function OnDocumentClick(event)
    {
        //get the point coordinates which you click on the sphere surface
        var vector = new THREE.Vector3(( event.clientX / window.innerWidth ) * 2 - 1, -( event.clientY / window.innerHeight ) * 2 + 1, 0.5);
        vector = vector.unproject(camera);
        var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());
        var intersects = raycaster.intersectObjects([sphere],true);
        if(intersects.length > 0)
        {
            //get click point spherical coordinates
            var heading1 = Math.atan2(intersects[0].point.x,intersects[0].point.z);
            var pitch1 = Math.asin(-(intersects[0].point.y)/radius);
            //calculate displacement of click point to intersected point
            var delta_heading = heading - heading1;
            var delta_pitch = pitch - pitch1;
            var target_pitch = parseFloat(sphere.rotation.x) +delta_pitch;
            var target_heading = parseFloat(sphere.rotation.y) + delta_heading;

            //using an animation to rotate the sphere
            anime({
                targets:sphere.rotation,
                x:target_pitch,
                y:target_heading,
                elasticity: 0
            });
        }
    }
最后,我使用动画库使旋转平滑

这是我的演示:

我取得了一点进步,以前的版本有点不对劲。当我在地上走来走去时,我得到了一个坏结果。我认为代码
sphere.rotation.x+=delta_pitch
使球体在对象轴上旋转。但我们需要的是使球体在世界空间轴上旋转。我们知道世界坐标轴总是
x_轴=(1,0,0);y_轴=(0,1,0);z_轴=(0,0,1)
;然后,我将世界坐标转换为对象坐标,球体矩阵解释球体从恒等旋转到当前旋转。逆矩阵解释了背景词。因此,我们可以将逆矩阵应用于基本轴,以获得对象空间坐标。使球体在新轴上旋转。我只是对OnDcoumentClick函数做了一点修改:

            var heading1 = Math.atan2(intersects[0].point.x,intersects[0].point.z);
            var pitch1 = Math.asin(-(intersects[0].point.y)/radius);
            //get the sphere inverse matrix;
            var sphere_matrix = new THREE.Matrix4().copy(sphere.matrix);
            var inverse_sphere_matrix = new THREE.Matrix4();
            inverse_sphere_matrix.getInverse(sphere_matrix);
            //convert world space x and y axises to sphere object space coordinates.
            var x_axis = new THREE.Vector3(1,0,0);
            var y_axis = new THREE.Vector3(0,1,0);
            x_axis.applyMatrix4(inverse_sphere_matrix);
            y_axis.applyMatrix4(inverse_sphere_matrix);

            //calculate displacement of click point to intersected point
            var delta_heading = heading - heading1;
            var delta_pitch = pitch - pitch1;
            //make sphere rotate around whith world x and y axises.
            sphere.rotateOnAxis(x_axis,delta_pitch);
            sphere.rotateOnAxis(y_axis,delta_heading);

这是我的新演示:

谢谢,这个看起来很不错,学习了。@俊东还是有点不舒服,但比以前好多了。我认为这可能是由于准确性造成的,它要好得多。我使用OrbitControl来发现新问题。移动相机,再次单击将无法获得所需的结果。您可以移动相机。很容易找到放相机的地方。但是我不知道如何用动画平滑地翻译。我使用的是OrbitControls,无法得到我想要的结果,你能帮我吗?非常感谢。