When a ball approaches a wall at a sharp angle, it won't hit the wall with it's front, but with it's side. So our previous algorithm won't work. Obviously the ball will hit the wall with the point on it's edge closest to the wall. The closest point of a circle to a line would be the intersection point of the circle and a line from the center of the circle perpendicular to the first line. I guess one could prove this mathematically, but I'm not that smart, so I'll have to rely on little sketches and common sense.
This is where vectors come in handy again. The line segment we're looking for is a vector starting in the center of the circle and parallel to the wall's normal. Since the walls won't change during the course of the demo, we can store the normals in the beginning of the demo in the walls array. new Vector(340, -150).normal.getNormalized() gets a Vector perpendicular to Vector(340, -150) and resizes it to a magnitude of 1. In the constructor of class collisionApp3 we store the normals in the walls array:
this.walls = new Array( {x: 10, y: 200, v: new Vector(340, -150), n: new Vector(340, -150).normal.getNormalized()}, {x: 350, y: 50, v: new Vector(0, 200), n: new Vector(0, 200).normal.getNormalized()}, {x: 350, y: 250, v: new Vector(-340, -50), n: new Vector(-340, -50).normal.getNormalized()} );
In the step() function we look for an intersection of each wall and Vector vec. The walls' normals point inwards. We want the vector to point towards the walls, so we need to invert the normal and then resize is to a length equal to the radius of the ball: n.getInverted().cross(this.radius)
for (var i=0; i<this.walls.length; i++){ var vec:Vector = this.walls[i].n.getInverted().cross(this.radius); ... if ( checkCollision({x: newX, y: newY}, vec, {x:this.walls[i].x, y:this.walls[i].y}, this.walls[i].v) ) { bCollision = true; break; } }
thank you so much for this!!
i have been searching for weeks to find this
Posted by Roman Vaughan, Whose homepage is http://smartie.awardspace.com/ on Thursday, 03 August 2006 at 7:21
This is the best collision detection explanation and example I have seen for flash yet! Much better than using a simple hitTest or whatever, thanks so much!
Posted by Vince, Whose homepage is http://kamazar.com on Sunday, 07 January 2007 at 12:56
There are some good flash tutorials dealing with collisions on www.tonypa.pri.ee. The website should provide some extra reference material for those interested.
Posted by Mike Hamman, on Friday, 11 April 2008 at 4:06
Thanks, this is the most on to it explanation I've had. Will allow for some truly dynamic realistic collisions. Are you still building on this?
Posted by Alexis, Whose homepage is http://www.joomlabear.com on Sunday, 29 June 2008 at 5:22