project: function(p,axis,i){ i = i || vec.make(); i[0] = Infinity; i[1] = -Infinity; for(var j=0; j < p.length; j++){ var dot = vec.dot(axis,p.vertices[j]) if( dot < i[0] ){ i[0] = dot; } if( dot > i[1] ){ i[1] = dot; } } return i; }
collides: function(a,b,v,o){ var res = o || {}; res.intersect = true; res.willIntersect = true; res.minTranslationVector = null; res.nearestEdge = null; v = v || vec.make() var minIntervalDistance = Infinity; var translationAxis = vec.make(); var nearestEdge = vec.make(); var axis = vec.make() var iA = vec.make(); var iB = vec.make(); var cA, cB, cD; // loop through all edges of both polygons for(var i=0; i < (a.length+b.length); i++){ var e = i < a.length ? i : i-a.length var edge = i < a.length ? a.edges[e] : b.edges[e] vec.perp(edge,axis) vec.norm(axis,axis) poly.project(a,axis,iA) poly.project(b,axis,iB) // are they currently intersecting? var iD = intervalDistance(iA,iB); if( iD >= 0 ){ res.intersect = false; } // will they intersect? var vProj = vec.dot(axis,v); if( vProj < 0 ){ iA[0] += vProj; } else { iA[1] += vProj; } iD = intervalDistance(iA,iB); if( iD >= 0 ){ res.willIntersect = false; } // find out if it's the closest one iD = Math.abs(iD); if( iD < minIntervalDistance ){ minIntervalDistance = iD; vec.copy(edge, nearestEdge); vec.copy(axis, translationAxis); cA = cA || poly.centroid(a) cB = cB || poly.centroid(b) cD = vec.sub(cA, cB, cD); if( vec.dot(cD, translationAxis) < 0 ){ vec.neg(translationAxis,translationAxis) } } // no intersection is and won't happen if( !res.intersect && !res.willIntersect ){ break; } } // the minimum translation vector can // be used to push the polygons apart if( res.willIntersect ){ translationAxis[0] *= minIntervalDistance; translationAxis[1] *= minIntervalDistance; res.minTranslationVector = translationAxis; res.nearestEdge = nearestEdge; } else { vec.free(translationAxis) vec.free(nearestEdge) } vec.free(iA) vec.free(iB) vec.free(cA) vec.free(cB) vec.free(cD) vec.free(axis) // free `v` if it wasn't passed in as // an argument if( !arguments[2] ){ vec.free(v); } return res; },