javascript - Circle/rectangle collision response -


so built time ago little breakout clone, , wanted upgrade little bit, collisions. when first made had basic "collision" detection between ball , brick, in fact considered ball rectangle. created issue edge collisions, thought change it. thing is, found answers problem: example image ball_deflection.jpeg , last comment of thread : circle/rect collision reaction not find how compute final velocity vector.

so far have :

- found closest point on rectangle,
- created normal , tangent vectors,

and need somehow "divide velocity vector normal component , tangent component; negate normal component , add normal , tangent components new velocity vector" i'm sorry if seems terribly easy not mind around ... 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 collision response } 

thanks !

edit: found this didn't know if applicable @ points of rectangle or corners.

best explained couple of diagrams:

angles

have angle of incidence = angle of reflection. call value θ.

angles2

have θ = normal angle - incoming angle.

atan2 function computing angle of vector positive x-axis.

then code below follows:

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.h));    var dist = createvector(circle.pos.x - nearestx, circle.pos.y - nearesty);   var dnormal = createvector(- dist.y, dist.x);    var normal_angle = atan2(dnormal.y, dnormal.x);   var incoming_angle = atan2(circle.vel.y, circle.vel.x);   var theta = normal_angle - incoming_angle;   circle.vel = circle.vel.rotate(2*theta); } 

another way of doing velocity along tangent , subtracting twice value circle velocity.

angles3

then code becomes

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.h));    var dist = createvector(circle.pos.x - nearestx, circle.pos.y - nearesty);   var tangent_vel = dist.normalize().dot(circle.vel);   circle.vel = circle.vel.sub(tangent_vel.mult(2)); } 

both of code snippets above same thing in same time (probably). pick whichever 1 best understand.

also, @arbuthnott pointed out, there's copy-paste error in nearesty should use rect.h instead of rect.w.

edit: forgot positional resolution. process of moving 2 physics objects apart they're no longer intersecting. in case, since block static, need move ball.

penetration diagram

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.h));       var dist = createvector(circle.pos.x - nearestx, circle.pos.y - nearesty);    if (circle.vel.dot(dist) < 0) { //if circle moving toward rect     //update circle.vel using 1 of above methods   }    var penetrationdepth = circle.r - dist.mag();   var penetrationvector = dist.normalise().mult(penetrationdepth);   circle.pos = circle.pos.sub(penetrationvector); } 

Comments

Popular posts from this blog

php - Vagrant up error - Uncaught Reflection Exception: Class DOMDocument does not exist -

vue.js - Create hooks for automated testing -

Add new key value to json node in java -