← Physics thread Flying fish simulator version 1, run 6 parameters; tests 1-3 post-hoc; test 4 v1: pass at own muscle, FAIL at the upper bound; v2: not reachable on assumed drag; v3: airborne at zero drag, no sustained aerobic flight (Lean C14 agrees)
Validation status: not a validated result  Pre-registered 2026-10-31 20:34 UTC before the first run (PREREG.md, hash in PREREG.sha256). Parameters shown are those of run 6; tests 1 to 3 are post-hoc (exploratory: the model was changed after run 1's result, every change is in RUNS.md); test 4 has run (2026-10-31 22:45 UTC, physiology chain wired): under the real fish's own muscle it passes; under the pre-registered non-bird upper bound (a bat's 9.1 % flight muscle, launch uncapped, flapping allowed) it FAILS: the model lets that fish gain net energy for 26 s bouts on its burst store. With the chain capping the launch the real fish cannot even lift off, which shows the tuned launch thrust to be unphysical. Both outcomes are in RUNS.md; nothing was retuned. A match in the table below means "not contradicted by the second-hand field figures with these parameters", nothing more.

3D view — the computed trajectory, flown by the anatomy meshes

Loading three.js and the fish mesh… if this line stays, the 3D view is unavailable here; the 2D charts below are the same run and do not need WebGL.

How a flying fish swims, taxis, takes off and glides, in equations

A point-mass model of one real fish, the darkedged-wing flying fish specimen whose fins Park and Choi measured in a wind tunnel, moving through five phases. Every parameter is listed below with where it came from; the ones that are assumed or tuned have sliders so you can see how much they matter. The sim does not know what a real glide looks like; the validation panel compares it with the published field figures, which are themselves second-hand. Nothing here uses bird data (class Aves is the frozen holdout). Scope: this is the organism level of a chain whose chemistry (gill exchange, haemoglobin), organ (cardiac output) and tissue (muscle power) levels are being written as separate sourced modules; until they land the power interface is a stub that returns zero and says so. Development (genome to morphology) and molecular dynamics are not simulated. Flying fish are not isometric within a species (Davenport 1992: fin area ∝ L1.83, wing loading ∝ L1.24), so this one 60 g specimen does not stand for the family; the designed flier, when it comes, changes parameters only, never these equations.

Side view: height above the sea against distance

The five phases are coloured. Blue is water; the grey band just above the surface is where the lower tail lobe can still touch it (taxiing). The dashed line is 8 m, the maximum recorded flight height.

Speed against time, with the minimum lift-supported speed

vmin = √(2W/(ρSCL,max)) for the current parameters (constraint C9 in the Lean ledger) is the dashed line; the shaded strip below it is where lift cannot hold the fish up in a glide.

Energy per unit mass against time

Kinetic ½v², potential g z, and their sum. In the glide the sum can only fall (drag); in the taxi the tail adds energy.

Validation against the published figures

Field values are quoted second-hand (see the physics page). A match here means the model with these parameters is not contradicted by them; it does not make the parameters measured, and it is not a test unless the parameters are the pre-registered ones.

Parameters and their sources

The equations the integrator solves

State (x, z, vx, vz); z = 0 is the sea surface; integrated with classical RK4 at dt = 1 ms. Gravity: a_z += -g Air lift: L = ½ ρ_air v² S C_L(α) perpendicular to velocity (applies when the fins are out of the water) Air drag: D = ½ ρ_air v² S C_D(α) · f_ge(h/b) opposite to velocity C_L(α) = CL0 + (CLmax - CL0)·α/35° for α ≤ 35°, then falls linearly to 0 at 60° (stall; shape assumed) C_D(α) = CDmin + k·C_L², k from C_D(0°) = CL0 / (L/D)max f_ge(r) = 1 for r ≥ 0.97; linear to 0.86 at r = 0.33; 0.86 below (Park and Choi 2010, water surface; r = h/b, b = span/2) Water drag: D_w = ½ ρ_water v² A_f C_dw (submerged body); on the lobe only, scaled by the immersed fraction, while taxiing Thrust: T along the path; swim: T_swim = ½ ρ_water v_approach² A_f C_dw ; taxi: T_taxi = factor · T_swim while the lobe is in the water Path: the swim thrust acts along the assumed approach angle (the measured 20° leap pitch is a body angle, not the path); while taxiing the fish trims α each step so lift balances weight at half the lobe height with a damping term on the vertical speed (assumed control law, gain 2 per m and 2 s/m), bounded to [-10°, stall]; it leaves the water when even -10° gives more lift than weight (about 16 m/s with this polar) or at the take-off speed target, then holds the glide α. Buoyancy: taken equal to weight while submerged (assumed neutral). Powered flight: (hypothetical fish only) thrust along the path T = min(P_avail / v, 2W), P_avail = f_muscle · m · p_muscle − P_inertial, applied while airborne; the real fish gets none (it does not flap). Breach: the vertical velocity is set to zero when the body centre reaches the surface, on exit and on re-entry (shallow leap, tail dipped; assumed, no planing model) Phases: swim (z + lobe < 0) → taxi (lobe in water, body out) → glide (lobe clear) → taxi again on re-entry if v ≥ v_reentry, else stop.

Physiology chain (chemistry, organ, tissue levels)

Off. When the chain is wired (checkbox above), the swim and taxi thrust are capped by the axial muscle's available power and the flier's flapping by the flight muscle's, both limited by O2 delivery from the gill, haemoglobin and heart modules in water and by the blood O2 store and burst store once airborne (gills do not ventilate in air). Every module parameter with its kind and source is listed here when on. Source of truth: physiology/ in the repository, written by the physiology agent; this page imports a published copy.

Per-glide record