0

Google's WebGL Globe allow placing markes at a specific lat long. But how can we get the lat long value of point currently at front or at center of screen. May be using camera position or rotation value.

We can use below code to find position on globe from lat long values:

var phi = (90 - lat) * Math.PI / 180;
var theta = (180 - lng) * Math.PI / 180;
point.position.x = 200 * Math.sin(phi) * Math.cos(theta);
point.position.y = 200 * Math.cos(phi);
point.position.z = 200 * Math.sin(phi) * Math.sin(theta);
jcaron
  • 17,302
  • 6
  • 32
  • 46
XIMRX
  • 2,130
  • 3
  • 29
  • 60
  • Read about [`THREE.Spherical()`](https://threejs.org/docs/index.html#api/math/Spherical) and its `.setFromVector3()` method. – prisoner849 Jan 14 '18 at 00:43
  • You should be able to use raycadting to get an intersection in Cartesian coordinates, then subtract the position of the globe from the intersection point, then convert this Cartesian vector to a latitude and longitude using trig or one of the built in functions. I think there's a .toPolar or something built into Vector class – OtterFamily Jan 14 '18 at 11:21

2 Answers2

0

As far as I can see there’s no direct way to get it. I see two options:

  • you can either modify globe.js to “export” the rotation object: add the following at the end of globe.js, just after this.scene = scene;:

    this.rotation = rotation;
    
  • or, if you prefer not to modify globe.js, you can use the scene property, find the camera in there, and use its position the find the latitude and longitude. There may be an easier way using the scene directly, not quite sure.

Note that globe uses three.js, so you can use that in any searches.

jcaron
  • 17,302
  • 6
  • 32
  • 46
0

The other way is to use THREE.Spherical():

phi.innerHTML = "0";
theta.innerHTML = "0";

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 0, 10);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

var controls = new THREE.OrbitControls(camera, renderer.domElement);

var sphere = new THREE.Mesh(new THREE.SphereGeometry(2.5, 16, 12), new THREE.MeshBasicMaterial({color: "maroon", wireframe: true}));
scene.add(sphere);

renderer.domElement.addEventListener("mousedown", onMouseDown, false);

var center = new THREE.Vector2(); // default is [0.0], the center of the screen
var raycaster = new THREE.Raycaster();
var point = new THREE.Vector3();
var spherical = new THREE.Spherical();
var intersect;

function onMouseDown(event) {
  raycaster.setFromCamera(center, camera);
  intersect = raycaster.intersectObject(sphere);
  if (intersect.length === 0) return;
  
  sphere.worldToLocal(point.copy(intersect[0].point));
  spherical.setFromVector3(point);
  phi.innerHTML = THREE. Math.radToDeg(Math.PI * .5 - spherical.phi);
  theta.innerHTML = THREE.Math.radToDeg(spherical.theta);
  
  let marker = new THREE.Mesh(new THREE.BoxGeometry(.125, .125, .125), new THREE.MeshBasicMaterial({
    color: Math.random() * 0xffffff,
    wireframe: true
  }));
  marker.position.copy(intersect[0].point);
  scene.add(marker);

}


render();

function render() {
  requestAnimationFrame(render);
  renderer.render(scene, camera);
}
body {
  overflow: hidden;
  margin: 0;
}
#data{
  font-family: Monotype;
  color: white;
  position: absolute;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<div id="data">
phi: <span id="phi"></span>&deg;<br>
theta: <span id="theta"></span>&deg;
</div>
prisoner849
  • 16,894
  • 4
  • 34
  • 68