Portability  portable (needs FFI) 

Stability  provisional 
Maintainer  felipe.lessa@gmail.com 
Safe Haskell  SafeInfered 
Shapes used for collisions, their properties and some useful polygon functions.
 data Shape
 data ShapeType
 newShape :: Body > ShapeType > Position > IO Shape
 type CollisionType = Word32
 collisionType :: Shape > StateVar CollisionType
 type Group = Word32
 group :: Shape > StateVar Group
 type Layers = Word32
 layers :: Shape > StateVar Layers
 type Elasticity = CpFloat
 elasticity :: Shape > StateVar Elasticity
 type Friction = CpFloat
 friction :: Shape > StateVar Friction
 type SurfaceVel = Vector
 surfaceVel :: Shape > StateVar SurfaceVel
 body :: Shape > Body
 momentForShape :: Mass > ShapeType > Position > Moment
 momentForCircle :: Mass > (Distance, Distance) > Position > Moment
 momentForSegment :: Mass > Position > Position > Moment
 momentForPoly :: Mass > [Position] > Position > Moment
 shapePointQuery :: Shape > Position > IO Bool
 shapeSegmentQuery :: Shape > Position > Position > IO (Maybe (CpFloat, Vector))
 type Segment = (Position, Position)
 data Intersection
 = IntNowhere
  IntPoint !Position
  IntSegmt !Segment
 epsilon :: CpFloat
 (.==.) :: CpFloat > CpFloat > Bool
 isLeft :: (Position, Position) > Position > Ordering
 isClockwise :: [Position] > Bool
 isConvex :: [Position] > Bool
 intersects :: Segment > Segment > Intersection
 polyReduce :: Distance > [Position] > [Position]
 polyCenter :: [Position] > Position
 convexHull :: [Position] > [Position]
Shapes
There are three types of shapes that can be attached to bodies:
Circle  A circle is the fastest collision type. It also rolls smoothly. 
LineSegment  A line segment is meant to be used as a static shape. (It can be used with moving bodies, however two line segments never generate collisions between each other.) 
Polygon  Polygons are the slowest of all shapes but the most flexible. The list of vertices must form a convex hull with clockwise winding. Note that if you want a nonconvex polygon you may add several convex polygons to the body. 
newShape :: Body > ShapeType > Position > IO ShapeSource
newShape b type off
creates a new shape attached to
body b
at offset off
. Note that you have to
add the shape to a space otherwise it won't generate
collisions.
Properties
Collision type
type CollisionType = Word32Source
The collision type is used to determine which collision callback will be called. Its actual value doesn't have a meaning for Chipmunk other than the correspondence between shapes and the collision pair functions you add. (default is zero)
Group
Groups are used to filter collisions between shapes. If the group is zero, then it imposes no restriction to the collisions. However, if the group is nonzero then the shape will not collide with other shapes in the same nonzero group. (default is zero)
This is primarely used to create multibody, multishape objects such as ragdolls. It may be thought as a lightweight alternative to creating a callback that filters the collisions.
Layers
Layers are similar to groups, but use a bitmask. For a collision
to occur, two shapes must have at least one layer in common.
In other words, layer1 .&. layer2
should be nonzero.
(default is 1
, meaning all bits set)
Note that although this type may have more than 32 bits, for portability you should only rely on the lower 32 bits.
Elasticity
type Elasticity = CpFloatSource
The elasticity of the shape is such that 0.0
gives no bounce
while 1.0
give a "perfect" bounce. Note that due to
inaccuracies using 1.0
or greater is not recommended.
The amount of elasticity applied during a collision is calculated by multiplying the elasticity of both shapes. (default is zero)
By default oldstyle elastic iterations are done when the
space step
s. This used to result in a notsogood
simulation, but now this is the recommended setting.
Friction
The friction coefficient of the shape according
to Coulumb friction model (i.e. 0.0
is frictionless,
iron on iron is around 1.0
, and it could be greater
then 1.0
).
The amount of friction applied during a collision is determined by multiplying the friction coefficient of both shapes. (default is zero)
Surface velocity
type SurfaceVel = VectorSource
The surface velocity of the shape. Useful to create conveyor belts and players that move around. This value is only used when calculating friction, not collision. (default is zero)
Utilities
body s
is the body that this shape is associated
to. Useful especially in a space callback.
momentForShape :: Mass > ShapeType > Position > MomentSource
momentForShape m s off
is a convenience function that calculates
the moment of inertia for shape s
with mass m
and at a
offset off
of the body's center. Uses momentForCircle
,
momentForSegment
and momentForPoly
internally.
momentForCircle :: Mass > (Distance, Distance) > Position > MomentSource
momentForCircle m (ri,ro) off
is the moment of inertia
of a circle of m
mass, inner radius of ri
, outer radius
of ro
and at an offset off
from the center of the body.
momentForSegment :: Mass > Position > Position > MomentSource
momentForSegment m p1 p2
is the moment of inertia of a
segment of mass m
going from point p1
to point p2
.
momentForPoly :: Mass > [Position] > Position > MomentSource
momentForPoly m verts off
is the moment of inertia of a
polygon of m
mass, at offset off
from the center of
the body and comprised of verts
vertices. This is similar
to Polygon
(and the same restrictions for the vertices
apply as well).
shapePointQuery :: Shape > Position > IO BoolSource
shapePointQuery shape p
returns True
iff the point
in position p
(in world's coordinates) lies within the
shape shape
.
shapeSegmentQuery :: Shape > Position > Position > IO (Maybe (CpFloat, Vector))Source
shapeSegmentQuery shape p1 p2
returns Just (t,n)
iff the
segment from p1
to p2
(in world's coordinates)
intersects with the shape shape
. In that case, 0 <= t <=
1
indicates that one of the intersections is at point p1 +
(p2  p1) `scale` t
with normal n
.
For polygons
This section is inspired by pymunk.util
,
a Python module made from http://code.google.com/p/pymunk/,
although implementations are quite different.
Also, unless noted otherwise all polygons are assumed to be simple (i.e. no overlapping edges).
data Intersection Source
A possible intersection between two segments.
IntNowhere  Don't intercept. 
IntPoint !Position  Intercept in a point. 
IntSegmt !Segment  Share a segment. 
The epsilon used in the algorithms below when necessary to compare floats for "equality".
(.==.) :: CpFloat > CpFloat > BoolSource
"Equality" under epsilon
. That is, a .==. b
if abs (a  b) <= epsilon
.
isLeft :: (Position, Position) > Position > OrderingSource
isLeft (p1,p2) vert
is

LT
ifvert
is at the left of the line defined by(p1,p2)
. 
EQ
ifvert
is at the line(p1,p2)
. 
GT
otherwise.
isClockwise :: [Position] > BoolSource
O(n). isClockwise verts
is True
iff verts
form
a clockwise polygon.
intersects :: Segment > Segment > IntersectionSource
O(1). intersects seg1 seg2
is the intersection between
the two segments seg1
and seg2
. See Intersection
.
polyReduce :: Distance > [Position] > [Position]Source
O(n). polyReduce delta verts
removes from verts
all
points that have less than delta
distance
in relation to the one preceding it.
Note that a very small polygon may be completely "eaten"
if all its vertices are within a delta
radius from the
first.
polyCenter :: [Position] > PositionSource
O(n). polyCenter verts
is the position in the center
of the polygon formed by verts
.
convexHull :: [Position] > [Position]Source
O(n log n). convexHull verts
is the convex hull of the
polygon defined by verts
. The vertices of the convex
hulls are given in clockwise winding. The polygon
doesn't have to be simple.
Implemented using Graham scan, see http://cgm.cs.mcgill.ca/~beezer/cs507/3coins.html.