shapes-0.1.0.0: physics engine and other tools for 2D shapes

Safe HaskellNone
LanguageHaskell2010

Physics.Contact.SAT

Description

Separating Axis Test (SAT). A separating axis is a direction along which the projections of two shapes do not overlap. Alternately, a separating axis is a line between two shapes that do not intersect.

If no separating axis is found, use the axis of smallest overlap to determine which features of the objects are involved in the collision (e.g. calculate contact points and normals).

Synopsis

Documentation

data Overlap Source #

An overlap between two shapes.

Constructors

Overlap 

Fields

Instances

data SATResult Source #

Either the separating axis or the smallest overlap between two shapes.

Constructors

Separated Neighborhood

the edge that forms a separating axis between the two shapes.

MinOverlap Overlap

the smallest overlap

type ContactPoints = Either Neighborhood (SP Neighborhood Neighborhood) Source #

A contact manifold can contain either a single point or a pair of points. For example, a pair of touching edges can be described by a pair of points. A vertex touching an edge can be described by a single point.

data Contact Source #

A contact manifold

Constructors

Contact 

Fields

Instances

satToEither :: SATResult -> Either Neighborhood Overlap Source #

One side of an isomorphism.

overlapTest Source #

Arguments

:: Ord a 
=> SP a a

an interval

-> SP a a

another interval

-> Bool

Do the intervals overlap?

assumes pairs are (min, max)

overlapAmount Source #

Arguments

:: (Ord a, Num a) 
=> SP a a

an interval (e.g. the projection of a shape onto an axis)

-> SP a a

another interval

-> Maybe a

If the intervals overlap, by how much?

assumes pairs are (min, max)

overlapNormal :: Overlap -> V2 Source #

get the normal from the overlap

overlap Source #

Arguments

:: ConvexHull

The receiving shape "sEdge".

-> Neighborhood

An edge normal from the receiving shape.

-> ConvexHull

The penetrating shape "sPen".

-> Maybe Overlap

Any overlap from "sPen" into "sEdge".

Check for overlap along a single axis (edge normal).

minOverlap Source #

Arguments

:: ConvexHull

The receiving shape "sEdge".

-> [Neighborhood]

Edge normals from the receiving shape.

-> ConvexHull

The penetrating shape "sPen".

-> SATResult

Axis of smallest overlap or separating axis.

Find the axis (edge normal) with the smallest overlap between the two shapes.

penetratingEdge Source #

Arguments

:: Overlap 
-> SP Neighborhood Neighborhood

the two vertices that define the edge (in order)

Choose the best edge to act as a penetrator. The overlap test yields a penetrating vertex, but this vertex belongs to two edges.

Choose the edge that is closest to perpendicular to the overlap normal vector. i.e. the edge that is closest to parallel with the penetrated edge

penetratedEdge :: Overlap -> SP Neighborhood Neighborhood Source #

Extract the endpoints of the penetrated edge.

contactPoints' :: ContactPoints -> Either P2 (SP P2 P2) Source #

Extract just the point data from ContactPoints.

clipEdge Source #

Arguments

:: SP Neighborhood Neighborhood

the penetrated edge

-> V2

the normal vector for the overlap

-> SP Neighborhood Neighborhood

the penetrating edge ("incident" edge)

-> Maybe ContactPoints 

Clip a pair of edges into a contact manifold.

contactDebug Source #

Arguments

:: ConvexHull 
-> ConvexHull 
-> (Maybe (Flipping (Either Neighborhood Contact)), SATResult, SATResult)

Either of separating axis (the normal at the Neighborhood) or a contact manifold

Flipping indicates the direction of the collision. Same means a is penetrated by b. Flipped means b is penetrated by a.

How it works:

  1. Find the smallest overlap along the axes of each shape's edges.
  2. Clip this overlap to a contact manifold.

The result should probably never be Nothing, but I don't know if that's guaranteed.

contact Source #

Arguments

:: ConvexHull

shape "a"

-> ConvexHull

shape "b"

-> Maybe (Flipping (Either Neighborhood Contact))

Either of separating axis (the normal at the Neighborhood) or a contact manifold

contact_ :: Overlap -> Maybe Contact Source #

Use clipping to calculate the contact manifold for a given overlap.