Drawing curves on WebGL Globe using THREE.js and D3
This tutorial shows how to draw curves on a WebGL Globe.
Step 1: Create an interactive 3D Globe
This is not the focus of this tutorial. There are some differences between this tutorial and the original WebGL Globe:
- Use ES6
- Use hammer.js for easier event handling
- All the meshes are added to a root mesh. Mouse drag events rotate the root mesh instead of the camera. This simplifies the logic to calculate rotations.
Step 2: Draw curve to 3D Globe
A 3D curve consists of a start and end point, and one or more middle control points. THREE.js provides two 3D curve methods: QuadraticBezierCurve3 and CubicBezierCurve3. Here we want to use CubicBezierCurve3 because it has 2 control points, meaning that we have more control on the curvature.
The input is an array of geolocations, i.e., latitude and longitude coordinates:
const coords = [
[ startLat, startLng, endLat, endLng ],
[ startLat, startLng, endLat, endLng ],
...
];
First we convert these coordinates into 3D points on the globe/sphere:
const points = [
[ start, mid1, mid2, end ],
[ start, mid1, mid2, end ],
...
];
With the start, end and 2 middle control points, we can use CubicBezierCurve3 to construct a 3D spline:
const spline = new THREE.CubicBezierCurve3(start, mid1, mid2, end);
Here is the complete logic:
Here is the diagram:
To adjust the curvature of the spline, change the position of the 2 middle control points (currently at 0.25 and 0.75 along the curve) and the logic to calculate altitude.
With this spline, you can draw a 3D curve using THREE.Geometry (or THREE.BufferGeometry) and add it to a THREE.Line. Alternately, if you want to add some thickness to the path, use THREE.TubeGeometry(or THREE.TubeBufferGeometry) and add it to a THREE.Mesh. The benefit of Buffer geometry is that you can use the setDrawRange to animate the paths.
Here is the complete source code for this tutorial on stackblitz:
Here is another example using flight route data:
https://stackblitz.com/edit/webgl-globe-2