Skip to content

Commit

Permalink
box collision ariticle added
Browse files Browse the repository at this point in the history
  • Loading branch information
BurntWaffleCake committed Dec 12, 2023
1 parent b2c9c08 commit 9d1c445
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 20 deletions.
1 change: 1 addition & 0 deletions articleTemplateObjects/physicsEngineArticleNavObject.html
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
<hr style="width: 75%" />
<a href="../projects/Physics/BallCollision/index.html" target="_top" class="article-nav-link">Ball Collision</a>
<a href="../projects/Physics/BallCollisionOptimization/" target="_top" class="article-nav-link">Ball Collision Optimization</a>
<a href="../projects/Physics/BoxCollision/index.html" target="_top" class="article-nav-link">Box Collision</a>
<a href="../projects/Physics/index.html" target="_top" class="article-nav-link">Polygon Collision</a>
<a href="../projects/Physics/index.html" target="_top" class="article-nav-link">Physics Engine</a>
</nav>
Expand Down
4 changes: 4 additions & 0 deletions projects/Physics/BoxCollision/images/AABB.drawio.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
96 changes: 96 additions & 0 deletions projects/Physics/BoxCollision/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<!DOCTYPE html>

<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Box Collision</title>
<meta name="description" content="Projects" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="../../../styles/articlestylesheet.css" />
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
</head>

<style>
.image-holder {
max-width: 100%;
}

.image-holder img {
max-width: 100%;
height: auto;
background-color: white;
}

.article-nav-header {
font-size: larger;
}

.equation {
text-align: center;
padding: 0;
margin: 0;
padding-bottom: 1rem;
}
</style>

<body>
<object id="global-nav-object" data="../../../articleTemplateObjects/articleGlobalNavObject.html"></object>

<div id="article-body">
<object data="../../../articleTemplateObjects/physicsEngineArticleNavObject.html"></object>

<div class="vertical-divider"></div>

<article id="article-contents">
<h1>Box Collision</h1>

<h2>Basic Polygon Collision</h2>
<p>
Balls are the simplest collision shape we need to handle. Unfortunately, most complex volumes are not made up of only balls and instead use complex polygons and shapes to fully or partially
represent itself. In our case with 2D collision, triangles are the most basic shape we can decompose these volumes into. This article will not go into triangle and other decomposition
algorithms and instead focus on collision between box or rectangular volumes.
</p>

<h2>AABB Box Collision</h2>
<p>
AABB collision is the most simple way to calculate the collision between two boxes. All of the edges of the box we want to collide is mapped to the x and y axis of the coordinate frame we
are using. This means that all colliders do not have rotation allowing for every efficient and fast calculations to test for collision. In our case (with 2d collision), we only need to test
the x and y axis to see if two colliders are colliding which we can calculate using the overlap of the projection of these shapes onto said axis. If these projections do not overlap in any
of the tested axis, we can conclude that the two volumes are not colliding. This concept of using projections is further expanded in the SAT collision algorithm.
</p>

<p style="text-align: center">calculating overlap between two lines</p>

<p class="equation">\( overlap =\max{(0, \min{(A_{max}, B_{max})}-\max{(A_{min}, B_{min})})}\)</p>

<div class="image-holder" style="display: flex; justify-content: center">
<img class="" style="width: 90%" src="./images/AABB.drawio.svg" />
</div>

<h2>Pros and Cons</h2>
<p>
AABB is extremely fast compared to other collision algorithms and its simple nature allows for efficient and fast calculations. This is why many games use AABB when testing for collision
using bounding boxes that encapsulate the entire body that needs collision. This, however, comes at the cost of precision as AABB is locked to the axis and does not allow any rotation. AABB
also only represents a box and is unable to test for collision between more complex geometry. AABB serves as an excellent approximation of a body's volume and is often used as an
optimization method for more complex collision algorithms.
</p>

<h2>SAT Algorithm</h2>
<p>
SAT or Separating Axis Theorem is a method of finding collision using a set of axis and overlaps between projections. The overlap calculations from AABB is applicable here with the max and
min points being derived by projecting the colliding geometries onto an arbitrary axis instead of using the x and y axis. SAT allows for our boxes to have rotation and can be extended to any
convex polygon (any line drawn across a geometry can not have move than 2 points of intersection with that geometry). SAT uses an arbitrarily large number of axis to find whether two
geometries collide, however; we only need to test a set number of them in order to determine whether two geometries are colliding. These axis can be obtained by fetching all the normals of
both geometries, ignoring any normals that are parallel to existing axis. By projecting both geometries to these axis and making sure every axis has an overlap, we can guarantee a
collision/overlap between those two geometries (as long as they are both convex).
</p>
</article>

<div class="vertical-divider"></div>

<nav id="article-bookmarks"></nav>
</div>
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@

p {
margin: 0;
}

options {
margin: 0;
position: absolute;
color: white;
top: 1rem;
Expand All @@ -45,10 +49,15 @@
</style>

<body>
<p>
Drag mouse to move boxes<br />
Press space to spawn new boxes
</p>
<options>
<p>
Drag mouse to move boxes<br />
Press space to spawn new boxes
</p>
<br />
<button id="flingButton">fling</button>
<button id="clearButton">clear</button>
</options>

<div id="container">
<canvas id="source"></canvas>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ let boxes = [];

const gravity = 0;
const restitution = 1;
var substeps = 1;
var substeps = 4;

let time = 0.0;
function loop(t) {
Expand All @@ -402,20 +402,23 @@ function loop(t) {
if (mouse1Down) {
let point = getMousePos(canvas, mousePos);
let closestBox = boxes[0];
let distance = Math.sqrt((point.x - closestBox.x) ** 2 + (point.y - closestBox.y) ** 2);
for (let i = 1; i < boxes.length; i++) {
let nextBox = boxes[i];
let nextDistance = Math.sqrt((point.x - nextBox.x) ** 2 + (point.y - nextBox.y) ** 2);
if (nextDistance < distance) {
closestBox = nextBox;
distance = nextDistance;

if (closestBox !== undefined) {
let distance = Math.sqrt((point.x - closestBox.x) ** 2 + (point.y - closestBox.y) ** 2);
for (let i = 1; i < boxes.length; i++) {
let nextBox = boxes[i];
let nextDistance = Math.sqrt((point.x - nextBox.x) ** 2 + (point.y - nextBox.y) ** 2);
if (nextDistance < distance) {
closestBox = nextBox;
distance = nextDistance;
}
}
}
closestBox.x = point.x;
closestBox.y = point.y;
closestBox.x = point.x;
closestBox.y = point.y;

closestBox.dx = mouseDelta.x * 50;
closestBox.dy = mouseDelta.y * 50;
closestBox.dx = mouseDelta.x * 50;
closestBox.dy = mouseDelta.y * 50;
}
}

for (let c = 0; c < substeps; c++) {
Expand Down Expand Up @@ -483,12 +486,12 @@ let mouse1Down = false;
let mousePos = { x: 0, y: 0 };
let mouseDelta = { x: 0, y: 0 };

document.addEventListener("mousedown", (event) => {
console.log("mousedown");
canvas.addEventListener("mousedown", (event) => {
if (event.buttons == 1) {
mouse1Down = true;
}
});

document.addEventListener("mouseup", (event) => {
if (event.buttons == 0) {
mouse1Down = false;
Expand All @@ -504,7 +507,6 @@ canvas.addEventListener("mousemove", (event) => {

document.onkeydown = function (event) {
if (event.key == " ") {
console.log("spacePressed");
boxes.push(
new Box(
Math.random() * width,
Expand All @@ -519,3 +521,25 @@ document.onkeydown = function (event) {
);
}
};

const clearButton = document.getElementById("clearButton");
const flingButton = document.getElementById("flingButton");

clearButton.onkeydown = function (e) {
e.preventDefault();
};

clearButton.onclick = function (e) {
boxes = [];
};

flingButton.onkeydown = function (e) {
e.preventDefault();
};

flingButton.onclick = function (e) {
boxes.forEach((box) => {
box.dx += box.m / 2 - Math.random() * box.m;
box.dy += box.m / 2 - Math.random() * box.m;
});
};

0 comments on commit 9d1c445

Please sign in to comment.