The 3D version of this simulator resolves who-sees-whom analytically: for every fish it sorts visible neighbors by distance and subtracts each closer neighbor's angular footprint from farther ones' footprints in one pass. This 2D version solves the same occlusion problem with an independent, genuinely different computational method — rasterized ray-casting — because a flat plane makes it cheap to sample a fish's field of view directly instead of doing interval algebra:
for each of R rays spanning the visible FOV (excluding the blind sector):
among all neighbors whose visual disk (half-angle = atan(bodyRadius/dist)) covers this ray's angle,
the NEAREST one wins the ray (it physically blocks the ones behind it)
→ that neighbor's ray-tally += 1
weight_j = (rays won by j) / R ≈ j's unoccluded fraction of the visual field
A closer, bigger-looking fish naturally wins more rays than a distant, small-looking one — the same visual-angle weighting the 3D model computes with trigonometry falls out here for free from the sampling geometry, and increasing "Vision rays" makes the estimate converge on the exact occluded fraction (verified numerically below).
Close-range avoidance is also modeled differently. The 3D version simply pushes away from anything inside a fixed radius (1/d-style repulsion, isotropic and instantaneous). Here, avoidance uses time-to-collision (τ, Lee's tau theory) — the same variable real fish and birds are shown to use for braking and collision avoidance:
closing speed = −(Δpos · Δvelocity) / |Δpos|
τ = |Δpos| / closing speed (if actually closing; else a weak spacing term applies)
avoidance weight = 1 / max(τ, τ_min)
Two fish converging fast at close range get an urgent, large steering push (τ small) even if they're not yet touching; two fish drifting slowly past each other barely react — a qualitatively different (and more realistic) trigger than pure distance.
Finally, this 2D model adds a diagnostic the 3D version doesn't have: instead of startling every fish at once and reading global polarization, "Startle ONE fish" kicks a single individual and then times how long each other fish takes before its own heading first deviates from its pre-startle value by more than 28°. Plotting that reaction latency against each fish's initial distance from the startled individual and fitting a zero-intercept regression gives a real measured propagation speed for the fright response — the same quantity Rosenthal et al. (PNAS 2015) measured in golden shiner schools, where behavioral information was found to spread through the group as a wave with a roughly constant speed, faster than any single fish's own swimming speed, because the visual-alignment coupling relays the signal fish-to-fish rather than each fish reacting only to the original startle.
Group order is still measured with the standard polarization order parameter Φ = |(1/N)·Σ(v_i/|v_i|)| ∈ [0,1].
- Blind zone — widen it and each fish goes half-blind behind itself; alignment (and the startle cascade) propagates more slowly.
- Vision range — how far a fish can resolve another fish at all, independent of angle.
- School size — more bodies means more mutual occlusion at fixed density.
- Turning agility — the physical cap on how fast a fish's body can rotate toward its desired heading.
- Vision rays — occlusion-sampling resolution; raise it to see the ray-cast weight estimate converge on the exact analytic occluded fraction.