Skip to content

Models

Simulations

Interactive parametric models with 3D visualization, built for fun — every number is editable, and the dossier's there if you want to see how it works.

What this is

Live models, not videos

Move a slider and the actual equations re-solve — nothing below is a pre-rendered animation. I built these for fun, tinkering with physics and data I find interesting, not as a teaching tool. Where real events give me something to check against, the models are calibrated to reproduce them — but treat every number as an estimate, not a prediction.

Each simulation has a collapsible scientific dossier — assumptions, capabilities and limitations, and the full math — if you want to see how it actually works. Otherwise, just go break things.

Heavy models · precomputed

The compute grid — simulations too big for a browser

The simulations above run live in your browser, so they stay small. These three do not: millions of Monte-Carlo trials, an O(N²) orbital conjunction screen, and a pseudo-spectral Navier–Stokes sweep. They run on a home Mac mini (M2 Pro) saturating all its cores — and on a little grid of whatever other devices are idle, each pulling independent work-units. The reduced results are published as static data and drawn below; nothing heavy runs on your device unless you opt in.

War-cost · Monte Carlo

loading…

Kessler · cascade ensemble

loading…

Navier–Stokes · Re sweep

loading…

Lend a device. Any phone or laptop can join the grid — it computes work-units in the browser, no install. Point it at a running coordinator.

Open browser worker →

Interactive 3D · live orbital data

Orbital — Live Satellite Catalog & Kessler Cascade

Every tracked object in Earth orbit, propagated live on the GPU from real CelesTrak orbital elements — the actual Starlink shells, the ISS, GPS, and the named debris clouds, with J2 plane precession and shadow-side eclipse dimming. Then break it: collide satellites, fire an ASAT, or launch a deliberate coordinated attack and watch the Kessler chain reaction shred low orbit while a live event log names every kill, an altitude histogram fills with debris, and an economic-loss counter climbs. Fast-forward ten years to see which shells drag clears and which stay poisoned for generations.

  • — Live catalog: ~18,000 real objects from CelesTrak (cached), classified into LEO/MEO/GEO/HEO + tracked debris
  • — Real orbital mechanics: GPU Kepler propagation, J2 secular precession, atmospheric-drag decay, GEO eclipse
  • — Click any satellite to inspect or destroy it; four incident scenarios including a deliberate Kessler attack
Launch simulation →
Scientific dossier — assumptions, capabilities & the mathematics

Dossier

Orbital — Live Catalog & Kessler Cascade

The full tracked population of Earth orbit — roughly 18,000 objects from the CelesTrak catalog — is propagated forward in time from each object's real orbital elements. You can inspect or destroy any object, stage collisions and anti-satellite strikes, and then fast-forward a decade to watch which debris shells clear and which stay lethal for generations.

Assumptions

  • Two-body gravity is the base field. Earth is a point mass with gravitational parameter \(\mu=GM_\oplus\); every object follows a Keplerian conic perturbed only by the dominant oblateness term.
  • Oblateness enters through the secular \(J_2\) terms only. The node and perigee precess; short-period oscillations, higher zonal/tesseral harmonics, luni-solar gravity and solar radiation pressure are neglected for catalog objects.
  • Catalog energy is conserved. Semi-major axis is fixed for tracked objects (no per-object drag integration); atmospheric drag is modelled explicitly only for collision fragments, and statistically for the decade-scale fast-forward.
  • Breakups are isotropic. A collision or ASAT ejects fragments with a characteristic spread of relative velocity; fragment counts are representative heuristics, not a NASA standard breakup-model spectrum.
  • Input data is live but cached. Elements come from real CelesTrak TLEs (with a synthetic fallback), classified into LEO/MEO/GEO/HEO plus tracked debris families (Cosmos-2251, Iridium-33, Fengyun-1C, …).

Capabilities & limitations

  • Can: reproduce the true geometry of the Starlink shells, GPS, the ISS and named debris clouds; show correct nodal/apsidal precession (so Sun-synchronous and Molniya planes behave correctly); render eclipse dimming and the along-plane spreading of a fresh debris cloud; account for the economic value destroyed.
  • Cannot: match an operational propagator (SGP4) to the metre — keeping only secular \(J_2\) means positions drift from truth over long spans; produce calibrated breakup fragment counts; resolve true collision probabilities (you choose the collisions). The decade decay is a statistical survival model, not a per-object atmospheric integration.

Mathematics

1 · Kepler propagation. Each object's mean motion and period follow from its semi-major axis \(a\):

\[ n=\sqrt{\frac{\mu}{a^{3}}},\qquad T=\frac{2\pi}{n}=2\pi\sqrt{\frac{a^{3}}{\mu}},\qquad \mu=GM_\oplus=398{,}600.4418\ \mathrm{km^3\,s^{-2}}. \]

The mean anomaly advances linearly, \(M(t)=M_0+n\,(t-t_0)\), and the eccentric anomaly \(E\) is recovered from Kepler's equation by Newton–Raphson — the exact iteration the propagator runs (six steps):

\[ M=E-e\sin E,\qquad E_{k+1}=E_k-\frac{E_k-e\sin E_k-M}{1-e\cos E_k}. \]

The position in the orbital (perifocal) plane and the radius are then

\[ x=a(\cos E-e),\qquad y=a\sqrt{1-e^{2}}\,\sin E,\qquad r=a\,(1-e\cos E), \]

and a 3–1–3 rotation by \((\Omega,i,\omega)\) carries that into the Earth-centred inertial frame, \(\mathbf r_{\mathrm{ECI}}=R_3(-\Omega)\,R_1(-i)\,R_3(-\omega)\,[\,x,\ y,\ 0\,]^{\mathsf T}\). The speed at any point obeys the vis-viva relation

\[ v^{2}=\mu\!\left(\frac{2}{r}-\frac{1}{a}\right). \]

2 · \(J_2\) secular precession. Earth's oblateness adds the leading zonal term to the potential,

\[ U(r,\phi)=-\frac{\mu}{r}\left[\,1-J_2\Big(\frac{R_\oplus}{r}\Big)^{2}P_2(\sin\phi)\right],\qquad P_2(u)=\tfrac12\big(3u^{2}-1\big),\qquad J_2=1.082627\times10^{-3}, \]

where \(\phi\) is geocentric latitude. Averaging Lagrange's planetary equations over one orbit kills the periodic terms and leaves secular drifts of the node \(\Omega\) and argument of perigee \(\omega\). With the semi-latus rectum \(p=a(1-e^{2})\):

\[ \dot\Omega=-\tfrac{3}{2}\,nJ_2\Big(\frac{R_\oplus}{p}\Big)^{2}\cos i,\qquad \dot\omega=\tfrac{3}{4}\,nJ_2\Big(\frac{R_\oplus}{p}\Big)^{2}\big(5\cos^{2}i-1\big). \]

The simulation stores these as \(k=\tfrac32 J_2(R_\oplus/p)^2 n\) with \(\dot\Omega=-k\cos i\) and \(\dot\omega=k\,(2-\tfrac52\sin^2 i)\); the two forms are identical because \(2-\tfrac52\sin^2 i=\tfrac12(5\cos^2 i-1)\).

Proof — the critical inclination. The perigee stops precessing exactly when its rate vanishes:

\[ \dot\omega=0\ \Longleftrightarrow\ 5\cos^{2}i-1=0\ \Longrightarrow\ \cos i=\pm\tfrac{1}{\sqrt5}\ \Longrightarrow\ i=63.43^{\circ}\ \text{(or }116.57^{\circ}). \]

This is why Molniya/Tundra orbits sit at \(63.4^{\circ}\): the apogee stays frozen over the same hemisphere. Sun-synchronous orbits use the other rate — forcing the node to precess at exactly one revolution per year, \(\dot\Omega=2\pi/\text{yr}\approx1.991\times10^{-7}\ \mathrm{rad/s}\), and solving for \(\cos i\) gives the familiar retrograde \(i\approx98^{\circ}\) at a few hundred km altitude. Both results fall straight out of the equations above and are visible in the live catalog.

3 · Fragment dynamics and re-entry. Each collision fragment is integrated as a true two-body trajectory with a thin-atmosphere drag sink below 450 km, using a semi-implicit (symplectic) Euler step with \(\Delta t\le 20\,\mathrm s\):

\[ \ddot{\mathbf r}=-\frac{\mu}{\lVert\mathbf r\rVert^{3}}\,\mathbf r,\qquad \mathbf v\leftarrow\mathbf v\Big(1-c\,e^{(300-h)/90}\,\Delta t\Big)\quad(h<450\ \mathrm{km}). \]

To decide a fragment's long-term fate, its instantaneous state \((\mathbf r,\mathbf v)\) is converted back to orbital elements — the exact algebra the fast-forward uses:

\[ a=\Big(\frac{2}{r}-\frac{v^{2}}{\mu}\Big)^{-1},\qquad h=\lVert\mathbf r\times\mathbf v\rVert,\qquad e=\sqrt{1-\frac{h^{2}}{\mu a}},\qquad q=a(1-e)-R_\oplus, \]

and the perigee altitude \(q\) drives a decade survival probability that runs from \(0\) below 300 km to \(\sim0.95\) above 1200 km.

4 · The Kessler criticality (the headline result). Treat a shell as a population of \(N\) objects. Mutual collisions create fragments at a rate proportional to the number of pairs, \(\propto N^2\); atmospheric drag removes objects on a timescale \(\tau_d(h)\). The population then obeys a logistic-type balance:

\[ \frac{dN}{dt}=\underbrace{\tfrac12\,\kappa\,N^{2}}_{\text{collisional production}}\;-\;\underbrace{\frac{N}{\tau_d(h)}}_{\text{atmospheric sink}},\qquad \kappa=\frac{\langle\sigma\,v_{\text{rel}}\,f\rangle}{V_{\text{shell}}}, \]

with \(\sigma\) the collision cross-section, \(v_\text{rel}\) the encounter speed and \(f\) the fragments produced per collision. The cascade becomes self-sustaining — growing with zero new launches — precisely when production overtakes the sink:

\[ \frac{dN}{dt}>0\ \Longleftrightarrow\ N>N_{\text{crit}}=\frac{2}{\kappa\,\tau_d(h)}. \]

Because \(\tau_d\) climbs from days near 300 km to centuries above 700 km, the critical population \(N_\text{crit}\) collapses with altitude. That is the quantitative reason the 700–1200 km shells are the dangerous ones — and why, after a cascade, the fast-forward shows those shells still poisoned a decade later while the low ones self-clean. This is Kessler syndrome stated as an inequality.

Interactive 3D · discrete-event simulation

Strike vs. Defense — Iran→Israel Cost Model

Parametric cost model of Iranian missile/drone salvos against layered Israeli/US air defense, on real terrain. Discrete-event engagement engine (battery fire cycles, weapon flyout, shoot-look-shoot), terrain-masked radar coverage, sensor-gated interceptors, decoys and separating warheads, Israeli/Iranian doctrine options, Monte-Carlo batch statistics and a campaign-economics view of the war of inventories.

  • — Historical salvos: True Promise I–IV (2024–2026), calibrated against documented outcomes
  • — All parameters editable — unit costs, Pk, magazines, doctrine, sensors
  • — Educational model built on open-source estimates
Launch simulation →
Scientific dossier — assumptions, capabilities & the mathematics

Dossier

Strike vs. Defense — Cost Model

A parametric, discrete-event model of a missile/drone salvo meeting a layered air defense over real terrain. It answers an economic question the headlines rarely do: for a given salvo and a given defensive posture, who spends more, how many leakers get through, and how long each side's magazines last.

Assumptions

  • Threats are grouped into three categories — drone, cruise, ballistic — each facing an ordered chain of defensive layers.
  • Each layer is a five-parameter object: an engageable share \(\mathrm{cov}\), interceptors per engagement \(s\) (salvo), single-shot kill probability \(P_k\), unit cost, and a magazine depth.
  • Engagements are independent Bernoulli trials. A layer attempts a fraction \(\mathrm{cov}\) of the threats it sees and kills each engaged threat with probability \(1-(1-P_k)^{s}\).
  • Sensor fusion gives a small bonus. When two or more radar families hold a track, that engagement's kill probability rises by \(0.05\), capped at \(0.97\).
  • Batteries saturate. Each has a fire-cycle time, finite ready rounds, and shoot–look–shoot up to two rounds; targets arriving faster than a battery can cycle leak through.
  • Radar visibility is geometric. Line of sight uses a \(\tfrac43\)-Earth refraction model with terrain masking ray-marched against a real elevation grid.
  • Costs are open-source point estimates and the type splits within historical salvos are author estimates; treat them as editable, not authoritative.

Capabilities & limitations

  • Can: compute a deterministic expected value (mean of repeated trials) and a single Monte-Carlo run that drives the animation; deplete magazines; model decoys and separating warheads; apply doctrine (weapon-target assignment, interceptor reserves); mask radar by terrain; and produce a campaign-economics view — all calibrated so the eight loadable historical salvos reproduce their documented interception rates.
  • Cannot: serve as an operational or predictive tool. Engagements are decided statistically and are only partially coupled to the drawn radar geometry (a known issue being closed). Unit costs are point estimates; trajectories are representative, not optimised.

Mathematics

1 · One layer. A layer firing a salvo of \(s\) interceptors, each with single-shot kill probability \(P_k\), kills an engaged threat with probability

\[ P_k^{\text{eng}}=1-(1-P_k)^{s}, \]

raised by the fusion bonus to \(\min(0.97,\ P_k^{\text{eng}}+0.05)\) when \(\ge 2\) sensor families hold the track. Since the layer only engages a share \(\mathrm{cov}\) of the threats it sees, the probability a single threat survives that layer is

\[ L_\ell=1-\mathrm{cov}_\ell\,\big[\,1-(1-P_{k,\ell})^{s_\ell}\big]. \]

2 · The layered chain. With layers treated as independent, the overall leakage probability through \(m\) layers is the product of the per-layer survivals — the core equation of the whole model:

\[ P_{\text{leak}}=\prod_{\ell=1}^{m}L_\ell=\prod_{\ell=1}^{m}\Big(1-\mathrm{cov}_\ell\big[\,1-(1-P_{k,\ell})^{s_\ell}\big]\Big). \]

From \(M_{\text{in}}\) incoming threats the expected counts are simply

\[ \mathbb E[\text{leak}]=M_{\text{in}}\,P_{\text{leak}},\qquad \mathbb E[\text{stopped}]=M_{\text{in}}\,(1-P_{\text{leak}}). \]

The multiplicative form makes the defensive logic obvious: leakage falls geometrically with each added layer, which is exactly why air defense is built in depth rather than as one perfect wall.

3 · Interceptor expenditure and cost. The threats reaching layer \(\ell\) are those that survived everything before it, so the expected number of interceptors that layer fires is

\[ \mathbb E\big[N_\ell^{\text{shots}}\big]\approx M_\ell\,\mathrm{cov}_\ell\,s_\ell\,\bar r_\ell,\qquad M_\ell=M_{\text{in}}\!\!\prod_{j<\ell}L_j,\qquad \bar r_\ell\in[1,2], \]

with \(\bar r_\ell\) the average rounds per engagement under shoot–look–shoot. Summing over layers and categories gives the two spend totals and the cost-exchange ratio — the number that decides the "war of inventories":

\[ C_{\text{def}}=\sum_\ell N_\ell^{\text{shots}}\,c_\ell,\qquad C_{\text{atk}}=\sum_{\text{cat}}n_{\text{cat}}\,c_{\text{cat}},\qquad \mathrm{CER}=\frac{C_{\text{def}}}{C_{\text{atk}}}, \]

alongside the ground damage from leakers, \(D=\sum_{\text{cat}}\mathbb E[\text{leak}]_{\text{cat}}\,d_{\text{cat}}\). The defender "wins the economics" only when \(\mathrm{CER}<1\) and magazines outlast demand — a \(\$50{,}000\) interceptor against a \(\$20{,}000\) drone already loses on price even when it hits.

4 · Why average many trials. Each threat's fate is a chain of Bernoulli draws, so a single run is noisy. The "expected value" mode reports the sample mean over \(N=16\) independent trials,

\[ \widehat{C}=\frac1N\sum_{j=1}^{N}C^{(j)},\qquad \mathrm{SE}=\frac{\sigma_C}{\sqrt N}, \]

whose standard error shrinks as \(1/\sqrt N\) — enough to stabilise the headline numbers while staying cheap enough to recompute on every slider move.

5 · Saturation and magazines. Statistics are not the only way a defense fails. A battery with fire-cycle \(t_c\) and \(m\) ready rounds, facing a salvo spread over a window \(\tau\), can service at most

\[ N_{\text{engageable}}\le\min\!\Big(m,\ \big\lfloor \tau/t_c\big\rfloor\Big)\ \text{per battery}, \]

and everything beyond that leaks regardless of \(P_k\). Once cumulative shots exhaust the magazine, the layer drops out of the product in §2 entirely, \(L_\ell\to 1\), and the \(\mathrm{CER}\) spikes. This is the mathematical heart of the inventory war: cheap mass beats expensive excellence once the magazines run dry.

6 · Radar horizon and terrain masking. Detection is gated by line of sight. Using the standard \(\tfrac43\)-Earth refraction radius, the horizon range from height \(h\) and the two-station intervisibility condition (radar height \(h_r\), target height \(h_t\), ground range \(d\)) are

\[ R_{\text{eff}}=\tfrac43 R_\oplus\approx 8493\ \mathrm{km},\qquad d_h=\sqrt{2R_{\text{eff}}\,h},\qquad \sqrt{2R_{\text{eff}}\,h_r}+\sqrt{2R_{\text{eff}}\,h_t}\ \ge\ d. \]

Earth curvature alone hides anything below \(\Delta h=d^{2}/(2R_{\text{eff}})\) at range \(d\). On top of that, terrain is ray-marched: for each azimuth \(\psi\) the model takes the largest masking angle along the ground path,

\[ \alpha(\psi)=\max_{0

where \(z(s)\) is the real terrain elevation. This is what makes radar shadows form behind the Zagros and Taurus ranges in the scene — and, once sensors are fully coupled to engagements, what makes a single radar's contribution measurable in dollars.

Interactive map · 79 indexes

Freedom Index — World Map of Liberty

A world map that recolors itself to whichever measure of freedom you choose, from 79 indexes across a dozen publishers — Freedom House, the EIU Democracy Index, V-Dem's full family of democracy and rights indices, RSF press freedom, Heritage and Fraser economic freedom, the World Bank's governance indicators, the WJP Rule of Law Index, Transparency International's corruption index, and more. Hover any country for its score, click for a full breakdown grouped by category, or filter the index list by name. The choropleth sits over a dark relief basemap so geography and politics read at once.

  • — 79 indexes across Political & Civil, Press, Economic, Rule of Law & Governance, Human Rights & Society, and Composite categories
  • — Esri dark relief basemap + administrative boundaries/labels, no API keys; choropleth from world-atlas borders
  • — Compiled snapshot, each index linked to its source — verify before citing
Launch simulation →
Scientific dossier — assumptions, capabilities & the mathematics