This is an alternative site for discovering Elm packages.
You may be looking for the
official Elm package site
instead.

Collision detection in two dimensions

type alias Vec2 =
Vec2.Vec2

A vector with x and y components

type Hull
= Bounded (List Side)

A collection of sides that together represent a hull. This library interprets the sides as forming the smallest possible convex polygon.

vec2 : Float -> Float -> Vec2

Build a Vec2 given x and y

```
vec2 1 2 -- x = 1, y = 2
```

fromVectors : List Vec2 -> Hull

Given the vertexes of a polygon, compute a hull. Vertexes must be ordered counter-clockwise around the center of the shape. Only works for convex polygons.

Returns an empty hull if given less than three vertexes.

isInside : Vec2 -> Hull -> Bool

Returns `True`

if the given position is on or in the given hull.
Defaults to `False`

if the hull has no sides.

```
hull =
fromVertexes
[ vec2 0 1
, vec2 3 4
, vec2 1 0
]
isInside hull (vec2 1 1) == True
isInside hull (vec2 -1 2) == False
isInside hull (vec2 0 0) == True
```

isOutside : Vec2 -> Hull -> Bool

Returns `True`

if the given position is outside the given hull.
The logical inverse of `isInside`

.

```
module Collision2D (isOutside, isInside, fromVectors, Hull, Vec2, vec2) where
{-| Collision detection in two dimensions
# Building a Hull
@docs Vec2, Hull, vec2, fromVectors
# Collision Detection
@docs isInside, isOutside
-}
import Vec2
{-| A vector with x and y components
-}
type alias Vec2 =
Vec2.Vec2
{-| Build a Vec2 given x and y
vec2 1 2 -- x = 1, y = 2
-}
vec2 : Float -> Float -> Vec2
vec2 =
Vec2.vec2
{-| Given the vertexes of a polygon, compute a hull. Vertexes must be ordered
counter-clockwise around the center of the shape. Only works for convex polygons.
Returns an empty hull if given less than three vertexes.
-}
fromVectors : List Vec2 -> Hull
fromVectors vertexes =
let
segments =
(List.drop 1 vertexes)
++ (List.take 1 vertexes)
|> List.map2 (,) vertexes
in
if List.length vertexes >= 3 then
fromSegments segments
else
Bounded []
fromSegments : List ( Vec2, Vec2 ) -> Hull
fromSegments segments =
let
toNormal a b =
let
( x, y ) = Vec2.toTuple (Vec2.direction a b)
in
Vec2.fromTuple ( -y, x )
toSide ( a, b ) =
{ keyPoint = a
, normal = toNormal a b
}
isDefined vec =
not (isNaN (Vec2.getX vec) || isNaN (Vec2.getY vec))
in
List.map toSide segments
|> List.filter (.normal >> isDefined)
|> Bounded
{-| Returns `True` if the given position is on or in the given hull.
Defaults to `False` if the hull has no sides.
hull =
fromVertexes
[ vec2 0 1
, vec2 3 4
, vec2 1 0
]
isInside hull (vec2 1 1) == True
isInside hull (vec2 -1 2) == False
isInside hull (vec2 0 0) == True
-}
isInside : Vec2 -> Hull -> Bool
isInside point (Bounded sides) =
let
isBehind side =
Vec2.dot side.normal (Vec2.sub point side.keyPoint) < 1.0e-6
in
not (List.isEmpty sides) && List.all isBehind sides
{-| Returns `True` if the given position is outside the given hull.
The logical inverse of `isInside`.
-}
isOutside : Vec2 -> Hull -> Bool
isOutside point boundary =
not (isInside point boundary)
{-| A collection of sides that together represent a hull. This library
interprets the sides as forming the smallest possible convex polygon.
-}
type Hull
= Bounded (List Side)
{- A side is a straight-line boundary with an inside and an outside. The key
point is a location on the boundary. The
[normal](https://en.wikipedia.org/wiki/Normal_%28geometry%29) is a unit vector
perpendicular to the boundary.
Any point on the side can be a key point, so sides with different key points can
be equivalent sometimes.
Since the sides have no endpoints, infinite-area hulls are possible (e.g. if
there are less than three sides).
-}
type alias Side =
{ keyPoint : Vec2
, normal : Vec2
}
```