FlowField

class FlowField @JvmOverloads constructor(val graph: GridGraph, val sources: Set<Cell>, val cellSize: Double = Defaults.cellSize, val origin: Point2D = Defaults.origin)(source)

A precomputed distance-from-sources field over a GridGraph, exposed at point-level granularity for continuous-space agents.

Wraps three things together that previously had to be carried in parallel by every continuous-space agent that wanted to follow a gradient: the graph, a set of goal cells (sources), and the distanceField map that quantifies "how far from any goal." Adds point-level conversions (cellOf / centerOf) so agents holding continuous positions can query the field without rewriting the same point-to-cell arithmetic at every call site.

Construction runs one multi-source Dijkstra (the GridGraph.distanceField call). Queries are O(1) for distanceAt / arrivedAt and O(|passable neighbors|) for directionAt. Reconstruct (with the same or different sources) to refresh — there is no in-place recompute. Reconstruction is cheap, so building a fresh FlowField in initialize() of each replication is the standard pattern when the graph or sources may change between replications.

Typical use (evacuation):

class MyModel(parent: ModelElement) : AgentModel(parent, "evac") {
val graph: GridGraph = ...
val exits: Set<Cell> = setOf(Cell(0, 0), Cell(29, 29))
lateinit var field: FlowField
override fun initialize() {
super.initialize()
field = FlowField(graph, exits)
}
}
// Per-agent: while (!field.arrivedAt(myPos)) { step in field.directionAt(myPos) }

Geometry model: cells form a uniform grid of side cellSize anchored at origin. Cell (c, r) covers the continuous-space half-open rectangle [origin.x + c*cellSize, origin.x + (c+1)*cellSize) in x and similarly in y, with center at centerOf(Cell(c, r)). For non-uniform or transformed layouts, subclass or compose; the simple uniform case covers every shipped example.

Parameters

graph

the underlying lattice

sources

cells treated as goals (distance = 0). Must not be empty.

cellSize

side length of each cell in continuous space. Must be positive.

origin

continuous-space anchor of cell (0, 0)'s lower-left corner.

Constructors

Link copied to clipboard
constructor(graph: GridGraph, sources: Set<Cell>, cellSize: Double = Defaults.cellSize, origin: Point2D = Defaults.origin)

Types

Link copied to clipboard
object Defaults

Mutable global defaults for FlowField construction. Set once at model setup to change the fallback used when constructors don't pass an explicit value.

Properties

Link copied to clipboard
Link copied to clipboard

Distance-to-nearest-source for every reachable cell. Unreachable cells are absent. Source cells map to 0.0. Exposed for callers that want the raw map (e.g., to render a heatmap); most agent-side code should prefer distanceAt.

Link copied to clipboard
Link copied to clipboard
Link copied to clipboard

Functions

Link copied to clipboard

True if point's cell is a source cell — i.e., the agent at point has reached its goal. Out-of-bounds points are not arrived (they may be invalid placement).

Link copied to clipboard
fun cellOf(point: Point2D): Cell

Convert a point in continuous space to the cell containing it.

Link copied to clipboard
fun centerOf(cell: Cell): Point2D

Center coordinates of cell in continuous space.

Link copied to clipboard

Unit vector pointing from point toward the center of the passable neighbor of point's cell with the smallest field value (i.e., the most-downhill step in the gradient).

Link copied to clipboard

Distance from point's cell to the nearest source. Returns Double.POSITIVE_INFINITY for points whose cell is out of bounds, blocked, or unreachable from any source.