Skip to content
Andrew Voirol
Work → GeoGenesis
CartographyLive

GeoGenesis

A projection laboratory for unfurling a 3D sphere into a flat map — continuous Pythagorean limb departure, multi-projection topology mutators, 24-bit RGB country hit-testing, and Great-Circle flight arcs.

Code

10 entries · 2 codebases · 4 projections

Started Aug 1, 2026
GeoGenesis at 50% unfurl with London to Australia flight arc

The sphere-to-plane problem has haunted cartographers for centuries, but for interactive rendering, unfurling the globe in real-time is the hardest part. You can easily draw a 3D orthographic sphere, and you can easily draw a flat equirectangular map, but bridging the two requires continuous geometric surgery on the fly. As part of my broader Cartography project exploring rendering paradigms, I wanted to build a seamless transition without relying on hacky cross-fades or artifact-ridden clip interpolation.

GeoGenesis exists as two distinct codebases because while the projection math is framework-agnostic, the rendering integration is not. The first variant is a 1,053-line single-file React component built around a raw HTML5 Canvas 2D render loop, proving that high-performance continuous morphing is possible without WebGL or Three.js abstractions. The second variant is an Angular 21 implementation that leverages signals and zoneless change detection to drive D3's projection pipeline.

What It Does

  • Continuous unfurl from 3D globe (0%) to flat map (100%) with Pythagorean limb departure
  • 4 projection topologies: Orthographic, Plate Carrée, Winkel Tripel, Mollweide
  • 5 geodesic flight presets with Great-Circle Haversine SLERP arcs
  • 24-bit bijective RGB country hit detection (under 0.05ms)
  • 4 CRT phosphor color palettes
MOUNTING CANVAS 2D CONTEXT...

Technical Deep Dive

  • Pythagorean limb departure: R2−y2\sqrt{R^2 - y^2}R2−y2​ — sliding occluded points from sphere silhouette to equirectangular slots
  • Dynamic horizon clipping: α(t)=π2(1+t)\alpha(t) = \frac{\pi}{2}(1+t)α(t)=2π​(1+t)
  • Winkel Tripel: Multi-projection topology mutator built with 4th-order Taylor sinc guards
  • Mollweide equal-area: Solved via quadratic Newton-Raphson Kepler iteration in ≤4\le 4≤4 steps
  • Angular 21 variant: Uses d3.geoProjectionMutator with signal-driven zoneless change detection for frame-by-frame projection blending

What I Learned

The unfurl seam — where occluded back-face coordinates emerge into the visible front-face — is the hardest problem in this project. Every projection handles it differently, and none of them handle it cleanly. When you flatten a sphere, the points that were hidden behind it have to suddenly decide where they belong on the new 2D plane. You have to write specific mathematical logic to drag those hidden vertices across the limb boundary without them snapping or streaking across the screen. It's a continuous problem of mathematical classification that turns out to be far more complex than just interpolating between two shapes.

CanvasVisualizationAlgorithmsReactTypeScriptAngular

Related Threads

GeoGenesis 3D orthographic sphere with phosphor green CRT scanlines and starfield

GeoGenesis: mathematical projection unfurling and geodesic routing

1,053 lines of Canvas 2D, continuous Pythagorean limb departure unfurling, multi-projection topology mutators (Winkel Tripel & Mollweide), 24-bit RGB country hit-testing, and Haversine SLERP flight arcs.

GeoGenesis orthographic globe in dark mode — stark slate continents with graticule grid, stars behind, and UNFOLD WORLD button below

Building the GeoGenesis Unfold

An AI Studio D3 globe export becomes a buttery orthographic-to-equirectangular transition — through clip artifact rewrites, hemisphere math, and one very important minus sign.

Interactive Globe in 3D orthographic projection showing Americas and Atlantic with minimal dark UI and Toggle to Map button

Interactive Globe

An AI Studio export with genuinely clever math — a custom D3 projection interpolator that unfurls a 3D globe into a flat map and back.


Andrew Voirol

Builder, hacker, shipper. Currently leaving localhost.

Navigate

WorkThreadsBuilder's LogAboutContactRSS Feed

Connect

X / TwitterGitHubLinkedIn

© 2026 Andrew Voirol·Back to top ↑
✦Just one prompt away from figuring it all out.