将鼠标单击转换为旋转球体上的经度和纬度

时间:2017-10-07 21:19:35

标签: three.js

我有一个球体,我需要将鼠标点击转换为纬度和经度

只要球体没有旋转,但是如果它有任何旋转,一切都可以正常工作 - 我得到错误的结果

这是我的代码:

var mouse = new THREE.Vector2();
mouse.x = (event.pageX / window.innerWidth) * 2 - 1;
mouse.y = -(event.pageY / window.innerHeight) * 2 + 1;

var raycaster = new THREE.Raycaster();
raycaster.setFromCamera(mouse, camera);
var intersects = raycaster.intersectObject( EarthSphere );
if (intersects.length!=1) return;

var pointOnSphere = new THREE.Vector3();    
pointOnSphere.x = intersects[0].point.x;
pointOnSphere.y = intersects[0].point.y;
pointOnSphere.z = intersects[0].point.z;

var EarthRadius = 20;
var lat = 90 - (Math.acos(pointOnSphere.y / EarthRadius)) * 180 / Math.PI;
var lon = ((90 + (Math.atan2(pointOnSphere.x , pointOnSphere.z)) * 180 / Math.PI) % 360) - 180; 

我在说我需要以某种方式操纵基于EarthSphere的pointOnSphere,任何想法?

EDITED

earth.updateMatrixWorld(真); pointOnSphere = earth.localToWorld(pointOnSphere.clone());

我认为以下内容可行:

EarthSphere.updateMatrixWorld(true);
pointOnSphere = EarthSphere.localToWorld( pointOnSphere.clone() );

但它不起作用..

1 个答案:

答案 0 :(得分:2)

three.js demo image

我认为,您必须使用.worldToLocal()而不是.localToWorld()。因此,您将在球体的局部坐标中得到一个点。

该文件说明了.worldToLocal()

更新从世界空间到本地空间的矢量。

这意味着将更新传递给此函数的向量。没有创建新的THREE.Vector3()

这两个函数都只是更新传递给它们的现有向量。

var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var intersects;
var pointOfIntersection = new THREE.Vector3();
var localPoint = new THREE.Vector3();
var spherical = new THREE.Spherical();
var lat, lon;

window.addEventListener("mousedown", sphereClick, false);

function sphereClick(event) {
  mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
  mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
  raycaster.setFromCamera(mouse, camera);
  intersects = raycaster.intersectObjects([sphere]);
  if (intersects.length == 0) return;
  pointOfIntersection = intersects[0].point;
  sphere.worldToLocal(localPoint.copy(pointOfIntersection));  // that's how it works with translation from the world coordinate system to the local one 
  createPoint(localPoint);
}

function createPoint(position) {
  var point = new THREE.Mesh(new THREE.SphereGeometry(0.0625, 16, 12), new THREE.MeshBasicMaterial({
    color: 0x777777 + Math.random() * 0x777777
  }));
  point.position.copy(position);
  sphere.add(point);
  var color = point.material.color.getHexString();

  // three.js already has useful object to get polar coordinates from the given vector - 'position', which is in local coordinates already 
  spherical.setFromVector3(position);
  lat = THREE.Math.radToDeg(Math.PI / 2 - spherical.phi);
  lon = THREE.Math.radToDeg(spherical.theta);

  pointList.innerHTML += "<span style='color:#" + color + "'>lat: " + lat + ";  lon: " + lon + "</span><br>";
}

jsfiddle示例r87。