A simple method for detecting a convex polygon collision is the SAT (separating axis theorem), the separation axis theorem .
Principle: The polygon is projected onto a vector to see whether the projections of the two polygons overlap. If they do not overlap, the two polygons are considered separate, otherwise a vector is found to continue the projection. We don't need to compare a lot of vectors, because it's mathematically proven that the vertical vectors for each edge of the polygon are the vectors we need.
1.AABB
Let's start with AABB (Aabb is a rectangle on both sides parallel to the X-y axis)
To determine whether two aabb collide, we only need to project two times, respectively, on a vector parallel to the x and Y axes.
It can be seen that because the projections in the y-axis are separate, it is possible to conclude directly that the two aabb are separated.
functionAabbvsaabb (AABB1, aabb2) {//Check X Axis if(Aabb1.xmin >Aabb2.xmax)return false; if(Aabb1.xmax <aabb2.xmin)return false; //Check Y Axis if(Aabb1.ymin >Aabb2.ymax)return false; if(Aabb1.ymax <aabb2.ymin)return false; return true;}
Effect:---Click to run---
(Click to generate AABB, the collision becomes red, otherwise turn yellow)
2. Round
A round collision test can also be used on the SAT, which is a vector of two circles projected on the two center lines. Compares the radius and distance to the center, if the radius and greater than the center distance collide.
Code:
Note: Usually in order to optimize, it is the square instead of the root (sqrt good slow)
functioncirclevscircle (c1, c2) {varXSQR = C1.centerx-C2.centerx; XSQR*=Xsqr; varYSQR = C1.centery-C2.centery; YSQR*=Ysqr; //Get the distance^2 varDISTANCESQR = Xsqr +Ysqr; varRadiussum = C1.radius +C2.radius; if(Distancesqr <= radiussum*radiussum)return true; Else return false;}
Effect:---Click to run---
(Click to create a circle)
3. Polygon
(1) Find the vertical vector of all the edges of two polygons;
(2) Projecting two polygons onto the vertical vector to determine if the projections intersect, or if the two polygons do not intersect, otherwise select a vertical vector to continue the projection judgment.
Code:
functionPolyvspoly (P1, p2) {//check the normal in P1 for(vari = 0; i < p1.points.length-1; i++) { varEdge = Minus (P1.points[i], p1.points[i+1]); varnormal =Normal (Edge); varIsoverlap =checkcollide (Normal, p1, p2); if(!Isoverlap)return false; } //check Normal in P2 for(vari = 0; i < p2.points.length-1; i++) { varEdge = Minus (P2.points[i], p2.points[i+1]); varnormal =Normal (Edge); varIsoverlap =checkcollide (Normal, p1, p2); if(!Isoverlap)return false; } return true;}functioncheckcollide (axis, p1, p2) {varMin1 = Dot (p1.points[0], axis); varMax1 = Dot (p1.points[0], axis); for(varK = 1; K < P1.points.length; k++) { varv =Dot (P1.points[k], axis); if(V >max1) Max1=v; if(V <min1) min1=v; } varMin2 = Dot (p2.points[0], axis); varMax2 = Dot (p2.points[0], axis); for(varK = 1; K < P2.points.length; k++) { varv =Dot (P2.points[k], axis); if(V >max2) Max2=v; if(V <min2) min2=v; } if(!Isoverlap (min1, Max1, Min2, max2))return false; return true;}
Effect:---Click to run---
(Use the arrow keys to move, the collision turns red, otherwise turns yellow)
4. Circles and polygons
(1) Find the vertical vector for each edge of the polygon
(2) The circle and polygon are projected onto the vertical vector and then judged.
(In fact, the collision between the polygon is very similar, here is not wasted space)
Summarize:
The SAT is simple, which is projection + overlapping judgment.
The SAT is only suitable for convex bodies, after all, the vacancy in the middle of the concave body disappears after the projection.
Some websites about the SAT:
http://gamedevelopment.tutsplus.com/tutorials/collision-detection-with-the-separating-axis-theorem--gamedev-169
Polygon Collision--Sat method