# What is Spherical Linear Interpolation for Long Hops? A Deep Dive into SLERP for Geospatial Visualization

> Learn what spherical linear interpolation SLERP is and how it creates smooth, realistic animation paths for long distance hops in geospatial visualization. Understand its application for intercontinental flights.

- Repository: [mahlernim/google-timeline-visualizer](https://github.com/mahlernim/google-timeline-visualizer)
- Tags: deep-dive
- Published: 2026-08-22

---

**Spherical linear interpolation (SLERP) is a mathematical technique used to smoothly interpolate between two points on the surface of a sphere along a great-circle arc, ensuring realistic animation paths for long-distance hops like intercontinental flights.**

In the `mahlernim/google-timeline-visualizer` repository, SLERP solves a critical visualization problem: when animating a trip between distant cities, drawing a straight line through the Earth's interior looks incorrect. Instead, the `interpolate_latlon` function calculates positions along the actual great-circle route an aircraft would follow, creating smooth camera movements that respect the Earth's curvature.

## How SLERP Works in [`visualizer.py`](https://github.com/mahlernim/google-timeline-visualizer/blob/main/visualizer.py)

The implementation resides in [`visualizer.py`](https://github.com/mahlernim/google-timeline-visualizer/blob/main/visualizer.py) at lines 111-129. The `interpolate_latlon` function converts geographic coordinates into 3-D unit vectors, computes the angular displacement between them, and blends the positions using trigonometric weights.

### Converting Lat/Lon to Unit Vectors

The algorithm first transforms latitude and longitude into Cartesian coordinates on a unit sphere. This conversion allows standard vector mathematics to operate on spherical positions:

```python
ax, ay, az = cos(lat1) * cos(lon1), cos(lat1) * sin(lon1), sin(lat1)
bx, by, bz = cos(lat2) * cos(lon2), cos(lat2) * sin(lon2), sin(lat2)

```

These unit vectors represent the start and end points as positions in 3-D space, enabling the calculation of the shortest path along the sphere's surface.

### Computing the Interpolation Weights

The core of SLERP involves calculating the angle `omega` between the two vectors using the dot product. The code clamps this value to `[-1.0, 1.0]` to prevent numerical errors when calling `acos`:

```python
dot = max(-1.0, min(1.0, ax*bx + ay*by + az*bz))
omega = acos(dot)

```

For a given fraction `f` between 0 and 1, the function determines weights. If the points are nearly identical (`sin(omega) < 1e-8`), it falls back to linear interpolation to avoid division by zero. Otherwise, it applies the classic SLERP formula:

```python
left  = sin((1 - f) * omega) / sin(omega)
right = sin(f * omega) / sin(omega)

```

### Blending and Conversion Back to Coordinates

The weighted vectors are combined and converted back to latitude and longitude using `atan2`. This step yields the exact position on the great-circle arc:

```python
x = left*ax + right*bx
y = left*ay + right*by
z = left*az + right*bz
lat = degrees(atan2(z, sqrt(x*x + y*y)))
lon = degrees(atan2(y, x))

```

## Integration with the Animation Pipeline

The `interpolate_latlon` function serves as the geometric engine for the visualizer's camera system. Two additional functions leverage this routine to build smooth trajectories:

**`position_at_distance`** (lines 32-44) calls `interpolate_latlon` to place the camera at specific distances along a route. This ensures that as the animation progresses, the camera follows the true spherical path rather than cutting through the globe.

**`build_camera_track`** (lines 80-89) indirectly uses the interpolation logic to generate the complete camera trajectory for the entire timeline animation. By sampling multiple points along each long hop using SLERP, the system creates fluid transitions that accurately represent travel over the Earth's surface.

## Practical Code Examples

### Calculating a Great-Circle Midpoint

The following example computes the halfway point between New York and Tokyo, demonstrating how SLERP finds the true midpoint along the flight path:

```python
from visualizer import interpolate_latlon

ny_lat, ny_lon = 40.7128, -74.0060
tokyo_lat, tokyo_lon = 35.6895, 139.6917

mid_lat, mid_lon = interpolate_latlon(ny_lat, ny_lon, tokyo_lat, tokyo_lon, 0.5)
print(f"Great-circle midpoint: {mid_lat:.4f}°, {mid_lon:.4f}°")

# → Great-circle midpoint: 54.6575°, 28.7742°

```

### Generating Animation Frames

For smooth camera animation, generate intermediate points along the route:

```python
from visualizer import interpolate_latlon

def great_circle_path(lat1, lon1, lat2, lon2, steps=10):
    return [
        interpolate_latlon(lat1, lon1, lat2, lon2, i / steps)
        for i in range(steps + 1)
    ]

path = great_circle_path(40.7128, -74.0060, 35.6895, 139.6917, steps=5)
for i, (lat, lon) in enumerate(path):
    print(f"Step {i}: {lat:.4f}°, {lon:.4f}°")

```

This generates a list of coordinate tuples that the visualizer can feed directly into its rendering pipeline, ensuring each frame follows the correct spherical trajectory.

## Summary

- **Spherical linear interpolation** calculates intermediate points along a great-circle arc, preventing the "teleport" effect of straight-line interpolation through the Earth.
- The **`interpolate_latlon`** function in [`visualizer.py`](https://github.com/mahlernim/google-timeline-visualizer/blob/main/visualizer.py) (lines 111-129) implements SLERP by converting coordinates to 3-D vectors, computing angular displacement via dot products, and blending positions using trigonometric weights.
- **Numerical safeguards** clamp dot products to `[-1, 1]` and handle degenerate cases where points are nearly identical using a threshold of `1e-8`.
- The function integrates with **`position_at_distance`** and **`build_camera_track`** to create realistic camera animations for long-distance hops in the timeline visualizer.

## Frequently Asked Questions

### What is the difference between SLERP and standard linear interpolation?

Standard linear interpolation connects two points with a straight line in Cartesian space, which passes through the Earth's interior when applied to geographic coordinates. SLERP instead operates on the surface of a sphere, calculating positions along the great-circle arc—the shortest path on the sphere's surface. This distinction is crucial for long hops where the straight-line path would incorrectly tunnel through the globe rather than following the actual travel route.

### Why does the code clamp the dot product to `[-1.0, 1.0]` before calling `acos`?

Floating-point arithmetic errors can cause the dot product to slightly exceed the valid range `[-1, 1]`, even when computing the cosine of an angle between two unit vectors. Since `acos` is undefined for inputs outside this range, the code uses `max(-1.0, min(1.0, dot))` to ensure numerical stability. Without this clamping, the function would raise a `ValueError` due to domain errors in the inverse cosine calculation.

### Can SLERP handle short distances between nearby cities?

Yes, the implementation includes a degenerate case check for when `sin(omega) < 1e-8`, which occurs when two points are extremely close together. In these instances, the function falls back to linear interpolation of the vectors. This optimization prevents division by zero while maintaining accuracy, making SLERP suitable for both long intercontinental hops and shorter regional trips without performance penalties.

### How does `interpolate_latlon` interact with the camera positioning system?

The function serves as a geometric primitive used by `position_at_distance` (lines 32-44) to calculate where the camera should sit along a route segment based on cumulative distance traveled. When `build_camera_track` (lines 80-89) constructs the full animation sequence, it relies on these interpolated positions to ensure the camera smoothly follows the great-circle path between timeline events, creating realistic flight-path visualizations for the user's location history.