Stealing code from other people and then converting it to Danmakufu. Wooo
Collision_Box_Box
Determines if two rectangles are intersecting with each other. Returns true if they are and false if they are not.
cx1, cy1 is the center coordinates of rectangle 1.
w1, h1 is the width and height of rectangle 1.
r1 is the rotation of rectangle 1.
The other 5 parameters are the same except for rectangle 2.
function Collision_Box_Box(cx1, cy1, w1, h1, r1, cx2, cy2, w2, h2, r2){
let rectA = CalculateCorners(cx1, cy1, w1, h1, r1);
let rectB = CalculateCorners(cx2, cy2, w2, h2, r2);
let axisList = [
rectA[1] - rectA[0],
rectA[1] - rectA[2],
rectB[0] - rectB[3],
rectB[0] - rectB[1]
];
ascent(i in 0..4){
if(!IsAxisCollision(axisList[i])){
return false;
}
}
return true;
function CalculateCorners(cx, cy, width, height, rotation){
if(rotation == 0){
return [
[cx-width/2, cy-height/2],
[cx+width/2, cy-height/2],
[cx+width/2, cy+height/2],
[cx-width/2, cy+height/2]
];
}
else {
let angles = [
atan2(height/-2, width/-2)+rotation,
atan2(height/2, width/-2)+rotation,
atan2(height/2, width/2)+rotation,
atan2(height/-2, width/2)+rotation
];
let distance = (height^2 + width^2)^0.5/2;
return [
[cx+cos(angles[0])*distance, cy+sin(angles[0])*distance],
[cx+cos(angles[1])*distance, cy+sin(angles[1])*distance],
[cx+cos(angles[2])*distance, cy+sin(angles[2])*distance],
[cx+cos(angles[3])*distance, cy+sin(angles[3])*distance]
];
}
}
function IsAxisCollision(axis){
let rectAScalars = [
GenerateScalar(rectA[0], axis),
GenerateScalar(rectA[1], axis),
GenerateScalar(rectA[2], axis),
GenerateScalar(rectA[3], axis)
];
let rectBScalars = [
GenerateScalar(rectB[0], axis),
GenerateScalar(rectB[1], axis),
GenerateScalar(rectB[2], axis),
GenerateScalar(rectB[3], axis)
];
let rectAMin = ArrayMin(rectAScalars);
let rectAMax = ArrayMax(rectAScalars);
let rectBMin = ArrayMin(rectBScalars);
let rectBMax = ArrayMax(rectBScalars);
if(rectBMax <= rectAMax && rectBMax >= rectAMin)
{
return true;
}
else if (rectAMax <= rectBMax && rectAMax >= rectBMin)
{
return true;
}
return false;
}
function GenerateScalar(corner, axis){
let num = (corner[0] * axis[0]) + (corner[1] * axis[1]);
let denom = (axis[0] * axis[0]) + (axis[1] * axis[1]);
let divisionResult = num / denom;
let cornerProjected = [divisionResult * axis[0], divisionResult * axis[1]];
let scalar = (axis[0] * cornerProjected[0]) + (axis[1] * cornerProjected[1]);
return scalar;
}
}
function ArrayMin(array){
let min = array[0];
ascent(i in 1..length(array)){
if(array[i] < min){ min = array[i]; }
}
return min;
}
function ArrayMax(array){
let max = array[0];
ascent(i in 1..length(array)){
if(array[i] > max){ max = array[i]; }
}
return max;
}
I nested CalculateCorners, IsAxisCollision, and GenerateScalar because nothing should really be using those besides the collision function itself. ArrayMin and ArrayMax are also used by the collision function but those are probably useful elsewhere too so I left them unnested.