# `Cauldron2D.Collision`
[🔗](https://github.com/jaman/cauldron/blob/v0.1.3/cauldron_2d/lib/cauldron_2d/collision.ex#L1)

Bodies against a tile grid, and against each other.

The grid is a function from a tile coordinate to what is there:

    :open                          nothing
    :solid                         the whole tile
    {:diagonal, :nw | :ne | :sw | :se}   the half toward that corner

`sweep/5` moves a body of some radius from one point to another in steps no longer than
a quarter tile, so nothing passes through a wall however fast it travels, and reports the
last clear point, the surface normal and the tile it would have entered. `bounce/3`
reflects a velocity off that normal.

    case Cauldron2D.Collision.sweep(grid, from, to, radius) do
      {:clear, at} -> at
      {:blocked, at, normal, cell} -> ...
    end

`Cauldron2D.Collision.Buckets` finds bodies near each other without comparing every pair.

# `cell`

```elixir
@type cell() :: {integer(), integer()}
```

# `corner`

```elixir
@type corner() :: :nw | :ne | :sw | :se
```

# `grid`

```elixir
@type grid() :: (cell() -&gt; solid())
```

# `normal`

```elixir
@type normal() :: {float(), float()}
```

# `point`

```elixir
@type point() :: {float(), float()}
```

# `solid`

```elixir
@type solid() :: :open | :solid | {:diagonal, corner()}
```

# `bounce`

```elixir
@spec bounce(point(), normal(), number()) :: point()
```

Reflect `velocity` off a surface with unit `normal`.

The component along the normal is reversed and scaled by `restitution`; the component
along the surface is kept. A velocity already moving away from the surface is returned
unchanged.

# `cell_of`

```elixir
@spec cell_of(point()) :: cell()
```

The tile a point is in.

# `circles_overlap?`

```elixir
@spec circles_overlap?(point(), number(), point(), number()) :: boolean()
```

Whether two circles overlap.

# `distance_sq`

```elixir
@spec distance_sq(point(), point()) :: float()
```

The square of the distance between two points.

# `inside?`

```elixir
@spec inside?(grid(), point()) :: boolean()
```

Whether `point` lies in solid material.

# `sweep`

```elixir
@spec sweep(grid(), point(), point(), number()) ::
  {:clear, point()} | {:blocked, point(), normal(), cell()}
```

Move a body of `radius` from `from` to `to`.

Returns `{:clear, to}` when nothing is in the way, or
`{:blocked, at, normal, cell}` with the last clear position, the unit normal of the
surface struck, and the tile struck. A body already inside a wall is blocked at `from`
with a normal opposing its motion.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
