Detecting collision of rectangle with circle

后端 未结 3 1838
忘了有多久
忘了有多久 2020-12-04 18:54

Actually I am trying to detect thee collision of the Rectangle with the circle in the following piece of code:-

function checkCollision() {
     //checking o         


        
3条回答
  •  甜味超标
    2020-12-04 19:19

    That's a way to do it:

    1) find the corner of the rectangle nearest to the circle center
    2) see how the circle is positioned relative to the corner

    The function takes a third parameter to allow the distinction between a "solid" rectangle and a simple outline (i.e. whether the case of a circle located entirely inside the rectangle should be considered a collision)

    function collides (rect, circle, collide_inside)
    {
        // compute a center-to-center vector
        var half = { x: rect.w/2, y: rect.h/2 };
        var center = {
            x: circle.x - (rect.x+half.x),
            y: circle.y - (rect.y+half.y)};
    
        // check circle position inside the rectangle quadrant
        var side = {
            x: Math.abs (center.x) - half.x,
            y: Math.abs (center.y) - half.y};
        if (side.x >  circle.r || side.y >  circle.r) // outside
            return false; 
        if (side.x < -circle.r && side.y < -circle.r) // inside
            return collide_inside;
        if (side.x < 0 || side.y < 0) // intersects side or corner
            return true;
    
        // circle is near the corner
        return side.x*side.x + side.y*side.y  < circle.r*circle.r;
    }
    
    var rect = { x:50, y:50, w:80, h:30 };
    var circle = { x:105, y:135, r:16 };
    
    if (collides (rect, circle)) { /* bang! */ }
    

    I have a second function that computes a collision normal vector, to allow animating an circle bouncing off rectangles. Together they serve as a base for this fiddle

    function bounces (rect, circle)
    {
        // compute a center-to-center vector
        var half = { x: rect.w/2, y: rect.h/2 };
        var center = {
            x: circle.x - (rect.x+half.x),
            y: circle.y - (rect.y+half.y)};
    
        // check circle position inside the rectangle quadrant
        var side = {
            x: Math.abs (center.x) - half.x,
            y: Math.abs (center.y) - half.y};
        if (side.x >  circle.r || side.y >  circle.r) // outside
            return { bounce: false }; 
        if (side.x < -circle.r && side.y < -circle.r) // inside
            return { bounce: false }; 
        if (side.x < 0 || side.y < 0) // intersects side or corner
        {
            var dx = 0, dy = 0;
            if (Math.abs (side.x) < circle.r && side.y < 0)
            {
                dx = center.x*side.x < 0 ? -1 : 1;
            }
            else if (Math.abs (side.y) < circle.r && side.x < 0)
            {
                dy = center.y*side.y < 0 ? -1 : 1;
            }
    
            return { bounce: true, x:dx, y:dy };
        }
        // circle is near the corner
        bounce = side.x*side.x + side.y*side.y  < circle.r*circle.r;
        if (!bounce) return { bounce:false }
        var norm = Math.sqrt (side.x*side.x+side.y*side.y);
        var dx = center.x < 0 ? -1 : 1;
        var dy = center.y < 0 ? -1 : 1;
        return { bounce:true, x: dx*side.x/norm, y: dy*side.y/norm };   
    }
    

提交回复
热议问题