Skip to content

Commit

Permalink
add intersecting function to brick
Browse files Browse the repository at this point in the history
  • Loading branch information
okdargy committed Jul 10, 2023
1 parent 75bf23d commit 3c52c83
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/rich-sheep-hang.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"dotbrk": minor
---

use sat algorithm for checking intersects with rotated bricks
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
"types": "dist/index.d.ts",
"module": "dist/index.mjs",
"scripts": {
"run": "node dist/index.js",
"build": "tsup src/index.ts --format cjs,esm --dts",
"dev": "tsup src/index.ts && node dist/index.js",
"build": "tsup src/index.ts --format cjs,esm --dts",
"release": "pnpm run build && changeset publish",
"test": "jest --watchAll --verbose",
"lint": "tsc"
},
"repository": {
Expand Down
5 changes: 5 additions & 0 deletions src/class/Brick.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { checkCollision3d } from "../util/math"
import Vector3 from "./Vector3"

export default class Brick {
Expand Down Expand Up @@ -44,4 +45,8 @@ export default class Brick {
this.visibility = 1
this.collision = true
}

intersects(brick: Brick): boolean {
return checkCollision3d(this, brick)
}
}
101 changes: 101 additions & 0 deletions src/util/math.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import Brick from "../class/Brick";

export function generatePoints(cx: number, cy: number, vx: number, vy: number, rotatedAngle: number) {
rotatedAngle = rotatedAngle * Math.PI / 180;

let dx = vx - cx;
let dy = vy - cy;

let distance = Math.sqrt(dx * dx + dy * dy);
let originalAngle = Math.atan2(dy,dx);

let rotatedX = cx + distance * Math.cos(originalAngle + rotatedAngle);
let rotatedY = cy + distance * Math.sin(originalAngle + rotatedAngle);

return {
x: rotatedX,
y: rotatedY
}
}

export function rotateCords(square: Brick, a: "x" | "y" | "z", b: "x" | "y" | "z") {
let centerA = square.position[a] + (square.scale[a] / 2);
let centerB = square.position[b] + (square.scale[b] / 2);
//Work out the new locations

let topLeft = generatePoints(centerA, centerB, square.position[a], square.position[b], square.rotation),
topRight = generatePoints(centerA, centerB, square.position[a] + square.scale[a], square.position[b], square.rotation),
bottomLeft = generatePoints(centerA, centerB, square.position[a], square.position[b] + square.scale[b], square.rotation),
bottomRight = generatePoints(centerA, centerB, square.position[a] + square.scale[a], square.position[b] + square.scale[b], square.rotation);

return{
tl: topLeft,
tr: topRight,
bl: bottomLeft,
br: bottomRight
}
}

// sat algorithm for 2d collision detection
export function checkCollision(square1: Brick, square2: Brick, axis: "x" | "y" | "z", axis2: "x" | "y" | "z") {
let a = rotateCords(square1, axis, axis2);
let b = rotateCords(square2, axis, axis2);

let ax = [a.tl.x, a.tr.x, a.br.x, a.bl.x];
let ay = [a.tl.y, a.tr.y, a.br.y, a.bl.y];
let bx = [b.tl.x, b.tr.x, b.br.x, b.bl.x];
let by = [b.tl.y, b.tr.y, b.br.y, b.bl.y];

for (let i = 0; i < 4; i++) {
let j = (i + 1) % 4;
let normal = {
x: ay[i] - ay[j],
y: ax[j] - ax[i]
}

let minA = Infinity;
let maxA = -Infinity;

for (let k = 0; k < 4; k++) {
let projected = normal.x * ax[k] + normal.y * ay[k];
if (projected < minA) {
minA = projected;
}
if (projected > maxA) {
maxA = projected;
}
}

let minB = Infinity;
let maxB = -Infinity;

for (let k = 0; k < 4; k++) {
let projected = normal.x * bx[k] + normal.y * by[k];
if (projected < minB) {
minB = projected;
}
if (projected > maxB) {
maxB = projected;
}
}

if (maxA < minB || maxB < minA) {
return false;
}
}

return true;
}

// check collision for all 3 axis
export function checkCollision3d(square1: Brick, square2: Brick) {
var xy = checkCollision(square1, square2, "x", "y");
var xz = checkCollision(square1, square2, "x", "z");
var yz = checkCollision(square1, square2, "y", "z");

if(xy && xz && yz) {
return true;
}

return false;
}
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
"noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
"noUncheckedIndexedAccess": false, /* Add 'undefined' to a type when accessed using an index. */
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
Expand Down

0 comments on commit 3c52c83

Please sign in to comment.