2017-10-07 6 views
2

J'ai une sphère et je dois convertir un clic de souris à la latitude et la longitudeConvert clic de souris pour la latitude et la longitude sur la sphère pivotée

Tout fonctionne bien tant que la sphère ayant pas de rotation, mais si elle a une rotation - Je reçois des résultats erronés

Voici mon code:

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; 

Je Güssing que je dois manipuler en quelque sorte le pointOnSphere basé sur Earthsphere, des idées?

EDITED

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

Je pensais que quelque chose comme ce qui suit fonctionnerait:

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

Mais il ne fonctionne pas ..

+0

Avez-vous une matrice de rotation? – Rabbid76

+0

EarthSphere est un maillage, donc EarthSphere.matrix? – user1732451

Répondre

2

enter image description here

Je pense, vous devez utiliser .woldToLocal() plutôt que .localToWorld(). Ainsi, vous obtiendrez un point dans les coordonnées locales de votre sphère.

Le documetation dit à propos .worldToLocal():

mises à jour le vecteur de l'espace mondial à l'espace local.

Ce qui signifie que le vecteur transmis à cette fonction sera mis à jour. Aucune création d'un nouveau THREE.Vector3().

Ces deux fonctions mettent simplement à jour un vecteur existant que vous leur passez.

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 exemple r87.

+0

parfait! Merci – user1732451