Rotate globe using lat/long values

Hi, I’m using the three-globe library to create an earth. I have things orbiting around the earth, and I want to position the globe towards the camera based on it’s current lat/lng position on page render. I’ve tried everything under the sun to try to convert the lat/lng to x,y,z coordinates, but they never land on the correct place.

I’ve tried this:

const p = POLAR_2_CARTESIAN( my.latitude, my.longitude, my.altitude / EARTH_RADIUS_KM, Globe.getGlobeRadius() );
Globe.rotation.x = p.x;
Globe.rotation.y = p.y;
Globe.rotation.z = p.z;

and this:

Globe.setRotationFromEuler( new THREE.Euler( lat, lng, z, 'YXZ' ) );

And plenty of other variations. Any tips or solutions are greatly appreciated.

/cc

Hi, yes this is also my post, but I got no answer on stackoverflow so I thought I’d try my luck in this forum instead

function spericalCoordsToCartesianCoords(r, long, lat){

   //lat from -PI/2 (southpole) to +PI/2 (northpole), 0 is equator
   //long from -PI to PI, 0 is greenwich

   const x = r * cos(lat) * cos(long);
   const y = r * cos(lat) * sin(long);
   const z = r * sin(lat);

   return {x, y, z};
}

If you use the earth’s tilt to the ecliptic, I recommend working in the local coordinate system of the earth.

Thank you for the answer! I tried your suggestion but alas, it didn’t work. I think perhaps I’m setting the values wrong on the globe?

Here is what I tried:

var paris = {
     lat: 48.864716,
     lon: 2.349014
};
var parisPosition = spericalCoordsToCartesianCoords(
	Globe.getGlobeRadius(),
	paris.lat,
	paris.lon
);

Globe.rotation.x = parisPosition.x;
Globe.rotation.y = parisPosition.y;
Globe.rotation.z = parisPosition.z;

This centeres the globe in the middle of Russia

Try to rotate globe’s geometry: geometry.rotateY(Math.PI * 0.5)

You have to pass radians instead of degrees. But if you prefer to pass degrees then you have to convert them to radians.

function spericalCoordsToCartesianCoords(r, long, lat){

   //deg to rad
   const rad = Math.PI / 180;

   //lat from -90 (S) to +90 (N), 0 is equator
   //long from -180 (W) to +180 (E), 0 is greenwich

   const x = r * cos(lat * rad) * cos(long * rad);
   const y = r * cos(lat * rad) * sin(long * rad);
   const z = r * sin(lat * rad);

   return {x, y, z};
}

I see, thank you for clarifying! I’m pretty new at this. I tried this:

function spericalCoordsToCartesianCoords ( r, lat, long ) {
	const x = r * Math.cos( lat ) * Math.cos( long );
	const y = r * Math.cos( lat ) * Math.sin( long );
	const z = r * Math.sin( lat );

	return { x, y, z };
}

//paris
var paris = {
	lat: 48.864716,
	lon: 2.349014
};

var parisPosition = spericalCoordsToCartesianCoords(
	Globe.getGlobeRadius(),
	degreesToRadians( paris.lat ), // degreesToRadians from 'satellite.js';
	degreesToRadians( paris.lon ) // degreesToRadians from 'satellite.js';
);

Globe.rotation.x = parisPosition.x;
Globe.rotation.y = parisPosition.y;
Globe.rotation.z = parisPosition.z;

This puts the globe centering africa (upsidedown)

using

Globe.rotateY( Math.PI * 0.5 );

After puts it closer to central america.

The topic reminds me about another one: Azimuth, polar and radius from xyz - #7 by prisoner849

Yes, I just read it, that’s where my paris coords came from. unfortunately the example did not help my case. As I dont need to place an object at a certain lat/lang, I need to twist the globe to center the lat lang towards the camera.

Ah, I have to correct my answer.

Our convention is a.) and not b.) This means z and y must be swapped.

function spericalCoordsToCartesianCoords(r, long, lat){

   //lat from -PI/2 (S) to +PI/2 (N), 0 is equator
   //long from -PI (W) to PI (E), 0 is greenwich

   const x = r * cos(lat) * cos(long);
   const y = r * sin(lat);
   const z = r * cos(lat) * sin(long);

   return {x, y, z};
}

Depending on which axis you prefer as the reference axis x or z, you also have to swap x and z. The important thing is the y-axis is the vertical axis. In fact, I think this is the better convention. I have no idea why z is so often chosen as the vertical in mathematics. In an xy diagram, y is always the vertical. If you then go into the third dimension, it makes sense to leave the x and y axes and use the z axis for the plane.

In this case, greenwich is on the x-axis, if you swap x and z, greenwich is on the z-axis

I tested switching to this, but the globe faced Australia. It’s wierd, when I don’t touch the rotation it does seem to start at the correct value like this: https://www.geographyrealm.com/wp-content/uploads/2015/09/prime-meridian-equator-world-map.jpg

But somehow the number dont translate to the earth rotation.

The reason for this will lie here.

Globe.rotation.x = parisPosition.x;
Globe.rotation.y = parisPosition.y;
Globe.rotation.z = parisPosition.z;

You address positions to a rotation. Try (2*Math.PI) to “Globe.rotation.y = 2 * Math.PI;” then nothing should be different than if you used 0 because you did a 360° rotation.

If your globe is at the origin and you address the x,y,z positions to the camera (but then with a larger radius) plus the distance you want in addition to the radius and the camera with camera.lookAt(0, 0, 0); always look at the origin you should see what you hope to see.

You can also rotate the globe directly with long and lat, but you have to do it differently. To do this you have to make the globe to a subobject of a nullObject (Object3D). You then rotate the nullObject around the global x-axis (lat) and the globe around its local y-axis (long). The camera must then remain on the z-axis.

let pivot = new THREE.Object3D(); 
pivot.add("yourGlobeObject");
pivot.rotation.x = lat; //radians
yourGlobeObject.rotation.y = long; //radians

I’m not sure why this discussion is so long. Most likely I misunderstand the problem.

The way I understand it, it all depends on the orientations of the global coordinate system and the globe. Here is a demo, click on the buttons to turn the corresponding city towards the camera (see lines 64-69). The snapshot is for Paris:

https://codepen.io/boytchev/full/JjwVGVz

image

3 Likes

This is exactly what I need! I tried implementing what you made into mine, but then it didn’t work. It seems because I’m using three-globe instead of a sphere it messes something up.

I’m looking at this file:https://github.com/vasturiano/three-globe/blob/e94eb9d7f54ae27ee857258a4cc61cc6d8f73022/src/layers/globe.js#L4
Trying to find out what it could be and how I could fix it. What a hassle. If any of you have any suggestions, it would be most appreciated!

As I said:

Here is a version with three-globe. The command for rotation is different, because the orientation is different (snapshot showing Tokyo, rotation is in lines 49-54):

https://codepen.io/boytchev/full/NWemgaJ

image

Good luck with your project.

5 Likes

It worked!! Thank you so much for all your help, I’m so grateful!

1 Like