summaryrefslogtreecommitdiff
path: root/2d/_collisions
diff options
context:
space:
mode:
authorMatthew Kosarek <mattkae@protonmail.com>2021-07-01 19:46:08 -0400
committerMatthew Kosarek <mattkae@protonmail.com>2021-07-01 19:46:08 -0400
commit4878f0fc6a039d220dd7adecb18d19c688ae50b0 (patch)
tree993893f1d894aedb350e86c759370c0e8c54c443 /2d/_collisions
parent9f968320c83ce79f98006dec71674feff4686e3b (diff)
(mkosarek) Decent SAT description for now
Diffstat (limited to '2d/_collisions')
-rw-r--r--2d/_collisions/polygon_polygon.html177
-rw-r--r--2d/_collisions/polygon_polygon.html.content61
-rw-r--r--2d/_collisions/polygon_polygon/snippet2.cpp117
3 files changed, 317 insertions, 38 deletions
diff --git a/2d/_collisions/polygon_polygon.html b/2d/_collisions/polygon_polygon.html
index f401385..69938ff 100644
--- a/2d/_collisions/polygon_polygon.html
+++ b/2d/_collisions/polygon_polygon.html
@@ -72,9 +72,21 @@
<p>
The Separating Axis Theorem (SAT) provides a way to find the intersection between any <i>n</i>-sided <a href='https://ianqvist.blogspot.com/2009/09/convex-polygon-based-collision.html'>convex</a> polygon or circle. In this tutorial, I will explain how this theorem works, and how you can use it to both detect and resolve collisions in your simulation.
</p>
+
+ <ul>
+ <li><a href='#explanation_of_separating_axis_theorem'>Explanation of Separating Axis Theorem</a></li>
+ <li><a href='#algorithm_for_finding_intersection'>Algorithm for Finding the Intersection</a></li>
+ <li><a href='#collision_resolution'>SAT Collision Resolution</a></li>
+ <ul>
+ <li><a href='#intersecting_edge'>Finding the Intersecting Edge</a></li>
+ <li><a href='#intersecting_point'>Finding the Intersecting Point</a></li>
+ </ul>
+ <li><a href='#algorithm_for_collision_resolution'>Algorithm for Collision Resolution</a></li>
+ <li><a href='#live_example'>Live Example</a></li>
+ </ul>
</section>
<section>
- <h2>Explanation of Separating Axis Theorem</h2>
+ <h2 id="#explanation_of_separating_axis_theorem">Explanation of Separating Axis Theorem</h2>
<p>
SAT makes use of vector projection to figure out whether or not two concave polygons are intersecting. I believe the best way to describe it is to show you the instance where two polygons do <b>not</b> intersect.
@@ -147,7 +159,7 @@
</p>
</section>
<section>
- <h2>Algorithm for Finding the Intersection</h2>
+ <h2 id='algorithm_for_finding_intersection'>Algorithm for Finding the Intersection</h2>
<p>
Given two polygons <b>A</b> and <b>B</b>:
@@ -215,7 +227,7 @@
</code></pre> </p>
</section>
<section>
- <h2>SAT Collision Resolution</h2>
+ <h2 id='collision_resolution'>SAT Collision Resolution</h2>
<p>
Now that we know that our objects have intersected, we want to send them tumbling away from one another in order to simulate a collision. To do this, we will need to find the following things:
<ul>
@@ -224,10 +236,7 @@
<li><b>Relative Velocity</b>: easily found by taking the difference between the two velocities.
</ul>
- To find these values, we must first find both the shape and the edge that caused the intersection in the first place. To do this, we will think about what we know so far and try to arrive at some intutitive understanding of it. Keep in mind that I am not a proof-minded person, so you will not be finding that here.
- <br/>
-
- <h3>Finding the Intersecting Edge</h3>
+ <h3 id='intersecting_edge'>Finding the Intersecting Edge</h3>
We can already figure out that the following two triangles intersect one another:
<br />
<br />
@@ -238,7 +247,9 @@
<br/><br/>
- We know that <b>A</b> can only intersect <b>B</b> if: (1) a vertex from <b>A</b> is inside of <b>B</b>, (2) an edge of <b>A</b> flatly intersects an edge of <b>B</b>, or (3) a vertex of <b>A</b> overlaps exactly a vertex of <b>B</b>. Honestly, for our purposes, scenarios 2 and 3 are quite unlikely, but we can explore them a bit just to see how we might resolve them. We will start with the first case, since it is more likely. We will start by drawing the axis defined by the leftmost edge of <b>B</b> with both polygons projected onto it:
+ We know that <b>A</b> can only intersect <b>B</b> if: (1) a vertex from <b>A</b> is inside of <b>B</b>, (2) an edge of <b>A</b> flatly intersects an edge of <b>B</b>, or (3) a vertex of <b>A</b> overlaps exactly a vertex of <b>B</b>. For our purposes, scenario 3 is quite unlikely, so we can ignore it for now. We will start with the first case, since it is the most likely.
+ <br /> <br />
+ The following drawing shows both of our objects projected onto the axis defined by object <b>B</b>'s leftmost edge:
<br /> <br />
@@ -247,22 +258,150 @@
</div>
<br/><br/>
- This is a poorly drawn picture, but you should be able to see that the bit in green represents the intersection between the projections of the two polygons. If we were to repeat this same exercise for every edge here, we'll begin to see something very interesting. And, if we take new shapes and continue this stategy, we can begin to come to a very elegant conclusion:
- <br/>
- <br/>
-
- <i>The intersecting edge will be the one where the projection of triangle <b>A</b> overlaps with the projection of triangle <b>B</b> the <b>least</b></i>!
-
- <br /> <br />
- I'm sure someone more inclined to proving mathematical truities would love to describe this to you, but, for all intents and purposes, this intutitive understanding is good enough for us. We just want to make games, anyhow.
- <br />
- <h3>Finding which point causes the intersection</h3>
+ If you were to repeat this exercise of projecting the shapes onto every axis of both shapes, you will begin to unconver an interesting truth: <i>The intersecting edge will be the one where the projection of triangle <b>A</b> overlaps with the projection of triangle <b>B</b> the <b>least</b></i>! This should be unsurprising if you consider it. If our simulation is running quickly enough, the point of object <b>A</b> that is penetrating the edge of object <b>B</b> will just <i>barely</i> be inside of <b>B</b>. At the same time, it <i>should</i> be the only point that is currently inside of B. Hence, the overlap of the projection on that axis will be from that edge of <b>B</b> to that point on <b>A</b>. Knowing that this edge caused the intersection, we now have the collision normal.
+ <br />
+ <h3 id='intersecting_point'>Finding which point causes the intersection</h3>
+ This part is made easy by the fact that we know which edge of object <b>B</b> caused the intersection in the first place. We know, then, that the intersecting point on object <b>A</b> must be the point that is currently inside of <b>B</b>. Simply put, this point will be the vertex of <b>A</b> that was projected onto that axis that is <i>closest</i> to the edge of <b>B</b>. This will be true so long as the simulation is properly fast and the object is not infinitesmley small (in which case, we're dealing with particle physics, and you shouldn't be using this tutorial).
</p>
</section>
<section>
- <h2>
+ <h2 id='algorithm_for_collision_resolution'>Algorithm for Collision Resolution</h2>
+
+ <p>
+
+ Given two polygons <b>A</b> and <b>B</b>:
+ <ol>
+ <li>Find the intersecton as before</li>
+ <li>While finding the intersection, keep track of the axis that the projection on object <b>A</b> overlapped with the corresponding projection on object <b>B</b> the least. Remember the edge that this that held this axis.</li>
+ <li>Using this axis, find out which point on the other object inside of the edge by comparing the distances from the two points on the edge to the two points projected onto the axis created by that edge.</li>
+ <li>Use the calcualted edge to find the normal and the overlap point to find the point of application.</li>
+ </ol>
+
+ And that is it! Here is the code for this algorithm:
+
+ <pre><code><span class="code_keyword">struct</span> IntersectionResult {
+ <span class="code_keyword">bool</span> intersect = false;
+ <span class="code_keyword">Vector2</span> collisionNormal;
+ <span class="code_keyword">Vector2</span> relativeVelocity;
+ <span class="code_keyword">Vector2</span> firstPointOfApplication;
+ <span class="code_keyword">Vector2</span> secondPointOfApplication;
+};
+
+<span class="code_keyword">struct</span> Edge {
+ <span class="code_keyword">Vector2</span> normal;
+ <span class="code_keyword">Vector2</span> start;
+ <span class="code_keyword">Vector2</span> end;
+};
+
+<span class="code_keyword">struct</span> SATResult {
+ Edge* minOverlapEdge = NULL; <span class="code_comment">// Edge that caused the intersection (on the 'first' shape)</span>
+ <span class="code_keyword">Vector2</span> overlapPoint; <span class="code_comment">// Point that caused the intersection (on the 'second' shape)</span>
+ <span class="code_keyword">float32</span> minOverlap = FLT_MAX; <span class="code_comment">// Smallest projection overlap</span>
+};
+
+<span class="code_keyword">struct</span> ProjectionResult {
+ <span class="code_keyword">Vector2</span> minVertex;
+ <span class="code_keyword">Vector2</span> maxVertex;
+ <span class="code_keyword">Vector2</span> projection;
+};
+
+<span class="code_comment">// Given the vertices in the shape, we find the min and max vertices that project</span>
+<span class="code_comment">// onto the axis. We also save which vertices were which so that we can resolve</span>
+<span class="code_comment">// the collision later.</span>
+ProjectionResult getProjection(Vector2* vertices, <span class="code_keyword">int</span> numVertices, <span class="code_keyword">Vector2</span> axis) {
+ ProjectionResult pr;
+ <span class="code_keyword">float32</span> min = axis.dot(vertices[0]);
+ <span class="code_keyword">float32</span> max = min;
+
+ for (int v = 1; v < numVertices; v++) {
+ <span class="code_keyword">float32</span> d = axis.dot(vertices[v]);
+
+ if (d < min) {
+ pr.minVertex = vertices[v];
+ min = d;
+ } else if (d > max) {
+ pr.maxVertex = vertices[v];
+ max = d;
+ }
+ }
+
+ pr.projection = <span class="code_keyword">Vector2</span> { min, max };
+ <span class="code_keyword">return</span> pr;
+}
+
+<span class="code_keyword">bool</span> projectionsOverlap(Vector2 first, <span class="code_keyword">Vector2</span> second) {
+ <span class="code_keyword">return</span> first.x <= second.y && second.x <= first.y;
+}
+
+<span class="code_keyword">float32</span> getProjectionOverlap(Vector2 first, <span class="code_keyword">Vector2</span> second) {
+ <span class="code_keyword">float32</span> e = MIN(first.y, second.y);
+ <span class="code_keyword">float32</span> f = MAX(first.x, second.x);
+ <span class="code_keyword">return</span> e - f;
+}
+
+<span class="code_keyword">bool</span> runSatForShapesEdges(SATResult* result, ConvexPolygon* first, ConvexPolygon* second) {
+ for (int i = 0; i < first->numVertices; i++) {
+ <span class="code_keyword">Vector2</span> normal = first->edges[i].normal;
+
+ ProjectionResult firstProj = getProjection(first->transformedVertices, first->numVertices, normal);
+ ProjectionResult secondProj = getProjection(second->transformedVertices, second->numVertices, normal);
+
+ if (!projectionsOverlap(firstProj.projection, secondProj.projection)) {
+ <span class="code_keyword">return</span> false;
+ }
+
+ <span class="code_keyword">float32</span> overlap = getProjectionOverlap(firstProj.projection, secondProj.projection);
+ if (overlap < result->minOverlap) {
+ result->minOverlap = overlap;
+ result->minOverlapEdge = &first->edges[i];
+
+ <span class="code_comment">// The overlapPoint will be the point on the other shape that penetrated the edge.</span>
+ <span class="code_comment">// If we caught the intersection reasonably early, it should be the point on 'second'</span>
+ <span class="code_comment">// that is nearest to the points on 'first'.</span>
+ <span class="code_keyword">float32</span> min1min2 = (firstProj.minVertex - secondProj.minVertex).length();
+ <span class="code_keyword">float32</span> min1max2 = (firstProj.minVertex - secondProj.maxVertex).length();
+ <span class="code_keyword">float32</span> max1max2 = (firstProj.maxVertex - secondProj.maxVertex).length();
+ <span class="code_keyword">float32</span> max1min2 = (firstProj.maxVertex - secondProj.minVertex).length();
+
+ <span class="code_keyword">float32</span> closest = MIN(min1min2, MIN(min1max2, MIN(max1max2, max1min2)));
+ if (closest == min1min2 || closest == max1min2) {
+ result->overlapPoint = secondProj.minVertex;
+ } else {
+ result->overlapPoint = secondProj.maxVertex;
+ }
+ }
+ }
+
+ <span class="code_keyword">return</span> true;
+}
+
+<span class="code_keyword">const</span> <span class="code_keyword">float32</span> EPSILON = 1.f;
+IntersectionResult getIntersection(ConvexPolygon* first, ConvexPolygon* second) {
+ IntersectionResult ir;
+ SATResult sat;
+
+ if (!runSatForShapesEdges(&sat, first, second)) {
+ <span class="code_keyword">return</span> ir;
+ }
+
+ if (!runSatForShapesEdges(&sat, second, first)) {
+ <span class="code_keyword">return</span> ir;
+ }
+
+ ir.intersect = true;
+ ir.relativeVelocity = first->body.velocity - second->body.velocity;
+ ir.collisionNormal = sat.minOverlapEdge->normal;
+ ir.firstPointOfApplication = sat.overlapPoint - first->body.position;
+ ir.secondPointOfApplication = sat.overlapPoint - second->body.position;;
+
+ <span class="code_keyword">return</span> ir;
+}
+</code></pre> </p>
+ </section>
+ <section>
+ <h2 id='live_example'>
Live Example of Intersection Detection
</h2>
<div class="opengl_canvas_container">
diff --git a/2d/_collisions/polygon_polygon.html.content b/2d/_collisions/polygon_polygon.html.content
index 4f99d71..f2a9253 100644
--- a/2d/_collisions/polygon_polygon.html.content
+++ b/2d/_collisions/polygon_polygon.html.content
@@ -20,9 +20,21 @@
<p>
The Separating Axis Theorem (SAT) provides a way to find the intersection between any <i>n</i>-sided <a href='https://ianqvist.blogspot.com/2009/09/convex-polygon-based-collision.html'>convex</a> polygon or circle. In this tutorial, I will explain how this theorem works, and how you can use it to both detect and resolve collisions in your simulation.
</p>
+
+ <ul>
+ <li><a href='#explanation_of_separating_axis_theorem'>Explanation of Separating Axis Theorem</a></li>
+ <li><a href='#algorithm_for_finding_intersection'>Algorithm for Finding the Intersection</a></li>
+ <li><a href='#collision_resolution'>SAT Collision Resolution</a></li>
+ <ul>
+ <li><a href='#intersecting_edge'>Finding the Intersecting Edge</a></li>
+ <li><a href='#intersecting_point'>Finding the Intersecting Point</a></li>
+ </ul>
+ <li><a href='#algorithm_for_collision_resolution'>Algorithm for Collision Resolution</a></li>
+ <li><a href='#live_example'>Live Example</a></li>
+ </ul>
</section>
<section>
- <h2>Explanation of Separating Axis Theorem</h2>
+ <h2 id="#explanation_of_separating_axis_theorem">Explanation of Separating Axis Theorem</h2>
<p>
SAT makes use of vector projection to figure out whether or not two concave polygons are intersecting. I believe the best way to describe it is to show you the instance where two polygons do <b>not</b> intersect.
@@ -95,7 +107,7 @@
</p>
</section>
<section>
- <h2>Algorithm for Finding the Intersection</h2>
+ <h2 id='algorithm_for_finding_intersection'>Algorithm for Finding the Intersection</h2>
<p>
Given two polygons <b>A</b> and <b>B</b>:
@@ -113,7 +125,7 @@
</p>
</section>
<section>
- <h2>SAT Collision Resolution</h2>
+ <h2 id='collision_resolution'>SAT Collision Resolution</h2>
<p>
Now that we know that our objects have intersected, we want to send them tumbling away from one another in order to simulate a collision. To do this, we will need to find the following things:
<ul>
@@ -122,10 +134,7 @@
<li><b>Relative Velocity</b>: easily found by taking the difference between the two velocities.
</ul>
- To find these values, we must first find both the shape and the edge that caused the intersection in the first place. To do this, we will think about what we know so far and try to arrive at some intutitive understanding of it. Keep in mind that I am not a proof-minded person, so you will not be finding that here.
- <br/>
-
- <h3>Finding the Intersecting Edge</h3>
+ <h3 id='intersecting_edge'>Finding the Intersecting Edge</h3>
We can already figure out that the following two triangles intersect one another:
<br />
<br />
@@ -136,7 +145,9 @@
<br/><br/>
- We know that <b>A</b> can only intersect <b>B</b> if: (1) a vertex from <b>A</b> is inside of <b>B</b>, (2) an edge of <b>A</b> flatly intersects an edge of <b>B</b>, or (3) a vertex of <b>A</b> overlaps exactly a vertex of <b>B</b>. Honestly, for our purposes, scenarios 2 and 3 are quite unlikely, but we can explore them a bit just to see how we might resolve them. We will start with the first case, since it is more likely. We will start by drawing the axis defined by the leftmost edge of <b>B</b> with both polygons projected onto it:
+ We know that <b>A</b> can only intersect <b>B</b> if: (1) a vertex from <b>A</b> is inside of <b>B</b>, (2) an edge of <b>A</b> flatly intersects an edge of <b>B</b>, or (3) a vertex of <b>A</b> overlaps exactly a vertex of <b>B</b>. For our purposes, scenario 3 is quite unlikely, so we can ignore it for now. We will start with the first case, since it is the most likely.
+ <br /> <br />
+ The following drawing shows both of our objects projected onto the axis defined by object <b>B</b>'s leftmost edge:
<br /> <br />
@@ -145,22 +156,34 @@
</div>
<br/><br/>
- This is a poorly drawn picture, but you should be able to see that the bit in green represents the intersection between the projections of the two polygons. If we were to repeat this same exercise for every edge here, we'll begin to see something very interesting. And, if we take new shapes and continue this stategy, we can begin to come to a very elegant conclusion:
- <br/>
- <br/>
-
- <i>The intersecting edge will be the one where the projection of triangle <b>A</b> overlaps with the projection of triangle <b>B</b> the <b>least</b></i>!
-
- <br /> <br />
- I'm sure someone more inclined to proving mathematical truities would love to describe this to you, but, for all intents and purposes, this intutitive understanding is good enough for us. We just want to make games, anyhow.
- <br />
- <h3>Finding which point causes the intersection</h3>
+ If you were to repeat this exercise of projecting the shapes onto every axis of both shapes, you will begin to unconver an interesting truth: <i>The intersecting edge will be the one where the projection of triangle <b>A</b> overlaps with the projection of triangle <b>B</b> the <b>least</b></i>! This should be unsurprising if you consider it. If our simulation is running quickly enough, the point of object <b>A</b> that is penetrating the edge of object <b>B</b> will just <i>barely</i> be inside of <b>B</b>. At the same time, it <i>should</i> be the only point that is currently inside of B. Hence, the overlap of the projection on that axis will be from that edge of <b>B</b> to that point on <b>A</b>. Knowing that this edge caused the intersection, we now have the collision normal.
+ <br />
+ <h3 id='intersecting_point'>Finding which point causes the intersection</h3>
+ This part is made easy by the fact that we know which edge of object <b>B</b> caused the intersection in the first place. We know, then, that the intersecting point on object <b>A</b> must be the point that is currently inside of <b>B</b>. Simply put, this point will be the vertex of <b>A</b> that was projected onto that axis that is <i>closest</i> to the edge of <b>B</b>. This will be true so long as the simulation is properly fast and the object is not infinitesmley small (in which case, we're dealing with particle physics, and you shouldn't be using this tutorial).
+ </p>
+ </section>
+ <section>
+ <h2 id='algorithm_for_collision_resolution'>Algorithm for Collision Resolution</h2>
+
+ <p>
+
+ Given two polygons <b>A</b> and <b>B</b>:
+ <ol>
+ <li>Find the intersecton as before</li>
+ <li>While finding the intersection, keep track of the axis that the projection on object <b>A</b> overlapped with the corresponding projection on object <b>B</b> the least. Remember the edge that this that held this axis.</li>
+ <li>Using this axis, find out which point on the other object inside of the edge by comparing the distances from the two points on the edge to the two points projected onto the axis created by that edge.</li>
+ <li>Use the calcualted edge to find the normal and the overlap point to find the point of application.</li>
+ </ol>
+
+ And that is it! Here is the code for this algorithm:
+
+ #SNIPPET polygon_polygon/snippet2.cpp
</p>
</section>
<section>
- <h2>
+ <h2 id='live_example'>
Live Example of Intersection Detection
</h2>
<div class="opengl_canvas_container">
diff --git a/2d/_collisions/polygon_polygon/snippet2.cpp b/2d/_collisions/polygon_polygon/snippet2.cpp
new file mode 100644
index 0000000..8cbdcbe
--- /dev/null
+++ b/2d/_collisions/polygon_polygon/snippet2.cpp
@@ -0,0 +1,117 @@
+struct IntersectionResult {
+ bool intersect = false;
+ Vector2 collisionNormal;
+ Vector2 relativeVelocity;
+ Vector2 firstPointOfApplication;
+ Vector2 secondPointOfApplication;
+};
+
+struct Edge {
+ Vector2 normal;
+ Vector2 start;
+ Vector2 end;
+};
+
+struct SATResult {
+ Edge* minOverlapEdge = NULL; // Edge that caused the intersection (on the 'first' shape)
+ Vector2 overlapPoint; // Point that caused the intersection (on the 'second' shape)
+ float32 minOverlap = FLT_MAX; // Smallest projection overlap
+};
+
+struct ProjectionResult {
+ Vector2 minVertex;
+ Vector2 maxVertex;
+ Vector2 projection;
+};
+
+// Given the vertices in the shape, we find the min and max vertices that project
+// onto the axis. We also save which vertices were which so that we can resolve
+// the collision later.
+ProjectionResult getProjection(Vector2* vertices, int numVertices, Vector2 axis) {
+ ProjectionResult pr;
+ float32 min = axis.dot(vertices[0]);
+ float32 max = min;
+
+ for (int v = 1; v < numVertices; v++) {
+ float32 d = axis.dot(vertices[v]);
+
+ if (d < min) {
+ pr.minVertex = vertices[v];
+ min = d;
+ } else if (d > max) {
+ pr.maxVertex = vertices[v];
+ max = d;
+ }
+ }
+
+ pr.projection = Vector2 { min, max };
+ return pr;
+}
+
+bool projectionsOverlap(Vector2 first, Vector2 second) {
+ return first.x <= second.y && second.x <= first.y;
+}
+
+float32 getProjectionOverlap(Vector2 first, Vector2 second) {
+ float32 e = MIN(first.y, second.y);
+ float32 f = MAX(first.x, second.x);
+ return e - f;
+}
+
+bool runSatForShapesEdges(SATResult* result, ConvexPolygon* first, ConvexPolygon* second) {
+ for (int i = 0; i < first->numVertices; i++) {
+ Vector2 normal = first->edges[i].normal;
+
+ ProjectionResult firstProj = getProjection(first->transformedVertices, first->numVertices, normal);
+ ProjectionResult secondProj = getProjection(second->transformedVertices, second->numVertices, normal);
+
+ if (!projectionsOverlap(firstProj.projection, secondProj.projection)) {
+ return false;
+ }
+
+ float32 overlap = getProjectionOverlap(firstProj.projection, secondProj.projection);
+ if (overlap < result->minOverlap) {
+ result->minOverlap = overlap;
+ result->minOverlapEdge = &first->edges[i];
+
+ // The overlapPoint will be the point on the other shape that penetrated the edge.
+ // If we caught the intersection reasonably early, it should be the point on 'second'
+ // that is nearest to the points on 'first'.
+ float32 min1min2 = (firstProj.minVertex - secondProj.minVertex).length();
+ float32 min1max2 = (firstProj.minVertex - secondProj.maxVertex).length();
+ float32 max1max2 = (firstProj.maxVertex - secondProj.maxVertex).length();
+ float32 max1min2 = (firstProj.maxVertex - secondProj.minVertex).length();
+
+ float32 closest = MIN(min1min2, MIN(min1max2, MIN(max1max2, max1min2)));
+ if (closest == min1min2 || closest == max1min2) {
+ result->overlapPoint = secondProj.minVertex;
+ } else {
+ result->overlapPoint = secondProj.maxVertex;
+ }
+ }
+ }
+
+ return true;
+}
+
+const float32 EPSILON = 1.f;
+IntersectionResult getIntersection(ConvexPolygon* first, ConvexPolygon* second) {
+ IntersectionResult ir;
+ SATResult sat;
+
+ if (!runSatForShapesEdges(&sat, first, second)) {
+ return ir;
+ }
+
+ if (!runSatForShapesEdges(&sat, second, first)) {
+ return ir;
+ }
+
+ ir.intersect = true;
+ ir.relativeVelocity = first->body.velocity - second->body.velocity;
+ ir.collisionNormal = sat.minOverlapEdge->normal;
+ ir.firstPointOfApplication = sat.overlapPoint - first->body.position;
+ ir.secondPointOfApplication = sat.overlapPoint - second->body.position;;
+
+ return ir;
+}