Last active
March 1, 2024 13:43
-
-
Save snorpey/8134c248296649433de2 to your computer and use it in GitHub Desktop.
Calculate collision between circle and rotated rectangle
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Ported to JavaScript from | |
// http://www.migapro.com/circle-and-rotated-rectangle-collision-detection/ | |
// | |
// An example: | |
// var circle: { x: 20, y: 10, radius: 20 }; | |
// var rect: { x: 30, y: 30, width: 100, height: 100, rotation: Math.PI / 2 }; | |
// collideCircleWithRotatedRectangle( circle, rect ); | |
// // returns true. | |
// | |
// | |
// Please note: | |
// This code assumes that rect.x and rect.y are the CENTER coordinates | |
// of the rectangle. You may want to to change this. | |
// Also rotation values need to be in RADIANS. | |
function collideCircleWithRotatedRectangle ( circle, rect ) { | |
var rectCenterX = rect.x; | |
var rectCenterY = rect.y; | |
var rectX = rectCenterX - rect.width / 2; | |
var rectY = rectCenterY - rect.height / 2; | |
var rectReferenceX = rectX; | |
var rectReferenceY = rectY; | |
// Rotate circle's center point back | |
var unrotatedCircleX = Math.cos( rect.rotation ) * ( circle.x - rectCenterX ) - Math.sin( rect.rotation ) * ( circle.y - rectCenterY ) + rectCenterX; | |
var unrotatedCircleY = Math.sin( rect.rotation ) * ( circle.x - rectCenterX ) + Math.cos( rect.rotation ) * ( circle.y - rectCenterY ) + rectCenterY; | |
// Closest point in the rectangle to the center of circle rotated backwards(unrotated) | |
var closestX, closestY; | |
// Find the unrotated closest x point from center of unrotated circle | |
if ( unrotatedCircleX < rectReferenceX ) { | |
closestX = rectReferenceX; | |
} else if ( unrotatedCircleX > rectReferenceX + rect.width ) { | |
closestX = rectReferenceX + rect.width; | |
} else { | |
closestX = unrotatedCircleX; | |
} | |
// Find the unrotated closest y point from center of unrotated circle | |
if ( unrotatedCircleY < rectReferenceY ) { | |
closestY = rectReferenceY; | |
} else if ( unrotatedCircleY > rectReferenceY + rect.height ) { | |
closestY = rectReferenceY + rect.height; | |
} else { | |
closestY = unrotatedCircleY; | |
} | |
// Determine collision | |
var collision = false; | |
var distance = getDistance( unrotatedCircleX, unrotatedCircleY, closestX, closestY ); | |
if ( distance < circle.radius ) { | |
collision = true; | |
} | |
else { | |
collision = false; | |
} | |
return collision; | |
} | |
function getDistance( fromX, fromY, toX, toY ) { | |
var dX = Math.abs( fromX - toX ); | |
var dY = Math.abs( fromY - toY ); | |
return Math.sqrt( ( dX * dX ) + ( dY * dY ) ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment