0
votes

I have an animation using JS and Fabric.js whereby circles more around the screen. I'm trying to contain them to a specific area but having some issues.

After some reading yesterday I thought that testing to see if the circle was inside the rectangle (their container) would be quite simple but I've yet to get it working properly.

The circles are created at the bottom of the screen which is also where their container is. With the code that I have they 'float' to the top and stay there in one spot.

The console logs that I have indicate that they are outside the rectangle immediately so I'm assuming that something is wrong with my collision function.

My aim is for them to stay within the containing moving about and when they hit the edges they should change direction so that they will stay inside again.

Thanks for any help.

EDIT : EDITED TO ENABLE A TOUCH OF CLARITY AND USING THE COLSIOSN DETECTION FROM BELOW ANSWER AS NOW THINK THE PROBLEM IS WITH THE RESPONSE INSTEAD OF THE DETECTION.

Collision function:

function testCollision(circle, rectangle) {

return circle.left + circle.radius < rectangle.left + rectangle.width/2 //right side
    && circle.left - circle.radius < rectangle.left - rectangle.width/2 //left side
    && circle.top + circle.radius < rectangle.top + rectangle.height/2 //top
    && circle.top - circle.radius < rectangle.top - rectangle.height/2;

}

left = x & top = y

There are maxX and maxY values which is the width and height of the container.
this is the test:

if(testCollision(circle, rect) == false){
        var r = Math.atan2(y - maxY / 2, x - maxX / 2);
        vx = -Math.cos(r);
        vy = -Math.sin(r);
    }

any help is hugely appreciated, thanks!

1
@Geobits - I feel like I'm being dumb here - I've just drawn it out on paper so I'm hoping you're wrong:) the origin is in the centre so to get the left of the circle would be x+rad or left+rad (as left is effectively x) and to get the ride side of circle I'd need to do x-rad. Please elaborate further if I'm wrong as I'm kinda feeling a bit special at the moment.null
@Geobits - think we got wires crossed here. I'm well aware of what the radius is but thanks for clarifying. I can't refer to the original comment as it's deleted but from what I read I thought you - oh never mind, yo've deleted that message too. Convo fail. :)null

1 Answers

2
votes

The way i see it, a circle defined by (x,y,r) coordinates of the center and radius is inside a n axis-aligned rectangle defined by (x,y,w,h) coordinates of the center, the width and the height if the 4 points top,right,bottom,left of the circle are inside the rectangle:

function testCollision(circle, rectangle) {
  return circle.x + circle.r < rectangle.x + rectangle.w/2
      && circle.x - circle.r > rectangle.x - rectangle.w/2
      && circle.y + circle.r < rectangle.y + rectangle.h/2
      && circle.y - circle.r > rectangle.y - rectangle.h/2
}

I considered the positive direction of y to be towards the bottom, as is usual in coordinate systems on the web.