0

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!

2
  • @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. Commented Feb 24, 2014 at 17:36
  • @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. :) Commented Feb 24, 2014 at 17:53

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

3 Comments

hi, thanks for taking the time to reply. The origin is the centre so I changed it slightly to reflect that by using w/2 and - w/2 on lines 2 & 4. It should work perfectly yet the circles travel towards a point at the top of the screen and stay there. Makes me think the collsison detection is not the issue but more the response.
@SteveGreen I had the signs mixed up, please check the revised answer.
thanks for updating the answer, I had figured the signs out - I used aabb last year sometime which only added to the annoyance of getting this working :) The detection is there, the response is not. Thank you for your help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.