DistanceCalculator class
DistanceCalculator
A micro‑utility responsible for quickly and safely returning the
Euclidean distance between two particles (or arbitrary Offset
s) while
keeping memory usage bounded through a Least‑Recently‑Used cache.
Why does this class exist?
In a particle network the naïve way to connect n
particles requires
n²
distance checks per frame. Even after spatial pruning (e.g., QuadTree)
we re‑check many of the same pairs across successive frames because most
particles hardly move. Memoising those stable pairs eliminates redundant
square‑root calls and frees the CPU for painting.
Mathematical background
The Euclidean distance d between points p = (x₁, y₁) and q = (x₂, y₂) is
d = √[(x₂ − x₁)² + (y₂ − y₁)²]
This implementation sticks to the textbook formula for clarity; when you
only need comparisons you can cache d² and drop the expensive sqrt
.
Cache‑key derivation
We need a symmetric, fast key unique to a pair. The bitwise XOR
key = hash(p) ⊕ hash(q)
satisfies key(p,q) == key(q,p)
and is a single CPU instruction.
LRU eviction
A LinkedHashMap
preserves insertion order, so removing
_cache.keys.first
discards the least‑recently‑accessed entry, giving us an
O(1) LRU policy without extra metadata.
Usage pattern
final calc = DistanceCalculator(maxEntries: 2_000);
final dist = calc.betweenParticles(p1, p2);
// … render frame …
calc.reset(); // clear if every particle moved this tick
Constructors
- DistanceCalculator.new({int maxEntries = 10_000})
-
Creates a calculator with an upper bound (
maxEntries
) on how many distances may live in the cache at once.
Properties
- hashCode → int
-
The hash code for this object.
no setterinherited
- maxEntries → int
-
Maximum number of memoised distances before eviction.
final
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
Methods
-
betweenParticles(
Particle a, Particle b) → double - Returns the Euclidean distance between two Particles using the cache. The XOR key is computed once here so we don’t hash twice.
-
betweenPoints(
Offset a, Offset b) → double -
Raw distance between two
Offset
s without caching. Useful for sporadic checks (e.g., pointer→particle) where caching adds no value. -
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
reset(
) → void - Clears all cached entries in O(1). Call every frame if the entire swarm moves; otherwise let the cache span a few frames for better hits.
-
toString(
) → String -
A string representation of this object.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited