<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <link rel="stylesheet" href="/index.css"> <title>Physics for Games</title> <link rel="shortcut icon" href="favicon/favicon.ico" type="image/x-icon"> <meta name="description" content="A place to learn all about real-time physics simulations through descriptions, code snippets, and example programs all written in C++ and OpenGL."> <meta name="og:description" content="A place to learn all about real-time physics simulations through descriptions, code snippets, and example programs all written in C++ and OpenGL."> </head> <body> <header> <h1><a title="physicsforgames.com" href="/">Physics for Games</a></h1> </header> <main> <nav> <ul class="outer-tree"> <li><a href="/">Introduction</a></li> <li> <span>🏀<span>2D</span></span> <ul class="inner-tree"> <li><label>Rigidbody</label></li> <li><a title="/2d/rigidbody/rigidbody_1.html" href="/2d/rigidbody/rigidbody_1.html">Linear Forces</a></li> <li><a title="/2d/rigidbody/rigidbody_2.html" href="/2d/rigidbody/rigidbody_2.html">Rotational Forces</a></li> <li><a title="/2d/rigidbody/rigidbody_3.html" href="/2d/rigidbody/rigidbody_3.html">Collisions</a></li> <li><label>Collisions</label></li> <li><a title="/2d/_collisions/rectangle_line.html" href="/2d/_collisions/rectangle_line.html">Rectangle-Line</a></li> <li><a title="/2d/_collisions/rectangle_rectangle.html" href="/2d/_collisions/rectangle_rectangle.html">Rectangle-Rectangle</a></li> <li><a title="/2d/_collisions/polygon_polygon.html" href="/2d/_collisions/polygon_polygon.html">Separating Axis Theorem</a></li> </ul> </li> <li> <span>🌠<span>3D</span></span> <ul class="inner-tree"> <li><label>Rigidbody</label></li> <li><a title="/3d/rigidbody.html" href="/3d/rigidbody.html">Rigidbody in 3D</a></li> </ul> </li> <li> <span>🔧<span>WebAssembly</span></span> <ul class="inner-tree"> <li><a title="/intro/intro.html" href="/intro/intro.html">Introduction</a></li> </ul> </li> <li> <span>🛈<span>About</span></span> <ul class="inner-tree"> <li><a title="/roadmap.html" href="/roadmap.html">Roadmap</a></li> </ul> </li> </ul> </nav> <script src="./polygon_polygon/dist/output.js"></script> <script> window.onload = function() { var lPlayElement = document.getElementById('gl_canvas_play'), lStopElement = document.getElementById('gl_canvas_stop'); lPlayElement.addEventListener('click', function() { lPlayElement.style.display = 'none'; lStopElement.style.display = 'block'; }); lStopElement.addEventListener('click', function() { lStopElement.style.display = 'none'; lPlayElement.style.display = 'block'; }); } </script> <article> <h1>Separating Axis Theorem</h1> <section> <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> </section> <section> <h2>Explanation of Separating Axis Theorem</h2> <p> SAT makes use of vector projection to figure out whether or not two concave polygons are intersecting. The way to think about it is this: <br/> <br/> Given two shapes <b>A</b> and <b>B</b>. Imagine we could isolate a single edge of A and shine a light on it. </p> </section> <section> <h2>Algorithm for Finding the Intersection</h2> <p> Given two polygons <b>A</b> and <b>B</b>: <ol> <li>For each edge on <b>A</b>, get the normal <i>n</i> of that edge.</li> <li>Project each vertex <i>v</i> of <b>A</b> onto <i>n</i>. Return the minimum and maximum projection of all vertices.</li> <li>Repeat Step 2 for polygon <b>B</b>.</li> <li>If the min and max projections found in Steps 2 and 3 do <b>NOT</b> overlap, the polygons are not intersecting. Return false.</li> <li>If the projections overlap for each edge of both shapes, the shapes are intersecting. Return true.</li> </ol> And that is all there is to <i>finding</i> the intersection between two convex polygons. </p> </section> <section> <h2>SAT Collision Resolution</h2> <p> Now that we know our objects have intersecting, we want to be able to send them tumbling away from each other to simulate a collision. To do this, we will need to find the following things: <ul> <li><b>Collision Normal</b>: in what direction, point towards object <b>A</b>, did the polygons intersect</li> <li><b>Point of Application</b>: at what point on each object did the objects first intersect</li> <li><b>Relative Velocity</b>: easily found by taking the difference between the two velocities. </ul> <h3>Collision Normal</h3> <p> </p> </p> </section> <section> <h2> Live Example of Intersection Detection </h2> <div class="opengl_canvas_container"> <canvas id="gl_canvas" width="800" height="600"></canvas> <button id="gl_canvas_play" class="play_button"> Play </button> <button id="gl_canvas_stop" class="stop_button"> Stop </button> </div> </section> <footer id="references"> <h2>References</h2> <ul> <li><a href="https://en.wikipedia.org/wiki/Vector_projection">Vector Projection Wikapedia</a></li> </ul> </footer> </article> </main> </body> </html>