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