Bodies sorted into square buckets, so that only neighbours are compared.
buckets =
Cauldron2D.Collision.Buckets.new(4)
|> Cauldron2D.Collision.Buckets.insert(:ball, {10.5, 3.2}, 0.5)
|> Cauldron2D.Collision.Buckets.insert(:coin_9, {10.9, 3.0}, 0.1)
Cauldron2D.Collision.Buckets.pairs(buckets) # => [{:ball, :coin_9}]
Cauldron2D.Collision.Buckets.near(buckets, {10.0, 3.0}, 1.0)The bucket size is in tiles and should be at least the largest radius plus the largest reach queried, so that a body is never further than one bucket from anything it can touch. Build a fresh set each tick; there is no removal.
Summary
Functions
Add a body under id.
Ids of every body within reach of pos, measured surface to point.
An empty set with buckets size tiles across.
Every pair of overlapping bodies, each once, as {id, id} with the smaller id first.
Types
@type id() :: term()
@type t() :: %Cauldron2D.Collision.Buckets{ cells: %{required({integer(), integer()}) => [entry()]}, size: pos_integer() }
Functions
@spec insert(t(), id(), Cauldron2D.Collision.point(), number()) :: t()
Add a body under id.
@spec near(t(), Cauldron2D.Collision.point(), number()) :: [id()]
Ids of every body within reach of pos, measured surface to point.
@spec new(pos_integer()) :: t()
An empty set with buckets size tiles across.
Every pair of overlapping bodies, each once, as {id, id} with the smaller id first.