← Back to the collection
SYSTEMS / 2020 / HISTORICAL EXPERIMENT

Following the lay of the land.

Waterflow Simulation

An early terrain simulation: click to add water and explore the difficult relationship between shared state, rendering, and time.

MEDIUM
  • Java
BUILT WITH
  • Swing
  • AWT
  • Threads
ACCESS

Public source

Blue water flowing across the grayscale terrain rendered by the original Java Swing simulation
Fresh capture · original Swing renderer with isolated boundary and thread-visibility repairs.Open film ↗
01

A landscape as a data structure

An elevation grid is rendered as a grayscale image. Water is a second image layer. Each point tracks terrain height, water depth, and surface elevation, while neighboring cells provide candidates for downhill movement.

02

Concurrency is the real subject

The checked-in revision activates one worker, with three others commented out. In a fresh run, water reaching the boundary caused an out-of-range neighbor lookup. This recording uses an isolated copy with an edge guard and a volatile run flag; the terrain, transfer rules, event handler, and Swing renderer are unchanged. It is a visible study of shared state, not a verified four-worker or physically conservative simulator.

SYSTEM SKETCH / CONCEPTUAL OVERVIEW
TERRAIN GRID → SURFACE HEIGHT → LOWER NEIGHBOUR
     ↑                               │
 click: add water             transfer water
     └──────── IMAGE LAYERS ←─────────┘
A reading of the architecture, not an application screenshot.
SYSTEM MAP / RUNTIME COMPONENTS

Events and a worker share the same landscape.

Flow → Terrain → Points[][]: readData. Flow → Parallelize.run(): start. WaterClickListener → Terrain → Points[][]: mutate water. Play / Pause / End → Parallelize.run(): run / pause / stop. Terrain → Points[][] → Parallelize.run(): read neighbouring surfaces. Parallelize.run() → Terrain → Points[][]: mutate depth + image. Parallelize.run() → FlowPanel: repaint. Terrain → Points[][] → FlowPanel: two image layers.1234567801 / ENTRY POINTFlowRead terrain; build Swing windowStart one Parallelize worker02 / SHARED STATETerrain → Points[][]Height · water depth · surfaceTerrain image + water image03 / EVENT HANDLERWaterClickListenerMouse coordinatesAdd water to a 7 × 7 patch04 / WORKER THREADParallelize.run()Permuted cells → checkNeighborstransfer() toward lower surface05 / LIFECYCLEPlay / Pause / EndChange worker run flagsReset clears water depth06 / SWING RENDERERFlowPanelpaintComponent(Graphics)Draw terrain, then water overlay
  1. 01 / entry point

    Flow

    Read terrain; build Swing window

    Start one Parallelize worker

    • readData → 2. Terrain → Points[][]
    • start → 4. Parallelize.run()
  2. 02 / shared state

    Terrain → Points[][]

    Height · water depth · surface

    Terrain image + water image

    • read neighbouring surfaces → 4. Parallelize.run()
    • two image layers → 6. FlowPanel
  3. 03 / event handler

    WaterClickListener

    Mouse coordinates

    Add water to a 7 × 7 patch

    • mutate water → 2. Terrain → Points[][]
  4. 04 / worker thread

    Parallelize.run()

    Permuted cells → checkNeighbors

    transfer() toward lower surface

    • mutate depth + image → 2. Terrain → Points[][]
    • repaint → 6. FlowPanel
  5. 05 / lifecycle

    Play / Pause / End

    Change worker run flags

    Reset clears water depth

    • run / pause / stop → 4. Parallelize.run()
  6. 06 / Swing renderer

    FlowPanel

    paintComponent(Graphics)

    Draw terrain, then water overlay

    1. 1Flow Terrain → Points[][]readData
    2. 2Flow Parallelize.run()start
    3. 3WaterClickListener Terrain → Points[][]mutate water
    4. 4Play / Pause / End Parallelize.run()run / pause / stop
    5. 5Terrain → Points[][] Parallelize.run()read neighbouring surfaces
    6. 6Parallelize.run() Terrain → Points[][]mutate depth + image
    7. 7Parallelize.run() FlowPanelrepaint
    8. 8Terrain → Points[][] FlowPaneltwo image layers
    One worker is active in the checked-in program. Synchronization is local to the objects; this diagram does not imply a globally locked grid or a physically conservative simulation.
    Read from the implementation
    • Flow.java
    • Terrain.java
    • Points.java
    • WaterClickListener.java
    • Parallelize.java
    • FlowPanel.java
    03

    From event to movement

    Clicks add water to a seven-by-seven patch. The worker examines neighboring surface heights and transfers water toward a lower cell; a separate transparent image supplies the blue overlay. The film records a sequence of real add-water events and the resulting movement directly from the application’s renderer.

    04

    Why keep it in the collection

    It brings several systems concerns together in a small, visible world: shared mutable data, event handling, rendering, and worker lifetime. The later visualization projects revisit the same concern—how to let an interface reveal the computation underneath.

    CONTINUE EXPLORING

    Connected Components →

    Treat a grayscale image as a graph. Traverse neighboring pixels to discover connected regions.

    2021
    • C++