Created
February 2, 2011 04:46
-
-
Save louisstow/807250 to your computer and use it in GitHub Desktop.
SAT collision detection in JS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
SAT: function(poly1, poly2) { | |
var points1 = poly1.points, | |
points2 = poly2.points, | |
i = 0, l = points1.length, | |
j, k = points2.length, | |
normal = {x: 0, y: 0}, | |
length, | |
min1, min2, | |
max1, max2, | |
interval, | |
MTV, | |
dot, | |
nextPoint, | |
currentPoint; | |
//loop through the edges of Polygon 1 | |
for(;i<l;i++) { | |
nextPoint = points1[(i==l-1 ? 0 : i+1)]; | |
currentPoint = points1[i]; | |
//generate the normal for the current edge | |
normal.x = -(nextPoint[1] - currentPoint[1]); | |
normal.y = (nextPoint[0] - currentPoint[0]); | |
//normalize the vector | |
length = Math.sqrt(normal.x * normal.x + normal.y * normal.y); | |
normal.x /= length; | |
normal.y /= length; | |
//default min max | |
min1 = min2 = -1; | |
max1 = max2 = -1; | |
//project all vertices from poly1 onto axis | |
for(j = 0; j < l; ++j) { | |
dot = points1[j][0] * normal.x + points1[j][1] * normal.y; | |
if(dot > max1 || max1 === -1) max1 = dot; | |
if(dot < min1 || min1 === -1) min1 = dot; | |
} | |
//project all vertices from poly2 onto axis | |
for(j = 0; j < k; ++j) { | |
dot = points2[j][0] * normal.x + points2[j][1] * normal.y; | |
if(dot > max2 || max2 === -1) max2 = dot; | |
if(dot < min2 || min2 === -1) min2 = dot; | |
} | |
//calculate the minimum translation vector should be negative | |
interval = (min1 < min2) ? min2 - max1 : min1 - max2; | |
//exit early if positive | |
if(interval > 0) { | |
return false; | |
} | |
if(interval > MTV) MTV = interval; | |
} | |
//loop through the edges of Polygon 1 | |
for(i=0;i<k;i++) { | |
nextPoint = points2[(i==k-1 ? 0 : i+1)]; | |
currentPoint = points2[i]; | |
//generate the normal for the current edge | |
normal.x = -(nextPoint[1] - currentPoint[1]); | |
normal.y = (nextPoint[0] - currentPoint[0]); | |
//normalize the vector | |
length = Math.sqrt(normal.x * normal.x + normal.y * normal.y); | |
normal.x /= length; | |
normal.y /= length; | |
//default min max | |
min1 = min2 = -1; | |
max1 = max2 = -1; | |
//project all vertices from poly1 onto axis | |
for(j = 0; j < l; ++j) { | |
dot = points1[j][0] * normal.x + points1[j][1] * normal.y; | |
if(dot > max1 || max1 === -1) max1 = dot; | |
if(dot < min1 || min1 === -1) min1 = dot; | |
} | |
//project all vertices from poly2 onto axis | |
for(j = 0; j < k; ++j) { | |
dot = points2[j][0] * normal.x + points2[j][1] * normal.y; | |
if(dot > max2 || max2 === -1) max2 = dot; | |
if(dot < min2 || min2 === -1) min2 = dot; | |
} | |
//calculate the minimum translation vector should be negative | |
interval = (min1 < min2) ? min2 - max1 : min1 - max2; | |
//exit early if positive | |
if(interval > 0) { | |
return false; | |
} | |
if(interval > MTV) MTV = interval; | |
} | |
return {overlap: MTV}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment