![]() |
|
Ball vs lineBy now you are probably bored to have only single moving point. Not that there is something wrong with moving point, they are fine, but still, the point is only a point. How many moving points can you see around you? Not many I hope. Finally, we will take big step forward and start to move something more realistic - the ball. Im sure you have met many balls in your life and so you know how they differ from the points. Balls have width. In our 2D examples the ball is represented by circle and beside having coordinates of its center, it also has radius. game.myOb={r:10};
game.myOb.p0={x:150, y:100};
Here the moving object is ball with radius set to 10. Now we know coordinates of its center, its move vector and its radius and we want to know where it will hit the wall.
In the picture the intersection point between center of the ball and the wall would be where the grey circle is. Actually the ball hits the wall earlier. The point when the ball actually hits the ball, is actually intersection point between ball movement vector (red) and the wall (green) moved in the direction of its normal by the radius of the ball (blue). So, instead of finding intersection with wall vector, we could use another wall vector which is same direction, but with starting point moved. Axes methodBall intersection with line can also be found with other methods. Lets see how we can determine if ball has hit the wall using some simple projections.
In the picture we look at the ball in its end point p1. Vector (blue) is drawn from the start point of wall (v2.p0) to the center of ball. Now we project this new vector on the wall normal, this is on the picture vector v3 (red). To place the wall just near the wall we have to move it on the direction of walls normal by the amount of ball.r-v3.len In the example code walls normal is expected to be unit vector: v.lx = v.dy; v.ly = -v.dx; In the runme function we check for each wall vector: for(var i=1; i<5; i++){
var w=game["v"+i];
//if we have hit the wall
var pen=ob.r-findIntersection(ob, w);
if(pen>=0){
//move object away from the wall
ob.p1.x+=w.lx*pen;
ob.p1.y+=w.ly*pen;
//change movement
var vb=bounce(ob, w);
ob.vx=vb.vx;
ob.vy=vb.vy;
}
}
We find the amount of penetration to each of the walls and if ball is inside the wall we move it away and find new movement vector using same old bounce function. The function to find length of penetration: function findIntersection(v1, v2){
//vector between center of ball
//and starting point of wall
var v3={};
v3.vx=v1.p1.x-v2.p0.x;
v3.vy=v1.p1.y-v2.p0.y;
//project this vector on the normal of the wall
var v=projectVector(v3, v2.lx, v2.ly);
//find length of projection
v.len=Math.sqrt(v.vx*v.vx+v.vy*v.vy);
return v.len;
}
In this example try to drag end points of the wall points:
Notice that this example does not deal with the length of the walls, all walls are considered to continue forever. And so, this can be used to hold ball inside the box, but not to hold it outside of the box. We will see how to make ball collide with corners of walls in next chapter. You can download the source fla. Next: Ball in the corner. |
|