diff --git a/Hipmunk.cabal b/Hipmunk.cabal
--- a/Hipmunk.cabal
+++ b/Hipmunk.cabal
@@ -3,7 +3,7 @@
 Tested-With:   GHC
 Category:      Physics, Game
 Name:          Hipmunk
-Version:       0.2.1
+Version:       0.2.2
 Stability:     provisional
 License:       OtherLicense
 License-File:  LICENSE
@@ -13,9 +13,9 @@
 Synopsis:      A Haskell binding for Chipmunk.
 Description:
       Chipmunk is a fast, simple, portable, 2D physics engine
-      (<http://wiki.slembcke.net/main/published/Chipmunk>).
-      This package contains the Chipmunk rev4 source
-      (from <http://chipmunk-physics.googlecode.com/svn/trunk/>)
+      (<http://wiki.slembcke.net/main/published/Chipmunk>).  This
+      package contains the Chipmunk 4.1.0 source (see
+      <http://www.slembcke.net/forums/viewtopic.php?f=4&t=276>)
       and Haskell bindings to all of its functions. It is
       completely self-contained.
       .
diff --git a/NEWS b/NEWS
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,7 @@
+Version 0.2.2
+=============
+ - Update Chipmunk to version 4.1.0.
+
 Version 0.2.1
 =============
  - Small fix for GHC 6.10. Thanks Pekka Karjalainen and Creighton Hogg
diff --git a/Physics/Hipmunk/Common.hsc b/Physics/Hipmunk/Common.hsc
--- a/Physics/Hipmunk/Common.hsc
+++ b/Physics/Hipmunk/Common.hsc
@@ -104,7 +104,7 @@
 -- | @infinity@ may be used to create bodies with
 --   an infinite mass.
 infinity :: CpFloat
-infinity = 1e100
+infinity = 1e1000
 
 -- | Type synonym used to hint that the argument or result
 --   represents time.
diff --git a/chipmunk/chipmunk.h b/chipmunk/chipmunk.h
--- a/chipmunk/chipmunk.h
+++ b/chipmunk/chipmunk.h
@@ -19,11 +19,14 @@
  * SOFTWARE.
  */
 
+#ifndef CHIPMUNK_HEADER
+#define CHIPMUNK_HEADER
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 	
-typedef float cpFloat;
+typedef double cpFloat;
 	
 static inline cpFloat
 cpfmax(cpFloat a, cpFloat b)
@@ -83,4 +86,6 @@
 
 #ifdef __cplusplus
 }
+#endif
+
 #endif
diff --git a/chipmunk/cpBody.c b/chipmunk/cpBody.c
--- a/chipmunk/cpBody.c
+++ b/chipmunk/cpBody.c
@@ -1,15 +1,15 @@
 /* Copyright (c) 2007 Scott Lembcke
- *
+ * 
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
  * in the Software without restriction, including without limitation the rights
  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  * copies of the Software, and to permit persons to whom the Software is
  * furnished to do so, subject to the following conditions:
- *
+ * 
  * The above copyright notice and this permission notice shall be included in
  * all copies or substantial portions of the Software.
- *
+ * 
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -18,7 +18,7 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-
+ 
 #include <stdlib.h>
 #include <math.h>
 #include <float.h>
@@ -36,21 +36,21 @@
 {
 	body->velocity_func = cpBodyUpdateVelocity;
 	body->position_func = cpBodyUpdatePosition;
-
+	
 	cpBodySetMass(body, m);
 	cpBodySetMoment(body, i);
 
 	body->p = cpvzero;
 	body->v = cpvzero;
 	body->f = cpvzero;
-
+	
 	cpBodySetAngle(body, 0.0f);
 	body->w = 0.0f;
 	body->t = 0.0f;
-
+	
 	body->v_bias = cpvzero;
 	body->w_bias = 0.0f;
-
+	
 	body->data = NULL;
 //	body->active = 1;
 
@@ -112,7 +112,7 @@
 {
 	body->p = cpvadd(body->p, cpvmult(cpvadd(body->v, body->v_bias), dt));
 	cpBodySetAngle(body, body->a + (body->w + body->w_bias)*dt);
-
+	
 	body->v_bias = cpvzero;
 	body->w_bias = 0.0f;
 }
@@ -137,22 +137,22 @@
 	// Calculate the world space anchor coordinates.
 	cpVect r1 = cpvrotate(anchr1, a->rot);
 	cpVect r2 = cpvrotate(anchr2, b->rot);
-
+	
 	cpVect delta = cpvsub(cpvadd(b->p, r2), cpvadd(a->p, r1));
 	cpFloat dist = cpvlength(delta);
 	cpVect n = dist ? cpvmult(delta, 1.0f/dist) : cpvzero;
-
+	
 	cpFloat f_spring = (dist - rlen)*k;
 
 	// Calculate the world relative velocities of the anchor points.
 	cpVect v1 = cpvadd(a->v, cpvmult(cpvperp(r1), a->w));
 	cpVect v2 = cpvadd(b->v, cpvmult(cpvperp(r2), b->w));
-
+	
 	// Calculate the damping force.
 	// This really should be in the impulse solver and can produce problems when using large damping values.
 	cpFloat vrn = cpvdot(cpvsub(v2, v1), n);
 	cpFloat f_damp = vrn*cpfmin(dmp, 1.0f/(dt*(a->m_inv + b->m_inv)));
-
+	
 	// Apply!
 	cpVect f = cpvmult(n, f_spring + f_damp);
 	cpBodyApplyForce(a, f, r1);
@@ -164,7 +164,7 @@
 //{
 //	cpFloat ke = body->m*cpvdot(body->v, body->v);
 //	cpFloat re = body->i*body->w*body->w;
-//
+//	
 //	if(ke + re > body->m*dvsq)
 //		body->active = 1;
 //	else if(body->active)
@@ -175,6 +175,6 @@
 //		body->w = 0.0f;
 //		body->w_bias = 0.0f;
 //	}
-//
+//	
 //	return body->active;
 //}
diff --git a/chipmunk/cpBody.h b/chipmunk/cpBody.h
--- a/chipmunk/cpBody.h
+++ b/chipmunk/cpBody.h
@@ -25,27 +25,48 @@
 
  
 typedef struct cpBody{
+	// *** Integration Functions.
+
 	// Function that is called to integrate the body's velocity. (Defaults to cpBodyUpdateVelocity)
 	cpBodyVelocityFunc velocity_func;
 	
 	// Function that is called to integrate the body's position. (Defaults to cpBodyUpdatePosition)
 	cpBodyPositionFunc position_func;
 	
+	// *** Mass Properties
+	
 	// Mass and it's inverse.
+	// Always use cpBodySetMass() whenever changing the mass as these values must agree.
 	cpFloat m, m_inv;
+	
 	// Moment of inertia and it's inverse.
+	// Always use cpBodySetMass() whenever changing the mass as these values must agree.
 	cpFloat i, i_inv;
 	
-	// NOTE: v_bias and w_bias are used internally for penetration/joint correction.
+	// *** Positional Properties
+	
 	// Linear components of motion (position, velocity, and force)
-	cpVect p, v, f, v_bias;
+	cpVect p, v, f;
+	
 	// Angular components of motion (angle, angular velocity, and torque)
-	cpFloat a, w, t, w_bias;
-	// Unit length 
-	cpVect rot; 
+	// Always use cpBodySetAngle() to set the angle of the body as a and rot must agree.
+	cpFloat a, w, t;
 	
+	// Cached unit length vector representing the angle of the body.
+	// Used for fast vector rotation using cpvrotate().
+	cpVect rot;
+	
+	// *** User Definable Fields
+	
 	// User defined data pointer.
 	void *data;
+	
+	// *** Internally Used Fields
+	
+	// Velocity bias values used when solving penetrations and correcting joints.
+	cpVect v_bias;
+	cpFloat w_bias;
+	
 //	int active;
 } cpBody;
 
@@ -62,10 +83,11 @@
 void cpBodySetMoment(cpBody *body, cpFloat i);
 void cpBodySetAngle(cpBody *body, cpFloat a);
 
-// Modify the velocity of an object so that it will 
+//  Modify the velocity of the body so that it will move to the specified absolute coordinates in the next timestep.
+// Intended for objects that are moved manually with a custom velocity integration function.
 void cpBodySlew(cpBody *body, cpVect pos, cpFloat dt);
 
-// Integration functions.
+// Default Integration functions.
 void cpBodyUpdateVelocity(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt);
 void cpBodyUpdatePosition(cpBody *body, cpFloat dt);
 
diff --git a/chipmunk/cpCollision.c b/chipmunk/cpCollision.c
--- a/chipmunk/cpCollision.c
+++ b/chipmunk/cpCollision.c
@@ -170,13 +170,13 @@
 	
 	for(int i=0; i<poly1->numVerts; i++){
 		cpVect v = poly1->tVerts[i];
-		if(cpPolyShapeContainsVert(poly2, v))
+		if(cpPolyShapeContainsVertPartial(poly2, v, cpvneg(n)))
 			cpContactInit(addContactPoint(arr, &max, &num), v, n, dist, CP_HASH_PAIR(poly1, i));
 	}
 	
 	for(int i=0; i<poly2->numVerts; i++){
 		cpVect v = poly2->tVerts[i];
-		if(cpPolyShapeContainsVert(poly1, v))
+		if(cpPolyShapeContainsVertPartial(poly1, v, n))
 			cpContactInit(addContactPoint(arr, &max, &num), v, n, dist, CP_HASH_PAIR(poly2, i));
 	}
 	
@@ -283,6 +283,24 @@
 			findPointsBehindSeg(arr, &max, &num, seg, poly, minNorm, 1.0f);
 		else
 			findPointsBehindSeg(arr, &max, &num, seg, poly, minNeg, -1.0f);
+	}
+	
+	// If no other collision points are found, try colliding endpoints.
+	if(num == 0){
+		cpVect poly_a = poly->tVerts[mini];
+		cpVect poly_b = poly->tVerts[(mini + 1)%poly->numVerts];
+		
+		if(circle2circleQuery(seg->ta, poly_a, seg->r, 0.0f, arr))
+			return 1;
+			
+		if(circle2circleQuery(seg->tb, poly_a, seg->r, 0.0f, arr))
+			return 1;
+			
+		if(circle2circleQuery(seg->ta, poly_b, seg->r, 0.0f, arr))
+			return 1;
+			
+		if(circle2circleQuery(seg->tb, poly_b, seg->r, 0.0f, arr))
+			return 1;
 	}
 
 	return num;
diff --git a/chipmunk/cpPolyShape.h b/chipmunk/cpPolyShape.h
--- a/chipmunk/cpPolyShape.h
+++ b/chipmunk/cpPolyShape.h
@@ -74,3 +74,19 @@
 	
 	return 1;
 }
+
+// Same as cpPolyShapeContainsVert() but ignores faces pointing away from the normal.
+static inline int
+cpPolyShapeContainsVertPartial(cpPolyShape *poly, cpVect v, cpVect n)
+{
+	cpPolyShapeAxis *axes = poly->tAxes;
+	
+	int i;
+	for(i=0; i<poly->numVerts; i++){
+		if(cpvdot(axes[i].n, n) < 0.0f) continue;
+		cpFloat dist = cpvdot(axes[i].n, v) - axes[i].d;
+		if(dist > 0.0) return 0;
+	}
+	
+	return 1;
+}
diff --git a/chipmunk/cpShape.h b/chipmunk/cpShape.h
--- a/chipmunk/cpShape.h
+++ b/chipmunk/cpShape.h
@@ -43,19 +43,35 @@
 	// Called to by cpShapeDestroy().
 	void (*destroy)(struct cpShape *shape);
 	
-	// called by cpShapeQueryPoint
+	// called by cpShapeQueryPointQuery().
 	int (*pointQuery)(struct cpShape *shape, cpVect p);
 } cpShapeClass;
 
 // Basic shape struct that the others inherit from.
 typedef struct cpShape{
+	// The "class" of a shape as defined above 
 	const cpShapeClass *klass;
 	
-	// Unique id used as the hash value.
-	unsigned int id;
+	// cpBody that the shape is attached to.
+	cpBody *body;
+
 	// Cached BBox for the shape.
 	cpBB bb;
 	
+	// *** Surface properties.
+	
+	// Coefficient of restitution. (elasticity)
+	cpFloat e;
+	// Coefficient of friction.
+	cpFloat u;
+	// Surface velocity used when solving for friction.
+	cpVect surface_v;
+
+	// *** User Definable Fields
+
+	// User defined data pointer for the shape.
+	void *data;
+	
 	// User defined collision type for the shape.
 	unsigned int collision_type;
 	// User defined collision group for the shape.
@@ -63,18 +79,10 @@
 	// User defined layer bitmask for the shape.
 	unsigned int layers;
 	
-	// User defined data pointer for the shape.
-	void *data;
-	
-	// cpBody that the shape is attached to.
-	cpBody *body;
+	// *** Internally Used Fields
 	
-	// Coefficient of restitution. (elasticity)
-	cpFloat e;
-	// Coefficient of friction.
-	cpFloat u;
-	// Surface velocity used when solving for friction.
-	cpVect surface_v;
+	// Unique id used as the hash value.
+	unsigned int id;
 } cpShape;
 
 // Low level shape initialization func.
@@ -129,5 +137,5 @@
 
 // Basic allocation functions for cpSegmentShape.
 cpSegmentShape* cpSegmentShapeAlloc(void);
-cpSegmentShape* cpSegmentShapeInit(cpSegmentShape *seg, cpBody *body, cpVect a, cpVect b, cpFloat r);
-cpShape* cpSegmentShapeNew(cpBody *body, cpVect a, cpVect b, cpFloat r);
+cpSegmentShape* cpSegmentShapeInit(cpSegmentShape *seg, cpBody *body, cpVect a, cpVect b, cpFloat radius);
+cpShape* cpSegmentShapeNew(cpBody *body, cpVect a, cpVect b, cpFloat radius);
diff --git a/chipmunk/cpSpace.h b/chipmunk/cpSpace.h
--- a/chipmunk/cpSpace.h
+++ b/chipmunk/cpSpace.h
@@ -35,14 +35,21 @@
 } cpCollPairFunc;
 
 typedef struct cpSpace{
-	// Number of iterations to use in the impulse solver.
+	// *** User definable fields
+	
+	// Number of iterations to use in the impulse solver to solve contacts.
 	int iterations;
+	
+	// Number of iterations to use in the impulse solver to solve elastic collisions.
 	int elasticIterations;
-//	int sleepTicks;
 	
-	// Self explanatory.
+	// Default gravity to supply when integrating rigid body motions.
 	cpVect gravity;
+	
+	// Default damping to supply when integrating rigid body motions.
 	cpFloat damping;
+	
+	// *** Internally Used Fields
 	
 	// Time stamp. Is incremented on every call to cpSpaceStep().
 	int stamp;
