Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Another question on Angles & Vectors

This thread is locked; no one can reply to it. rss feed Print
Another question on Angles & Vectors
gary_ramsgate
Member #8,619
May 2007

Heeeeelp.

I have two circles moving around on-screen.
I can handle the collision detection with no problems but due to my lack of Math skills am still struggling to get a handle on vectors etc.

If my two circles are:

Circle 1 = x1,y1,vx1,vy1,r1
Circle 2 = x2,y2,vx2,vy2,r2

x,y = screen position
vx,vy = velocity
r= radius

Would anyone be as kind as to write a few lines of code to enable the angle of bounce to be calculated? I've spent about the last week trying to get my head around vectors and dot products, but am having no luck :)

Johan Halmén
Member #1,550
September 2001

Time n: Circles don't intersect
Time n+1: Circles do intersect

The collision should have appeared somewhere between time n and time n+1. Think of time as discrete frames. If you want a ralistic collision, you have to calculate the exact time n+d of the collision, do the collision calculus and then calculate the situation for frame n+1. The simpler way is to act like if the collision took place in n+1, even though the circles intersect in n+1. In n+2 the circles have moved in their new directions. But they might still intersect in n+2, which might cause problem. You can also make it simpler by actink like the collision took place in frame n. You kind of peek into n+1 and find out that the circles intersect. Then you calculate the collision and calculate the n+1 situation with the new directions. If the time steps are small enough, you can go this simpler way. Say the radius is 10 and circle movement from frame to frame is 0.1.

Anyway, the collision calculus is something as follows:
Define the line or vector from one circle to the other.
Find the point on this line where the circles touch. This is the collision point.
Define the line through this point perpendicular to the first line. This is the tangent of both circles.
Think like both circles collide against the tangent.
A collision against a wall: divide the speed vector into a normal vector and a tangent vector. Tangent vector has same direction as the wall. Normal vector is perpendicular. In collision nothing happens to the tangent component, but the normal component gets negated.
But in you case the two circles collide against each other, not against a wall. Swap the normal vectors of the circles!

Imagine two beads, one is at rest and the other hits it. The one at rest takes completely over the speed of the other bead, while the other bead stops. They swap their speeds! If they however have different masses, the situation might be other. In any collision of two beads or two circles, you can think of them swapping the normal vectors, while the tangent vectors are unchanged.

I should probably complete this with a drawing. And do study vector maths! Dividing vx and vy into vxnormal, vynormal, vxtangent and vytangent is heavy pain compared with doing it with vectors. With my vector class I would do something like.

Vektor normal(circle1.coord, circle2.coord);
Vektor c1_vt, c1_vn, c2_vt, c2_vn;
circle1.speed.components(normal, &c1_vt, &c1_vn); // divide speed into two vectors, one 
                                                  //in normal direction, other perpendicular to normal
circle2.speed.components(normal, &c2_vt, &c2_vn); // ditto
circle1.speed = c1_vt + c2_vn;
circle2.speed = c2_vt + c1_vn;

[edit]
Here we go...
{"name":"592270","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/3\/4\/34b355a2b9684f120b94ac6582e33e16.png","w":392,"h":510,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/3\/4\/34b355a2b9684f120b94ac6582e33e16"}592270
Two circles colliding. Black vectors show their velocities.
http://www.allegro.cc/files/attachment/592271
Find out the velocity vectors' tangent components (blue vectors) and normal components (red vectors)
http://www.allegro.cc/files/attachment/592272
Exchange the red vectors and add the red and blue vectors and you have your new velocities (black vectors).

Someone take over from this point and explain how the collision makes the objects spin and how the spinning affects further collisions.

Now why did you make me explain all this? Now I have to make a simple simulation application to find out this all is not just bulls hit. >:(

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Years of thorough research have revealed that the red "x" that closes a window, really isn't red, but white on red background.

Years of thorough research have revealed that what people find beautiful about the Mandelbrot set is not the set itself, but all the rest.

Paul whoknows
Member #5,081
September 2004
avatar

Not a reply but an article itself. Bookmarked!. Johan, it would be nice if you continue with this stuff, this thread has become really interesting now.

____

"The unlimited potential has been replaced by the concrete reality of what I programmed today." - Jordan Mechner.

Johan Halmén
Member #1,550
September 2001

I don't intend to. That's all there is. The spinning thing could be interesting, but there are too many things that are involved in it. Are the objects like circles like in air hockey? Or are they balls like in pools? Are they slippery against the surface or do they stick like rubber? Not to mention differing masses.

[edit]
Well, this I did. The files are attached. I did it with OSX and Xcode, but it probably runs well on any machine. There's even a dialog in the code for some settings, but I didn't implement it yet. Probably won't. Three coloured circles move inside a box and collide against the box and each other. The objects actually never collide. They bounce in frame n if frame n+1 would make them overlap. And after they have bounced, they will move in the new direction no matter if the movement makes them overlap another object. If this occures, I have no idea what happens. They might get stuck inside each other. And each time frame gets rendered. In a game the time frame should be as short as possible while the rendering rate could be some 50 - 100 fps.

{"name":"592291","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/6\/8\/689a8a93efe3d3b96959c8a908edd4d4.png","w":809,"h":629,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/6\/8\/689a8a93efe3d3b96959c8a908edd4d4"}592291

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Years of thorough research have revealed that the red "x" that closes a window, really isn't red, but white on red background.

Years of thorough research have revealed that what people find beautiful about the Mandelbrot set is not the set itself, but all the rest.

gary_ramsgate
Member #8,619
May 2007

I found some code on the net, which I've modified slightly to suit my program.
It seems to work, with the balls bouncing off each other correctly. I'm not sure how it works, but it does :-)

sprite[??].x, sprite[??].y - sprite co-ordinates
sprite[??].dx, sprite[??].dy - sprite velocity

1//This is the main physics function for the balls.
2//It contains very basic but effective collision response code
3//the following code was modified by code written by Joseph 'Phish' Humfrey
4
5double c_mass=1;
6double c2_mass=1;
7double collNormalAngle=atan2(sprite[n1].y-sprite[n].y,sprite[n1].x-sprite[n].x);
8 
9// n=vector connecting the centre of the balls
10// we are finding the components of the normalised vector n
11double nX=cos(collNormalAngle);
12double nY=sin(collNormalAngle);
13 
14// Now find the length of the components of each movement vectors
15// along n, by using a dot product
16double a1=sprite[n].dx*nX + sprite[n].dy*nY;
17double a2=sprite[n1].dx*nX + sprite[n1].dy*nY;
18double optimisedP = (2.0 * (a1-a2)) / (c_mass +c2_mass);
19 
20// Now find the resultant vectors
21sprite[n].dx=sprite[n].dx - (optimisedP * c2_mass * nX);
22sprite[n].dy=sprite[n].dy - (optimisedP * c2_mass * nY);
23sprite[n1].dx=sprite[n1].dx + (optimisedP * c_mass * nX);
24sprite[n1].dy=sprite[n1].dy + (optimisedP * c_mass * nY);

Go to: