喜欢这个网站http://www.gsmlondon.ac.uk/global-oil-map/
我想点击此标记,让此标记转到屏幕中心。 现在知道标记纬度和经度,点击后如何转动?我不明白。
答案 0 :(得分:0)
有趣的问题,我尝试了Matrix以获得正确的方向,但结果有点奇怪。我选择使用球面坐标系统的另一种方法,它现在可以使用。
我们需要得到两个点坐标,一个是球面上最接近相机的点我们注意到它是 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
});
}
}
最后,我使用动画库来使旋转平滑。
以下是我的演示:rotate the earth。
我取得了一些进展,之前的版本有点偏差。当我在地球上下来时,我得到了一个糟糕的结果。我认为代码sphere.rotation.x += delta_pitch
使球体在对象轴上旋转。但我们需要的是让球体在世界空间轴上旋转。我们知道世界轴坐标总是x_axis = (1,0,0) ; y_axis = (0,1,0) ; z_axis = (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);
以下是我的新演示:rotate earth new version。