Search code examples
processingcollision-detection

Processing: how to detect collisions when one object is traveling 'too fast'?


I have two objects: one is a ball, whose velocity is given by a vector of components velocity.x and velocity.y, such that, at every frame, the (x, y) position of the ball gets updated to (x + velocity.x, y + velocity.y); the other is a very thin horizontal rectangle that cannot move. Of course, I'd love the ball to change its trajectory whenever it hits the rectangle either from above or from below.

However, I've run into a problem I don't know how to fix: whenever the ball travels fast enough to go from one side of the rectangle to the other side in just one frame, the collision isn't detected because the ball never actually comes in contact with the rectangle. Being the rectangle very thin, the minimum velocity beyond which this behaviour occurs isn't even too high.

I know this is a problem that usually occurs when you want to keep an object inside the screen: in fact, if you just change the sign of its velocity as soon as it exits the screen, this doesn't necessarily make your object rebound off the side of the window (because it could travel so fast that a part of it gets stuck outside the edge), so you actually have to reposition it inside the window first, and then change the sign of its velocity accordingly. But I cannot use this trick here, because the behaviours of the ball on the two sides of the rectangle are supposed to be different: if the ball hits it from above, it will bounce upwards; if from below, it will bounce downwards. But when the ball manages to go past the rectangle in just one frame, how can I tell the program which side the ball should be repositioned? After all, once that frame is drawn, the program isn't able to know whether the ball came 'from the other side' of the rectangle, or if it's always been on that side.

I hope I managed to explain my problem clearly enough. What can I do to solve it?


Solution

  • Take the previous position of the ball and the current position of the ball, and create a line. Use that line to perform collision detection instead of the ball itself. Test for collision detection between the line and the rectangle.

    This is going to be a bit more complicated than testing for collision detection between a circle and a rectangle, but googling "line rectangle collision detection" will return a ton of results. Basically you'll want to break the rectangle down into 4 lines and then check whether each line intersects your path line.

    This question might help: How do you detect where two line segments intersect?