Skip to content

Bankde/fish-tank-simulator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Fish Schooling Simulation

Fish schooling simulation running entirely in the browser, in two flavours:

  • 2D (/2d/) — top-down view, vanilla JS + Canvas, sprite fish.
  • 3D (/3d/) — glass aquarium with a free orbit/fly camera, Three.js (vendored locally in 3d/vendor/, no CDN).

Both are 100% client-side — the server only serves static files; all simulation and tuning happens in the browser in real time.

Run

python3 server.py          # http://localhost:8000
python3 server.py 9090     # custom port

Then open:

  • http://localhost:8000/ — landing page linking to both
  • http://localhost:8000/2d/ — 2D simulation
  • http://localhost:8000/3d/ — 3D simulation

Any static file server works too (e.g. python3 -m http.server), as long as it serves the whole directory so /2d/ and /3d/ resolve.

3D camera controls

  • Drag — orbit around the tank.
  • Scroll — zoom in / out.
  • W A S D — fly the view horizontally; Q / E — down / up; hold Shift to move faster.

The 3D version runs the same Couzin model extended to three dimensions (wider orientation zone by default, since 3D neighbourhoods are sparser). Fish are simple oriented 3D meshes for now; the shark is a low-poly glTF model. Rocks are procedural: each is built from several hexagonal prisms merged into one vertex-coloured geometry, with 6 deterministic templates to choose from (a new rock picks one at random). Rocks have flat bottoms and sit on the tank floor. Seaweed is procedural too — 4 templates of bent tapered blades, anchored to the floor with a gentle current sway. Rocks, sharks and seaweed are added via buttons since the mouse drives the camera:

  • Camera: left-drag orbits, right-drag pans, scroll zooms, WASD/QE fly.
  • Click a rock or seaweed to open its transform gizmo (all edits happen through the gizmo — objects can't be dragged directly): drag the arrows to move along an axis (rock Y lifts it off the floor), the rings to rotate, the coloured + handles to resize along one axis, or the gold + to resize uniformly. A floating at the object's top-right (or the Delete/X key) removes it. Seaweed shows a reduced gizmo (slide on the floor, spin, uniform resize). Sharks are selectable too — a pulsing ring marks the selected shark and the ✕ (which follows it as it swims) or Delete/X removes just that one. The gizmo's layout rescales with the object so handles stay outside the mesh, while lines render at a constant 1px width; the selected object is highlighted.

Seaweed is decorative; rocks are solid obstacles. Collision uses two levels: a fitted bounding sphere for the cheap broad-phase test, then a set of ~8 sub-spheres (k-means-fitted to each template's vertices once at load) for the actual avoidance/contact. The narrow-phase query runs in the rock's template space, so under a non-uniform stretch each sub-sphere acts as a world-space ellipsoid — a 5x-stretched slab collides like a slab, not a row of fat balls — and moving/rotating/resizing adapt instantly without re-fitting. The 🔴 Collision zones button toggles a debug view that renders every no-swim volume (rock sub-spheres and shark bodies) as translucent red.

Model

Implements the zone-based schooling model (Aoki/Couzin) described in Wikipedia: Shoaling and schooling — Modelling school behaviour:

  • Zone of repulsion — fish always steer directly away from neighbors that get this close (highest priority).
  • Zone of orientation — fish align their heading with neighbors in this band.
  • Zone of attraction — fish steer toward neighbors in this band, keeping the school together.
  • Field of view — fish are blind in a cone behind them; the blind cone applies to orientation/attraction but not repulsion.
  • Heading changes are limited by a max turn rate, plus random noise.

Obstacles, predators, and the tank walls inject high-priority escape vectors on top of the schooling behavior, and hard constraints guarantee fish never leave the box or penetrate an obstacle.

Fish bodies are solid: the repulsion zone applies across all fish types (so different types avoid each other without schooling together), and a position-based separation pass each frame keeps fish bodies from overlapping — same type or not. Sharks are solid too: they keep separation from each other (so multiple sharks don't merge onto one chase route), and neither fish nor other sharks can overlap a shark's body.

2D controls

  • Fish types — tabs at the top of the panel; the "+" tab adds a new type with its own color and its own full set of schooling parameters. Fish only school with their own type (the zone model ignores other types entirely). A type can be removed with the trash button under its sliders.
  • All constants are sliders on the left panel and take effect immediately, including per-type fish count.
  • Rock mode — click the water to place a rock obstacle (radius set by its slider; the collision shape is a circle). Drag on any rock — in any mode — to resize it: pull outward to grow, inward to shrink. A dashed ring shows the collision radius while resizing.
  • Predator mode — click to place a shark that chases the nearest fish; fish flee it. Predators are draggable.
  • Seaweed mode — click to plant decorative seaweed (random variant and size); fish swim through it.
  • Erase mode — click a rock, shark, or seaweed to remove it one by one.
  • Pause/resume, reset fish positions, clear all placed items.
  • Persistence — all sliders, fish types, and placed rocks / sharks / seaweed are saved to localStorage automatically and restored on reload. "Reset settings" forgets everything and returns to defaults.

Uses a spatial hash grid for neighbor queries, so ~1000+ fish stay smooth.

Art credits (all public domain / CC0)

Layout

index.html          landing page (links to /2d/ and /3d/)
server.py           one-port static server with /2d + /3d routing
2d/index.html       2D simulation
2d/assets/          fish/shark/rock/seaweed sprites + licenses
3d/index.html       3D simulation
3d/vendor/          Three.js (local, no CDN)

About

Simulating fish schooling

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors