LearnOpenGL

Translation in progress of learnopengl.com.
git clone https://git.mtkn.jp/LearnOpenGL
Log | Files | Refs

Collision-detection.html (24759B)


      1 <!DOCTYPE html>
      2 <html lang="ja"> 
      3 <head>
      4     <meta charset="utf-8"/>
      5     <title>LearnOpenGL</title>
      6     <link rel="shortcut icon" type="image/ico" href="/favicon.ico"  />
      7 	<link rel="stylesheet" href="../static/style.css" />
      8 	<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"> </script>
      9 	<script src="/static/functions.js"></script>
     10 </head>
     11 <body>
     12 	<nav>
     13 <ol>
     14 	<li id="Introduction">
     15 		<a href="https://learnopengl.com/Introduction">はじめに</a>
     16 	</li>
     17 	<li id="Getting-started">
     18 		<span class="closed">入門</span>
     19 		<ol>
     20 			<li id="Getting-started/OpenGL">
     21 				<a href="https://learnopengl.com/Getting-started/OpenGL">OpenGL </a>
     22 			</li>
     23 			<li id="Getting-started/Creating-a-window">
     24 				<a href="https://learnopengl.com/Getting-started/Creating-a-window">ウィンドウの作成</a>
     25 			</li>
     26 			<li id="Getting-started/Hello-Window">
     27 				<a href="https://learnopengl.com/Getting-started/Hello-Window">最初のウィンドウ</a>
     28 			</li>
     29 			<li id="Getting-started/Hello-Triangle">
     30 				<a href="https://learnopengl.com/Getting-started/Hello-Triangle">最初の三角形</a>
     31 			</li>
     32 			<li id="Getting-started/Shaders">
     33 				<a href="https://learnopengl.com/Getting-started/Shaders">シェーダー</a>
     34 			</li>
     35 			<li id="Getting-started/Textures">
     36 				<a href="https://learnopengl.com/Getting-started/Textures">テクスチャ</a>
     37 			</li>
     38 			<li id="Getting-started/Transformations">
     39 				<a href="https://learnopengl.com/Getting-started/Transformations">座標変換</a>
     40 			</li>
     41 			<li id="Getting-started/Coordinate-Systems">
     42 				<a href="https://learnopengl.com/Getting-started/Coordinate-Systems">座標系</a>
     43 			</li>
     44 			<li id="Getting-started/Camera">
     45 				<a href="https://learnopengl.com/Getting-started/Camera">カメラ</a>
     46 			</li>
     47 			<li id="Getting-started/Review">
     48 				<a href="https://learnopengl.com/Getting-started/Review">まとめ</a>
     49 			</li>
     50 		</ol>
     51 	</li>
     52 	<li id="Lighting">
     53 		<span class="closed">Lighting </span>
     54 		<ol>
     55 			<li id="Lighting/Colors">
     56 				<a href="https://learnopengl.com/Lighting/Colors">Colors </a>
     57 			</li>
     58 			<li id="Lighting/Basic-Lighting">
     59 				<a href="https://learnopengl.com/Lighting/Basic-Lighting">Basic Lighting </a>
     60 			</li>
     61 			<li id="Lighting/Materials">
     62 				<a href="https://learnopengl.com/Lighting/Materials">Materials </a>
     63 			</li>
     64 			<li id="Lighting/Lighting-maps">
     65 				<a href="https://learnopengl.com/Lighting/Lighting-maps">Lighting maps </a>
     66 			</li>
     67 			<li id="Lighting/Light-casters">
     68 				<a href="https://learnopengl.com/Lighting/Light-casters">Light casters </a>
     69 			</li>
     70 			<li id="Lighting/Multiple-lights">
     71 				<a href="https://learnopengl.com/Lighting/Multiple-lights">Multiple lights </a>
     72 			</li>
     73 			<li id="Lighting/Review">
     74 				<a href="https://learnopengl.com/Lighting/Review">Review </a>
     75 			</li>
     76 		</ol>
     77 	</li>
     78 	<li id="Model-Loading">
     79 		<span class="closed">Model Loading </span>
     80 		<ol>
     81 			<li id="Model-Loading/Assimp">
     82 				<a href="https://learnopengl.com/Model-Loading/Assimp">Assimp </a>
     83 			</li>
     84 			<li id="Model-Loading/Mesh">
     85 				<a href="https://learnopengl.com/Model-Loading/Mesh">Mesh </a>
     86 			</li>
     87 			<li id="Model-Loading/Model">
     88 				<a href="https://learnopengl.com/Model-Loading/Model">Model </a>
     89 			</li>
     90 		</ol>
     91 	</li>
     92 	<li id="Advanced-OpenGL">
     93 		<span class="closed">Advanced OpenGL </span>
     94 		<ol>
     95 			<li id="Advanced-OpenGL/Depth-testing">
     96 				<a href="https://learnopengl.com/Advanced-OpenGL/Depth-testing">Depth testing </a>
     97 			</li>
     98 			<li id="Advanced-OpenGL/Stencil-testing">
     99 				<a href="https://learnopengl.com/Advanced-OpenGL/Stencil-testing">Stencil testing </a>
    100 			</li>
    101 			<li id="Advanced-OpenGL/Blending">
    102 				<a href="https://learnopengl.com/Advanced-OpenGL/Blending">Blending </a>
    103 			</li>
    104 			<li id="Advanced-OpenGL/Face-culling">
    105 				<a href="https://learnopengl.cm/Advanced-OpenGL/Face-culling">Face culling </a>
    106 			</li>
    107 			<li id="Advanced-OpenGL/Framebuffers">
    108 				<a href="https://learnopengl.com/Advanced-OpenGL/Framebuffers">Framebuffers </a>
    109 			</li>
    110 			<li id="Advanced-OpenGL/Cubemaps">
    111 				<a href="https://learnopengl.com/Advanced-OpenGL/Cubemaps">Cubemaps </a>
    112 			</li>
    113 			<li id="Advanced-OpenGL/Advanced-Data">
    114 				<a href="https://learnopengl.com/Advanced-OpenGL/Advanced-Data">Advanced Data </a>
    115 			</li>
    116 			<li id="Advanced-OpenGL/Advanced-GLSL">
    117 				<a href="https://learnopengl.com/Advanced-OpenGL/Advanced-GLSL">Advanced GLSL </a>
    118 			</li>
    119 			<li id="Advanced-OpenGL/Geometry-Shader">
    120 				<a href="https://learnopengl.com/Advanced-OpenGL/Geometry-Shader">Geometry Shader </a>
    121 			</li>
    122 			<li id="Advanced-OpenGL/Instancing">
    123 				<a href="https://learnopengl.com/Advanced-OpenGL/Instancing">Instancing </a>
    124 			</li>
    125 			<li id="Advanced-OpenGL/Anti-Aliasing">
    126 				<a href="https://learnopengl.com/Advanced-OpenGL/Anti-Aliasing">Anti Aliasing </a>
    127 			</li>
    128 		</ol>
    129 	</li>
    130 	<li id="Advanced-Lighting">
    131 		<span class="closed">Advanced Lighting </span>
    132 		<ol>
    133 			<li id="Advanced-Lighting/Advanced-Lighting">
    134 				<a href="https://learnopengl.com/Advanced-Lighting/Advanced-Lighting">Advanced Lighting </a>
    135 			</li>
    136 			<li id="Advanced-Lighting/Gamma-Correction">
    137 				<a href="https://learnopengl.com/Advanced-Lighting/Gamma-Correction">Gamma Correction </a>
    138 			</li>
    139 			<li id="Advanced-Lighting/Shadows">
    140 				<span class="closed">Shadows </span>
    141 				<ol>
    142 					<li id="Advanced-Lighting/Shadows/Shadow-Mapping">
    143 						<a href="https://learnopengl.com/Advanced-Lighting/Shadows/Shadow-Mapping">Shadow Mapping </a>
    144 					</li>
    145 					<li id="Advanced-Lighting/Shadows/Point-Shadows">
    146 						<a href="https://learnopengl.com/Advanced-Lighting/Shadows/Point-Shadows">Point Shadows </a>
    147 					</li>
    148 				</ol>
    149 			</li>
    150 			<li id="Advanced-Lighting/Normal-Mapping">
    151 				<a href="https://learnopengl.com/Advanced-Lighting/Normal-Mapping">Normal Mapping </a>
    152 			</li>
    153 			<li id="Advanced-Lighting/Parallax-Mapping">
    154 				<a href="https://learnopengl.com/Advanced-Lighting/Parallax-Mapping">Parallax Mapping </a>
    155 			</li>
    156 			<li id="Advanced-Lighting/HDR">
    157 				<a href="https://learnopengl.com/Advanced-Lighting/HDR">HDR </a>
    158 			</li>
    159 			<li id="Advanced-Lighting/Bloom">
    160 				<a href="https://learnopengl.com/Advanced-Lighting/Bloom">Bloom </a>
    161 			</li>
    162 			<li id="Advanced-Lighting/Deferred-Shading">
    163 				<a href="https://learnopengl.com/Advanced-Lighting/Deferred-Shading">Deferred Shading </a>
    164 			</li>
    165 			<li id="Advanced-Lighting/SSAO">
    166 				<a href="https://learnopengl.com/Advanced-Lighting/SSAO">SSAO </a>
    167 			</li>
    168 		</ol>
    169 	</li>
    170 	<li id="PBR">
    171 		<span class="closed">PBR </span>
    172 		<ol>
    173 			<li id="PBR/Theory">
    174 				<a href="https://learnopengl.com/PBR/Theory">Theory </a>
    175 			</li>
    176 			<li id="PBR/Lighting">
    177 				<a href="https://learnopengl.com/PBR/Lighting">Lighting </a>
    178 			</li>
    179 			<li id="PBR/IBL">
    180 				<span class="closed">IBL </span>
    181 				<ol>
    182 					<li id="PBR/IBL/Diffuse-irradiance">
    183 						<a href="https://learnopengl.com/PBR/IBL/Diffuse-irradiance">Diffuse irradiance </a>
    184 					</li>
    185 					<li id="PBR/IBL/Specular-IBL">
    186 						<a href="https://learnopengl.com/PBR/IBL/Specular-IBL">Specular IBL </a>
    187 					</li>
    188 				</ol>
    189 			</li>
    190 		</ol>
    191 	</li>
    192 	<li id="In-Practice">
    193 		<span class="closed">In Practice </span>
    194 		<ol>
    195 			<li id="In-Practice/Debugging">
    196 				<a href="https://learnopengl.com/In-Practice/Debugging">Debugging </a>
    197 			</li>
    198 			<li id="In-Practice/Text-Rendering">
    199 				<a href="https://learnopengl.com/In-Practice/Text-Rendering">Text Rendering </a>
    200 			</li>
    201 			<li id="In-Practice/2D-Game">
    202 				<span class="closed">2D Game </span>
    203 				<ol>
    204 					<li id="In-Practice/2D-Game/Breakout">
    205 						<a href="https://learnopengl.com/In-Practice/2D-Game/Breakout">Breakout </a>
    206 					</li>
    207 					<li id="In-Practice/2D-Game/Setting-up">
    208 						<a href="https://learnopengl.com/In-Practice/2D-Game/Setting-up">Setting up </a>
    209 					</li>
    210 					<li id="In-Practice/2D-Game/Rendering-Sprites">
    211 						<a href="https://learnopengl.com/In-Practice/2D-Game/Rendering-Sprites">Rendering Sprites </a>
    212 					</li>
    213 					<li id="In-Practice/2D-Game/Levels">
    214 						<a href="https://learnopengl.com/In-Practice/2D-Game/Levels">Levels </a>
    215 					</li>
    216 					<li id="In-Practice/2D-Game/Collisions">
    217 						<span class="closed">Collisions </span>
    218 						<ol>
    219 							<li id="In-Practice/2D-Game/Collisions/Ball">
    220 								<a href="https://learnopengl.com/In-Practice/2D-Game/Collisions/Ball">Ball </a>
    221 							</li>
    222 							<li id="In-Practice/2D-Game/Collisions/Collision-detection">
    223 								<a href="https://learnopengl.com/In-Practice/2D-Game/Collisions/Collision-detection">Collision detection </a>
    224 							</li>
    225 							<li id="In-Practice/2D-Game/Collisions/Collision-resolution">
    226 								<a href="https://learnopengl.com/In-Practice/2D-Game/Collisions/Collision-resolution">Collision resolution </a>
    227 							</li>
    228 						</ol>
    229 					</li>
    230 					<li id="In-Practice/2D-Game/Particles">
    231 						<a href="https://learnopengl.com/In-Practice/2D-Game/Particles">Particles </a>
    232 					</li>
    233 					<li id="In-Practice/2D-Game/Postprocessing">
    234 						<a href="https://learnopengl.com/In-Practice/2D-Game/Postprocessing">Postprocessing </a>
    235 					</li>
    236 					<li id="In-Practice/2D-Game/Powerups">
    237 						<a href="https://learnopengl.com/In-Practice/2D-Game/Powerups">Powerups </a>
    238 					</li>
    239 					<li id="In-Practice/2D-Game/Audio">
    240 						<a href="https://learnopengl.com/In-Practice/2D-Game/Audio">Audio </a>
    241 					</li>
    242 					<li id="In-Practice/2D-Game/Render-text">
    243 						<a href="https://learnopengl.com/In-Practice/2D-Game/Render-text">Render text </a>
    244 					</li>
    245 					<li id="In-Practice/2D-Game/Final-thoughts">
    246 						<a href="https://learnopengl.com/In-Practice/2D-Game/Final-thoughts">Final thoughts </a>
    247 					</li>
    248 				</ol>
    249 			</li>
    250 		</ol>
    251 	</li>
    252 	<li id="Guest-Articles">
    253 		<span class="closed">Guest Articles </span>
    254 		<ol>
    255 			<li id="Guest-Articles/How-to-publish">
    256 				<a href="https://learnopengl.com/Guest-Articles/How-to-publish">How to publish </a>
    257 			</li>
    258 			<li id="Guest-Articles/2020">
    259 				<span class="closed">2020 </span>
    260 				<ol>
    261 					<li id="Guest-Articles/2020/OIT">
    262 						<span class="closed">OIT </span>
    263 						<ol>
    264 							<li id="Guest-Articles/2020/OIT/Introduction">
    265 								<a href="https://learnopengl.com/Guest-Articles/2020/OIT/Introduction">Introduction </a>
    266 							</li>
    267 							<li id="Guest-Articles/2020/OIT/Weighted-Blended">
    268 								<a href="https://learnopengl.com/Guest-Articles/2020/OIT/Weighted-Blended">Weighted Blended </a>
    269 							</li>
    270 						</ol>
    271 					</li>
    272 					<li id="Guest-Articles/2020/Skeletal-Animation">
    273 						<a href="https://learnopengl.com/Guest-Articles/2020/Skeletal-Animation">Skeletal Animation </a>
    274 					</li>
    275 				</ol>
    276 			</li>
    277 			<li id="Guest-Articles/2021">
    278 				<span class="closed">2021 </span>
    279 				<ol>
    280 					<li id="Guest-Articles/2021/CSM">
    281 						<a href="https://learnopengl.com/Guest-Articles/2021/CSM">CSM </a>
    282 					</li>
    283 					<li id="Guest-Articles/2021/Scene">
    284 						<span class="closed">Scene </span>
    285 						<ol>
    286 							<li id="Guest-Articles/2021/Scene/Scene-Graph">
    287 								<a href="https://learnopengl.com/Guest-Articles/2021/Scene/Scene-Graph">Scene Graph </a>
    288 							</li>
    289 							<li id="Guest-Articles/2021/Scene/Frustum-Culling">
    290 								<a href="https://learnopengl.com/Guest-Articles/2021/Scene/Frustum-Culling">Frustum Culling </a>
    291 							</li>
    292 						</ol>
    293 					</li>
    294 					<li id="Guest-Articles/2021/Tessellation">
    295 						<span class="closed">Tessellation </span>
    296 						<ol>
    297 							<li id="Guest-Articles/2021/Tessellation/Height-map">
    298 								<a href="https://learnopengl.com/Guest-Articles/2021/Tessellation/Height-map">Height map </a>
    299 							</li>
    300 						</ol>
    301 					</li>
    302 				</ol>
    303 			</li>
    304 		</ol>
    305 	</li>
    306 	<li id="Code-repository">
    307 		<a href="https://learnopengl.com/Code-repository">Code repository </a>
    308 	</li>
    309 	<li id="Translations">
    310 		<a href="https://learnopengl.com/Translations">Translations </a>
    311 	</li>
    312 	<li id="About">
    313 		<a href="https://learnopengl.com/About">About </a>
    314 	</li>
    315 </ol>
    316 	</nav>
    317 	<main>
    318     <h1 id="content-title">Collision detection</h1>
    319 <h1 id="content-url" style='display:none;'>In-Practice/2D-Game/Collisions/Collision-detection</h1>
    320 <p>
    321   When trying to determine if a collision occurs between two objects, we generally do not use the vertex data of the objects themselves since these objects often have complicated shapes; this in turn makes the collision detection complicated. For this reason, it is a common practice to use more simple shapes (that usually have a nice mathematical definition) for collision detection that we <em>overlay</em> on top of the original object. We then check for collisions based on these simple shapes; this makes the code easier and saves a lot of performance. A few examples of such <def>collision shapes</def> are circles, spheres, rectangles, and boxes; these are a lot simpler to work with compared to arbitrary meshes with hundreds of triangles.
    322 </p>
    323 
    324 <p>
    325   While the simple shapes do give us easier and more efficient collision detection algorithms, they share a common disadvantage in that these shapes usually do not fully surround the object. The effect is that a collision may be detected that didn't really collide with the actual object; one should always keep in mind that these shapes are just approximations of the real shapes.  
    326 </p>
    327 
    328 <h2>AABB - AABB collisions</h2>  
    329 <p>
    330   AABB stands for <def>axis-aligned bounding box</def>, a rectangular collision shape aligned to the base axes of the scene, which in 2D aligns to the x and y axis. Being axis-aligned means the rectangular box has no rotation and its edges are parallel to the base axes of the scene (e.g. left and right edge are parallel to the y axis). The fact that these boxes are always aligned to the axes of the scene makes calculations easier. Here we surround the ball object with an AABB:
    331 </p>
    332 
    333 <img src="/img/in-practice/breakout/collisions_ball_aabb.png" alt="AABB on top of ball in OpenGL"/>
    334 
    335 
    336 
    337 <p>
    338   Almost all the objects in Breakout are rectangular based objects, so it makes perfect sense to use axis aligned bounding boxes for detecting collisions. This is exactly what we're going to do.
    339 </p>
    340 
    341 <p>
    342   Axis aligned bounding boxes can be defined in several ways. One of them is to define an AABB by a top-left and a bottom-right position. The <fun>GameObject</fun> class that we defined already contains a top-left position (its <var>Position</var> vector), and we can easily calculate its bottom-right position by adding its size to the top-left position vector (<var>Position</var><code> + </code><var>Size</var>). Effectively, each <fun>GameObject</fun> contains an AABB that we can use for collisions.
    343 </p>
    344 
    345 <p>
    346   So how do we check for collisions? A collision occurs when two collision shapes enter each other's regions e.g. the shape that determines the first object is in some way inside the shape of the second object. For AABBs this is quite easy to determine due to the fact that they're aligned to the scene's axes: we check for each axis if the two object' edges on that axis overlap. So we check if the horizontal edges overlap, and if the vertical edges overlap of both objects. If both the horizontal <strong>and</strong> vertical edges overlap we have a collision.
    347 </p>
    348 
    349 <img src="/img/in-practice/breakout/collisions_overlap.png" class="clean" alt="Image of overlapping edges of AABB"/>
    350 
    351 <p>
    352   Translating this concept to code is relatively straightforward. We check for overlap on both axes and if so, return a collision:
    353 </p>
    354 
    355 <pre><code>
    356 bool CheckCollision(GameObject &one, GameObject &two) // AABB - AABB collision
    357 {
    358     // collision x-axis?
    359     bool collisionX = one.Position.x + one.Size.x &gt;= two.Position.x &&
    360         two.Position.x + two.Size.x &gt;= one.Position.x;
    361     // collision y-axis?
    362     bool collisionY = one.Position.y + one.Size.y &gt;= two.Position.y &&
    363         two.Position.y + two.Size.y &gt;= one.Position.y;
    364     // collision only if on both axes
    365     return collisionX && collisionY;
    366 }  
    367 </code></pre>
    368 
    369 <p>
    370   We check if the right side of the first object is greater than the left side of the second object <strong>and</strong> if the second object's right side is greater than the first object's left  side; similarly for the vertical axis. If you have trouble visualizing this, try to draw the edges/rectangles on paper and determine this for yourself.
    371 </p>
    372 
    373 <p>
    374   To keep the collision code a bit more organized we add an extra function to the <fun>Game</fun> class:
    375 </p>
    376 
    377 <pre><code>
    378 class Game
    379 {
    380     public:
    381         [...]
    382         void DoCollisions();
    383 };
    384 </code></pre>
    385 
    386 <p>
    387   Within <fun>DoCollisions</fun>, we check for collisions between the ball object and each brick of the level. If we detect a collision, we set the brick's <var>Destroyed</var> property to <code>true</code>, which instantly stops the level from rendering this brick:
    388 </p>
    389 
    390 <pre><code>
    391 void Game::DoCollisions()
    392 {
    393     for (GameObject &box : this-&gt;Levels[this-&gt;Level].Bricks)
    394     {
    395         if (!box.Destroyed)
    396         {
    397             if (CheckCollision(*Ball, box))
    398             {
    399                 if (!box.IsSolid)
    400                     box.Destroyed = true;
    401             }
    402         }
    403     }
    404 }  
    405 </code></pre>
    406 
    407 <p>
    408   Then we also need to update the game's <fun>Update</fun> function:
    409 </p>
    410 
    411 <pre><code>
    412 void Game::Update(float dt)
    413 {
    414     // update objects
    415     Ball->Move(dt, this->Width);
    416     // check for collisions
    417     this->DoCollisions();
    418 }  
    419 </code></pre>
    420 
    421 
    422 <p>
    423   If we run the code now, the ball should detect collisions with each of the bricks and if the brick is not solid, the brick is destroyed. If you run the game now it'll look something like this:
    424 </p>
    425 
    426 <div class="video paused" onclick="ClickVideo(this)">
    427   <video width="600" height="450" loop>
    428     <source src="/video/in-practice/breakout/collisions.mp4" type="video/mp4" />
    429     <img src="/img/in-practice/breakout/collisions.png" class="clean"/>
    430   </video>
    431 </div>
    432 
    433 <p>
    434   While the collision detection does work, it's not very precise since the ball's rectangular collision shape collides with most of the bricks without the ball directly touching them. Let's see if we can figure out a more precise collision detection technique.
    435 </p>
    436 
    437 <h2>AABB - Circle collision detection</h2>
    438 <p>
    439   Because the ball is a circle-like object, an AABB is probably not the best choice for the ball's collision shape. The collision code thinks the ball is a rectangular box, so the ball often collides with a brick even though the ball sprite itself isn't yet touching the brick.
    440 </p>
    441 
    442 <img src="/img/in-practice/breakout/collisions_ball_aabb_touch.png" alt="Ball colliding with brick as an AABB"/>
    443 
    444 <p>
    445   It makes much more sense to represent the ball with a circle collision shape instead of an AABB. For this reason we included a <var>Radius</var> variable within the ball object. To define a circle collision shape, all we need is a position vector and a radius.
    446 </p>
    447 
    448   <img src="/img/in-practice/breakout/collisions_circle.png" alt="Ball circular collision shape"/>
    449 
    450 <p>
    451   This does mean we have to update the detection algorithm since it currently only works between two AABBs. Detecting collisions between a circle and a rectangle is a bit more complicated, but the trick is as follows: we find the point on the AABB that is closest to the circle, and if the distance from the circle to this point is less than its radius, we have a collision.
    452 </p>
    453   
    454   <p>
    455     The difficult part is getting this closest point \(\color{red}{\bar{P}}\) on the AABB. The following image shows how we can calculate this point for any arbitrary AABB and circle:
    456   </p>
    457 
    458   <img src="/img/in-practice/breakout/collisions_aabb_circle.png" class="clean" alt="AABB - Circle collision detection"/>
    459     
    460 <p>
    461    We first need to get the difference vector between the ball's center \(\color{blue}{\bar{C}}\) and the AABB's center \(\color{green}{\bar{B}}\) to obtain \(\color{purple}{\bar{D}}\). What we then need to do is <def>clamp</def> this vector \(\color{purple}{\bar{D}}\) to the AABB's half-extents \(\color{orange}{{w}}\) and \(\color{teal}{\bar{h}}\) and add it to \(\color{green}{\bar{B}}\). The half-extents of a rectangle are the distances between the rectangle's center and its edges: its size divided by two. This returns a position vector that is always located somewhere at the edge of the AABB (unless the circle's center is inside the AABB).
    462 </p>
    463     
    464 <note>
    465   A clamp operation <strong>clamps</strong> a value to a value within a given range. This is often expressed as:
    466   
    467 <pre><code>
    468 float clamp(float value, float min, float max) {
    469     return std::max(min, std::min(max, value));
    470 }  
    471 </code></pre>
    472   
    473   For example, a value of <code>42.0f</code> is clamped to <code>6.0f</code> with a range of <code>3.0f</code> to <code>6.0f</code>, and a value of <code>4.20f</code> would be clamped to <code>4.20f</code>.  <br/>
    474   
    475   Clamping a 2D vector means we clamp both its <code>x</code> and its <code>y</code> component within the given range.
    476 </note>
    477     
    478 <p>
    479    This clamped vector \(\color{red}{\bar{P}}\) is then the closest point from the AABB to the circle.  What we then need to do is calculate a new difference vector \(\color{purple}{\bar{D'}}\) that is the difference between the circle's center \(\color{blue}{\bar{C}}\) and the vector \(\color{red}{\bar{P}}\).
    480 </p>
    481     
    482     <img src="/img/in-practice/breakout/collisions_aabb_circle_radius_compare.png" class="clean" alt="Calculating difference vector D' to get distance between circle and closest point AABB"/>
    483       
    484 <p>
    485    Now that we have the vector \(\color{purple}{\bar{D'}}\), we can compare its length to the radius of the circle. If the length of \(\color{purple}{\bar{D'}}\) is less than the circle's radius, we have a collision.
    486 </p>
    487     
    488 <p>
    489   This is all expressed in code as follows:
    490 </p>
    491     
    492 <pre><code>
    493 bool CheckCollision(BallObject &one, GameObject &two) // AABB - Circle collision
    494 {
    495     // get center point circle first 
    496     glm::vec2 center(one.Position + one.Radius);
    497     // calculate AABB info (center, half-extents)
    498     glm::vec2 aabb_half_extents(two.Size.x / 2.0f, two.Size.y / 2.0f);
    499     glm::vec2 aabb_center(
    500         two.Position.x + aabb_half_extents.x, 
    501         two.Position.y + aabb_half_extents.y
    502     );
    503     // get difference vector between both centers
    504     glm::vec2 difference = center - aabb_center;
    505     glm::vec2 clamped = glm::clamp(difference, -aabb_half_extents, aabb_half_extents);
    506     // add clamped value to AABB_center and we get the value of box closest to circle
    507     glm::vec2 closest = aabb_center + clamped;
    508     // retrieve vector between center circle and closest point AABB and check if length &lt;= radius
    509     difference = closest - center;
    510     return glm::length(difference) &lt; one.Radius;
    511 }      
    512 </code></pre>
    513 
    514 <p>
    515   We create an overloaded function for <fun>CheckCollision</fun> that specifically deals with the case between a <fun>BallObject</fun> and a <fun>GameObject</fun>. Because we did not store the collision shape information in the objects themselves we have to calculate them: first the center of the ball is calculated, then the AABB's half-extents and its center.
    516 </p>
    517       
    518 <p>
    519   Using these collision shape attributes we calculate vector \(\color{purple}{\bar{D}}\) as <var>difference</var> that we clamp to <var>clamped</var> and add to the AABB's center to get point \(\color{red}{\bar{P}}\) as <var>closest</var>. Then we calculate the difference vector \(\color{purple}{\bar{D'}}\) between <var>center</var> and <var>closest</var> and return whether the two shapes collided or not.
    520 </p>
    521       
    522 <p>
    523   Since we previously called <fun>CheckCollision</fun> with the ball object as its first argument, we do not have to change any code since the overloaded version of <fun>CheckCollision</fun> now automatically applies. The result is now a much more precise collision detection algorithm:
    524 </p>
    525 
    526 <div class="video paused" onclick="ClickVideo(this)">
    527   <video width="600" height="450" loop>
    528     <source src="/video/in-practice/breakout/collisions_circle.mp4" type="video/mp4" />
    529     <img src="/img/in-practice/breakout/collisions_precise.png" class="clean"/>
    530   </video>
    531 </div>
    532 
    533 <p>
    534   It seems to work, but still, something is off. We properly do all the collision detection, but the ball does not <strong>react</strong> in any way to the collisions. We need to update the ball's position and/or velocity whenever a collision occurs. This is the topic of the <a href="https://learnopengl.com/In-Practice/2D-Game/Collisions/Collision-resolution" target="_blank">next</a> chapter.
    535 </p>
    536        
    537 
    538     </div>
    539     
    540     <div id="hover">
    541         HI
    542     </div>
    543    <!-- 728x90/320x50 sticky footer -->
    544 <div id="waldo-tag-6196"></div>
    545 
    546    <div id="disqus_thread"></div>
    547 
    548     
    549 
    550 
    551 </div> <!-- container div -->
    552 
    553 
    554 </div> <!-- super container div -->
    555 </body>
    556 </html>
    557 	</main>
    558 </body>
    559 </html>