Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

DarkBASIC Discussion / how do I code pool ball physics?

Author
Message
Latch
18
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 17th Aug 2006 03:40 Edited at: 2nd Oct 2006 03:05
[Edit]
(See bottom of thread for math update)
From time to time I come back to this to see If I can add to or change the method I'm using. There is something called "the 90 degree" rule which basically means after a collision, the directions of the pools balls will always be 90 degrees of each other. The only way I see this as possible is if the cue ball loses all of it's velocity along the collision normal to the ball being struck, and then the cue ball would just have it's velocity along the tangent - which would be 90 degrees to the collision normal. I don't see the cue ball losing all of it's velocity along the collision. It transfers a certain amount to the struck ball, but retains a little bit it the same direction. This plus the tangent vector add up to a direction that isn't quite 90 degrees.

I don't know if anyone can comment or verify my suppositon. I tried the 90 degree rule and got back collision behaviour that didn't look real to me. So I'll stick to my current method outlined towards the end of this thread. I've got to update it and change a couple of things because I can tell it still isn't quite right.


[Old - Second]
Actually, I am interested in the physics of this - in terms of code. And I now realize this isn't as simple of a routine as I had originally thought.

[Old - Original]

I need to create a simple routine that when two objects collide, based on their velocity and mass, they bounce off of each other at the correct angles and velocity.

I've already got the collision detection part. Now I just need the physics of the bounce. I don't want to use a dll - I don't care about gravity, and I don't care about the objects "jumping" up on the y axis. At this point, I don't care about ground friction. I do care about deceleration, however.

I'm really interested in this in terms of code, as opposed to generic physics equations.

Any help would be appreciated.

Enjoy your day.
Zotoaster
20
Years of Service
User Offline
Joined: 20th Dec 2004
Location: Scotland
Posted: 17th Aug 2006 15:35 Edited at: 17th Aug 2006 15:36
I'm not entirelly sure how it would be done, but the best thing to do is draw a picture, here's one I made:



The black circles are the balls, the red line shows the angle between the balls, the three green ones show the angle perpendicular to the red line (90 deg added on). The the blue lines show the angle of incidence, and the angle of reflection, if you look at the orange shaded bits, you will notice that they are both the same compared to the green lines.

The blue lines could be velocity, but I recommend you made it force or acceleration, so it would be easier to change the speeds using mass.

For this to work, your collision detection would really have to be, detection. If you've already coded it to stop the balls when they touch, start again .

So basically, if you collide:
a=angle between balls
b=a+90
ball_1_angle2=b-ball_1_angle 1
ball_2_angle2=b-ball_2_angle 1


As for deceleration, it's simple, just multiply the velocity by something less that 1 every loop, like:
vx=vx*0.98
etc..

Not sure if the bouncing bit is how it's actually done, but that's how I think it's done just from thinking about it

Latch
18
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 17th Aug 2006 23:47
Hi Z,

Well, I had a feeling I was trying to get away without doing the work! I was hoping someone would say, "oh that? the answer is 5!"

Your diagram helps a lot! It looks right...

So let's say, we have two objects. For ease, they both have a mass of 1, and the following properties:

v1=10 , ball_1_ang_1 = 50 | v2=0, ball_2_ang2 = 0 (not moving)
a = 0

With all this we calculate:
b=a+90 = 90
ball_1_ang_2= b-ball_1_ang_1
ball_1_ang_2= 40

Is this right? Shouldn't the angle be 50... I suddenly have lost the whole concept...

Enjoy your day.
Zotoaster
20
Years of Service
User Offline
Joined: 20th Dec 2004
Location: Scotland
Posted: 18th Aug 2006 00:53
There's no reason for it to be 50. When people say that the angle of reflection is the angle of incidence, well it's true really, but just backwards. That's why in programming you can't just leave it the same.

As for the image, I'm not entirelly sure that's right, because the velocity of one ball should affect the velocity of the other. It gets more complicated then I'm guessing. I think somewhere in the DBPro coding challenges thread there's a pool challenge. Since you have DBC I will try to convert one for you, but not tonight heh

Latch
18
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 18th Aug 2006 06:09 Edited at: 18th Aug 2006 06:17
Thank you, but please don't go to too much trouble! If it's an easy conversion, great!

I think I may have an answer with a slight modification to your orignal code:

a = angle between balls (collision normal)
b = a + 90 (looks like tangent to the normal)
c = (b - ball_ang_1) * 2
ball_ang_2 = ball_ang_1 + c

assign some numbers: a = 0, b = 90, ball_ang_1 = 50

c = (90-50) * 2 = 40 * 2 = 80
ball_ang_2 = 50 + 80 = 130

test: cos ball_ang_1 = cos 50 = .643
cos ball_ang_2 = cos 130 = -.643

So does this all come down to 180 - ball_angle ? If it does, I'm gonna kick myself!

cos 40 = .766
cos 180-40 = cos 140 = -.766

cos 72 = .309
cos 180-72 = cos 108 = -.309

Looks like it does! But maybe I'm not thinking right... Any thoughts?

I think I got the velocity:

mass obj1 = 10, v obj1 = 30, mass obj2 = 5, v obj2 = 0

momentum
before collision
obj1 mass 10 * 30v = 300
obj2 mass 5 * 0v = 0
total 300

after collision
obj1 mass 10 * ?v
obj2 mass 5 * ?v
total 300

mass 15 * v = 300
v = 300/15
v = 20

final
obj1 200
obj2 100
total 300

So obj1 slowed down 10 and obj2 sped up 20. Their v end up being the same.

Enjoy your day.
The Wilderbeast
19
Years of Service
User Offline
Joined: 14th Nov 2005
Location: UK
Posted: 19th Aug 2006 21:29
have you made a pong program before? cus it's exactly the same as that

Sven B
20
Years of Service
User Offline
Joined: 5th Jan 2005
Location: Belgium
Posted: 20th Aug 2006 23:48 Edited at: 20th Aug 2006 23:50
Actually... It isn't! Pong only deals with walls that are either 0° or 90°, where the calculations are way easier. Now we have to calculate the angle between each ball it will collide with, and use that angle to calculate the new angle etc.

I have to draw it to see how you calculate it. But now... I need some rest, it was 3.00h in the morning when I finally got to sleep...

It's the programmer's life:
Have a problem, solve the problem, and have a new problem to solve.
RUCCUS
20
Years of Service
User Offline
Joined: 11th Dec 2004
Location: Canada
Posted: 21st Aug 2006 02:11 Edited at: 21st Aug 2006 02:20
<EDIT>

Sorry, I was lazy, didnt read the entire thread. Ignore this post then

</EDIT>


It might not get you the satisfaction if figuring out all of the maths behind the direction the balls should go, but either way I'd recommend using Sparky's dll. It returns the bounce angles on the x,y and z axis when an intersection occurs with a normal by using trig. So basically, cast a ray from the center of the cue to the radius of the cue, in the direction the cue is going, pseudo;

OStore the cue in group 1
Store all balls except the cue in group 2
When the cue is hit, store it's current X/Z position (since y doesnt change), then move the cue by whatever speed you want + the cue's radius, and store these x/z position, and then move the cue backwards by the cue's radius. I didnt explain that too well so some code;



OX# and OZ# are the cue's old position, and NX# and NZ# is the position right infront of the cue. You could also use the newvalue commands to achieve these coordinates.

Now you plug in this info into the intersect object command, and if an intersection occurs the distance to the intersection is returned. Then you use the bounce commands that come with sparky's dll to record the bounce angles on the y axis, rotate the cue to that direction, and rotate the ball the cue hit to the bounce direction plus 180.

The rest is just handling the ball speeds.

Ill try and throw together a demo later tonight but no guarantees, gotta get up early tomorrow.


Projects: Online CTF Game | Newcommer's Guide to FPS's
Latch
18
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 21st Aug 2006 03:50 Edited at: 21st Aug 2006 09:08
Thank you guys for all the help!

@Wilderbeast - there are some similarities with pong, but the angles between the balls and the motion of the balls make the calculations a little different.

@ Sven B

The biggest problem I'm having is when the cue is coming at a ball from 180 or 0 degrees. Even if it is lined up with the collision normal (not a glancing shot), it bounces at a 90 degree angle when it should be hitting flush. I'm using cos and sin to break down the angle of motion into the x and z components... At 180, x is always -1, and at 0 it is always 1 - thus the 90 degree angle in the x direction. It has something to do with the way I'm calculating the angle to the normal - and maybe even the normal itself.

@RUCCUS

That sounds very reasonable.

The thing with Sparky's dll is that it casts a ray - so I'm assuming the ray comes from the direction the ball is facing. If the collision detection is based on the ray, then a ball that wasn't in the direct path of the ray but was in essence "grazed" or "kissed" by the passing cue wouldn't be detected as a collision.

Part of the trick is in being able to disregard the direction that any ball is facing. Maybe Sparky's dll will account for this - I don't know cause I've had a lot of trouble trying to use that dll in general.

The main problem I'm having, which Zotoaster helped a lot with, is finding the angle to the normal of collision.

If the cue is rolling at 140 degrees relative to the table, it collides with another ball forming a 45 degree collision normal. What is angle to the normal?

Logically it looks like 180-(direction-normal)
180 -(95) =85
So 85 degrees would be the angle to the collision normal.

But what if we had a normal that was perpendicular to our orignal normal of 45? That would 135 degrees.

So if the ball was again rolling at 140 degrees we would have:

180 - (140-135) = 175

The answer should be 5 - So I'm having trouble coming up with a general formula to calculate the angle to the normal. Once I get this, I got a pretty good idea how to calculate the resultant vectors - but we'll see about that!

Keep the help coming! I'm probably missing the most basic part of this whole thing.

Enjoy your day.
Latch
18
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 22nd Aug 2006 05:10
Should I not be trying to find the angle to the normal for the initial collision? Maybe I should just be using the angle relative to the pool table?

So if my cue ball is traveling at 140 degrees relative to the table and strikes another ball creating a collision normal of 45 degrees, do I care about the angle that is formed between the direction the cue ball was traveling and the collision normal, or would I do my calculations just based on the direction the cue was rolling?

This is where I get stuck. If it's just the angle relative to the table, then the velocity is just v*cos(140) (collision along the normal) and v*sin(140) (tangent to the collision normal).

But if I have to worry about the new angle formed between the collision normal and the angle the ball was rolling then it looks a little bit more like v*cos(85) and v*sin(85)

Enjoy your day.
Latch
18
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 23rd Aug 2006 11:27 Edited at: 23rd Aug 2006 11:29
In case anyone's interested. I looked over what posts I could find about pool in the DBPro forums, but it was a bit hard to decifer - and I couldn't find an example where the author claimed it worked well.

I did, however, manage to come up with an idea of how to calculate the angle between the cue ball's direction and the collision-normal. It is almost what Zotoaster had said. Though I actually ended up using triangle math to solve it (download diagram):

The cue ball is moving in direction d. The cue ball could be moving in any direction so don't get hung up on the fact that I drew it along the X axis. It doesn't matter.

The cue ball strikes another ball. n is where the centers of mass align also known as the collision normal. The collision normal has an angle realtive to the pool table, but we don't care about that. We want to know what angle is formed by d and n.

This is angle A. I should've seen this before, but a nice right triangle can be formed if we draw a perpendicular from d to the center of mass of the second ball. We'll call this P (for perpendicular).

Now it's easy to solve A with a little trig. Since we have the Opposite side P and the Hypotenuse n, we can solve A using sine.

sinA = P/n
A = asin(P/n)

Now that should be one troublesome piece out of the way. Now things start to get complicated.

Enjoy your day.

Attachments

Login to view attachments
Zotoaster
20
Years of Service
User Offline
Joined: 20th Dec 2004
Location: Scotland
Posted: 23rd Aug 2006 21:03
Don't forget about quadrants. It simples everything down if you use the atanfull() command instead to work out the angle. But it seems you're starting to work this out quite well - oh, by the way, the code I told you about that I found on the DBPro forums, well I can't translate it because it uses a plugin called ODE, and that does all the work, not the code, sorry heh.

Xenocythe
19
Years of Service
User Offline
Joined: 26th May 2005
Location: You Essay.
Posted: 23rd Aug 2006 21:25
Here is my calculation of the physics.
The green ball is primarily moving in the direction of the big black arrow. It strikes the ball and as you can see the line between the two balls is the angle of both pool balls on where they collided. You create perpendicular right angles out of it, and use the angle 45 degrees in between as to where the pool balls will end up.

At least, thats what my freinds dad (His job works with physics) explained to me. I'm pretty sure I remember it like that...


Attachments

Login to view attachments
Xenocythe
19
Years of Service
User Offline
Joined: 26th May 2005
Location: You Essay.
Posted: 23rd Aug 2006 21:26
Woops, place the red arrow on the left side of the anlge


Latch
18
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 24th Aug 2006 03:43 Edited at: 30th Aug 2006 08:22
Thank you for helpin' out!

@Xenocythe
I think there may be a piece of information missing in that scenario. If the balls hit head on and assuming the cue isn't spinning clockwise or counter-clockwise, the direction of force would be directly away from each other. The target ball would go straight forward, and the cue ball would slow down but continue forward. The velocity does have 2 components though - One is the line directly between the balls like you said, the other is tangent to the point of collision (the perpendicular) also like you said. The tangent line's velocity never changes - so in a head on collision, there wouldn't be any movement along that line at all. But with a little bit of an angle from the cue ball, suddenly, there is velocity along the tangent line... The line between the balls and the tangent line, will make up the slope for the new direction of each ball. The closer the collision is to 45 degrees, the closer the direction the balls end up would be 45 degrees to the perpendicular I think... I might be totally off my rocker.

@Zotoaster

Big question on quadrants. On this 3d pool table, z is north-south, and x is west-east. Effectively in 2d, z would be y, and x would be x, right? So, in DarkBASIC, looks like 0 degrees points in the positive z direction, then increases clockwise. On the standard set of axes I'm used to, 0 degrees points in the positive x direction and increase counter-clockwise.

How do I apply quadrants to all this if the trig functions return values based on the standard coordinate system, and any angle functions in DB return the clockwise values of DB?

Enjoy your day.
Zotoaster
20
Years of Service
User Offline
Joined: 20th Dec 2004
Location: Scotland
Posted: 31st Aug 2006 01:21
I followed what you said up to pretty much the last sentence. Are you looking to work out the angle between the balls? I know that involved quadrants, so you can use the atanfull() command.

Just tell me if I'm not following what you're talking about

Latch
18
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 2nd Sep 2006 06:23
Hi, thanks everyone for the input.

@Zotoaster

I guess it does come down to the angle between the balls. It's not the angle from one midpoint to the other midpoint of the ball (the collision normal) that I'm having trouble with, but it's the angle between the line of collision and the direction the ball(s) are rolling. Every time I think I have it figured out, I come upon another problem.

One of the goals is to conceive of the balls as "free floating." By that I mean they can travel in any direction independent of which way they are facing. Kinda like a puck on an air-hockey table. So, I have to be able to capture that direction and from that, and find the angle between the direction and the collision normal. A big problem I keep running into is finding a consistant direction (represented by an angle). I tried using the OBJECT ANGLE
command, but it's results are based on which direction the object is facing.

If I can't figure out the trig and physics, I might abandon the compexity of this and just use a Pong type method like The Wilderbeast suggested... But I really want to use the physics and get this right!

Right now, it's close to working, but inconsistenty...

I'm also using CUVREVALUE to make the objects slide around with acceleration and deceleration. I might have to scrap my current method and start from scratch.

Is there a simple way to code a generic acceleration? Would it be something like:



Enjoy your day.
Zotoaster
20
Years of Service
User Offline
Joined: 20th Dec 2004
Location: Scotland
Posted: 2nd Sep 2006 12:11 Edited at: 2nd Sep 2006 12:21
Acceleration is easy, basically do what you did:

Velocity=Velocity+Acceleration

but to give it some sort of maximum speed, it's not very realistic to do:
If Velocity>Maxmimum then Velocity=Maximum

I would do:
Velocity=Velocity * (a number less that 1, i.e. 0.98)


Anyway, to save you getting into a big moger, I found this in the Code Snippets section. It's 2D ball collision using vectors, by Phaelax. It's easy to change to 3D, and I also converted it to DBC for you. Mind you, it ran smoother on DBPro, maybe it would help if it was changed to 3D aswell...




[edit]
Here it is in 3D, it also shows how to use the friction. Use the upkey to increase the velocity after the friction has made all the balls stop.

Btw, it's hard to tell where the bounds are for the area that the balls stay in, but that doesn't really matter right now.


Latch
18
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 2nd Sep 2006 19:27
@Z

Thank you for the code! The demos look pretty good. I'll have to play around with them. My model looks similar, but I have one more angle that keeps throwing me off...

This helps a lot! Thanks again!

Enjoy your day.
Zotoaster
20
Years of Service
User Offline
Joined: 20th Dec 2004
Location: Scotland
Posted: 2nd Sep 2006 19:31
Thank Phaelax!

Latch
18
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 21st Sep 2006 21:38
Thank you Phaelax

Enjoy your day.
Latch
18
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 21st Sep 2006 23:19 Edited at: 2nd Oct 2006 03:06
I let this rest for a while but came back to it because I wasn't satisfied. Studying up on rudementary physics and trig I've come to the conclusion that a lot of the demos and explanations on the internet are incomplete and in some cases just wrong. Or, on the opposite side of the coin, I am incomplete or just plain wrong!

Anyway, I went back to conservation of momentum principles, crashed a couple of matchbox cars together over and over to see what they were doing, and took another stab at my collision routine. As I had written previously, the big problem was dealing with an indirect hit, or glancing collision and dealing with the angle in relation to the collision normal.

In my scenario, I'm neglecting the influence of friction between the objects, and I'm neglecting spin. But I'm including deceleration which implies friction with the surface. What I've come up with seems to accurately depict colliding sphere's in 2 dimensions most of the time. Because of a bug, the sphere's sometimes go off in bizaar directions - I'll have to track that down.

The big problem with the angle between the balls actually had something to do with the atanfull() function. It calculates angles in the opposite direction to sin() cos() and tan(). This was a big deal because it threw off my calculations over and over and I couldn't figure out why. After reviewing a similar function in C, atan2(), I discovered that if I just reversed the x and the y in the atanfull() function and was fine! (I used atanfull(y,x) instead of the help file indication of atanfull(x,y) ). Now I could effectively calculate the angle between the collision normal (CN), and the direction a ball was traveling (this is the angle one ball hits the other at).

Ok this is fine. But now, in every case, this newly found angle always treated the CN as the x axis, regardless of what the CN angle was. I fixed this by calcuating the formed angle as if it were at the origin, and then just rotated the results to the angle the CN really was.

Here's some psuedo code of the procedure:



This is basically where I am with this right now. It does a pretty good job but there are a few glitches. If anyone can give any feedback that would be great.

I've included a demo. Needs a little work on the collision detection, but it's functional for the most part.

Enjoy your day.

Attachments

Login to view attachments

Login to post a reply

Server time is: 2025-05-25 22:32:26
Your offset time is: 2025-05-25 22:32:26