Rotating a 3D globe to focus on a particular latitude and longitude.
Ensuring that post-rotation, the globe’s spin axis aligns with the global West-to-East direction, akin to how the real Earth rotates about its axis.
I’ve tried many times on GPT-4 and Sonnet3.5, but there is no ideal solution. The existing code is like this, but it only deals with the case where the initial globe is aligned around longitude, but if the user rolls the globe in any direction, this will not work.
rotateGlobeTo(targetLatLng, onComplete) {
// Current globe center point in lat/lng
// const currentLatLng = this.getGlobeCenterLatLng();
const initialLatLng = this.previousTargetLatLng;
// Normalize the longitude difference for the shortest path
const normalizeAngle = (angle) => {
return ((angle + 180) % 360) - 180;
};
const azimuthalAngle = normalizeAngle(targetLatLng.lng - initialLatLng.lng);
const azimuthalRotation = THREE.MathUtils.degToRad(azimuthalAngle);
// Calculate polar rotation based on latitudinal change
const polarAngle = targetLatLng.lat - initialLatLng.lat;
const polarRotation = THREE.MathUtils.degToRad(polarAngle);
// Create quaternions for each rotation
const azimuthalQuaternion = new THREE.Quaternion().setFromAxisAngle(
new THREE.Vector3(0, 1, 0), // Rotate around Y-axis for longitude
-azimuthalRotation
);
const polarQuaternion = new THREE.Quaternion().setFromAxisAngle(
new THREE.Vector3(1, 0, 0), // Rotate around X-axis for latitude
polarRotation
);
// Combine rotations: first apply polar rotation, then azimuthal
const finalRotation = polarQuaternion.multiply(azimuthalQuaternion);
this.animateRotation(finalRotation, onComplete);
}
animateRotation(finalRotation, onComplete) {
let duration = 800;
const startTime = Date.now();
const startRotation = this.earth.quaternion.clone(); // Clone the initial quaternion
const animate = () => {
const currentTime = Date.now();
const fraction = (currentTime - startTime) / duration;
if (fraction < 1) {
// Update the quaternion by interpolating between the start and the target
this.earth.quaternion
.copy(startRotation)
.slerp(finalRotation, fraction);
requestAnimationFrame(animate);
} else {
// Make sure we end precisely at the final rotation
this.earth.quaternion.copy(finalRotation);
if (typeof onComplete === "function") {
onComplete(); // Call the completion callback if provided
}
}
};
animate();
}
This is the current effect: https://ntc.playgeo.one/
Thanks