Circle/rectangle collision response

Viewed 6016

So I built some time ago a little Breakout clone, and I wanted to upgrade it a little bit, mostly for the collisions. When I first made it I had a basic "collision" detection between my ball and my brick, which in fact considered the ball as another rectangle. But this created an issue with the edge collisions, so I thought I would change it. The thing is, I found some answers to my problem:

for example this image

enter image description here

and the last comment of this thread : circle/rect collision reaction but i could not find how to compute the final velocity vector.

So far I have :

- Found the closest point on the rectangle,
- created the normal and tangent vectors,

And now what I need is to somehow "divide the velocity vector into a normal component and a tangent component; negate the normal component and add the normal and tangent components to get the new Velocity vector" I'm sorry if this seems terribly easy but I could not get my mind around that ... code :

function collision(rect, circle){
  var NearestX = Max(rect.x, Min(circle.pos.x, rect.x + rect.w));
  var NearestY = Max(rect.y, Min(circle.pos.y, rect.y + rect.w));

  var dist = createVector(circle.pos.x - NearestX, circle.pos.y - NearestY);
  var dnormal = createVector(- dist.y, dist.x);
//change current circle vel according to the collision response
}

Thanks !

EDIT: Also found this but I didn't know if it is applicable at all points of the rectangle or only the corners.

3 Answers

Correction of an idea shared above, with adjusting velocity after collision using tangental velocity.

bounciness - constant defined to represent lost force after collision

nv = vector                            # normalized vector from center of cricle to collision point        (normal)
pv = [-vector[1], vector[0]]           # normalized vector perpendicular to nv                             (tangental)
n = dot_product(nv, circle.vel)        # normal vector length
t = dot_product(pv, circle.vel)        # tangental_vector length
new_v = sum_vectors(multiply_vector(t*bounciness, pv), multiply_vector(-n*self.bounciness, nv))            # new velocity vector
circle.velocity = new_v
Related