Python What is the Position of Two Colliding Balls in a 2D Box after 10 Seconds?

  • Thread starter Thread starter Arman777
  • Start date Start date
  • Tags Tags
    2d Balls Box
Click For Summary
The discussion revolves around simulating the motion of two colliding balls in a 2D box, specifically a billiard table setup. The balls, each with a radius of 20, decelerate at a rate of 5 m/s², and the goal is to determine their positions after 10 seconds. Participants highlight potential issues in the code, such as the handling of collision points, the sensitivity of results to initial conditions, and the need for more detailed comments for clarity. There is also a suggestion to implement an event-driven simulation to accurately calculate collision times, as well as concerns about the accuracy of the current time step (dt) used in the simulation. The conversation emphasizes the complexity of accurately simulating physical interactions between the balls.
  • #31
Arman777 said:
However, when I use atan2(), Pa[1] becomes an acceptable value but this time Pa[0], Pb[0] and Pb[1] are not within the range of the accepted value (sometimes they are but sometimes not)
I'm not sure what you mean by "acceptable value". The function atan2 will return the correct angle. What you do with that angle is up to you.
 
Technology news on Phys.org
  • #32
FactChecker said:
I'm not sure what you mean by "acceptable value". The function atan2 will return the correct angle. What you do with that angle is up to you.
When I use atan2 for dt = 0.001 I get
526.4046809656061 170.8742588241399 445.23248886773865 256.0652790027961
But for atan I get
341.36661845405075 44.75395042783804 338.65671584881693 84.45754194958526

I don't know why this happens.

FactChecker said:
The green line makes some unexplained changes of direction
I guess that's the part where two particles collide. Since they have a radius of 20. The collision will happen when they are near then 40. Since we are plotting these datas on the graph this change might have looked like a direction change.
FactChecker said:
I assume that he means that the initial conditions of the simulation must match the initial conditions of the actual data.
I am just copying the initial conditions copying them and putting them on a file to run the code. Theres no mistake in there.
FactChecker said:
I don't know what to think about this. I am not a Python programmer. I would not trust a program that accepted that as valid code.
Python:
Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) [MSC v.1914 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> def motion(a):
...     return 2 * a
...
>>> if motion:
...     print("yey")
...
yey
>>>

Its in the core of the python. I mean it somehow works. Its of course wrong to use it like that... Weird side of the python :p

FactChecker said:
you to dump as much data as possible
What do you mean by dump as much as data. Like giving some random meaningful inputs and see what happens ?. Also I couldn't do it before since one of my functions were wrong...
I tried a simple case for the linear momentum conservation now I ll try with introcuding some angles.. and we will see.

Okay I ll try that
 
  • #33
When you use if on a non-boolean object in python it converts it to a boolean

>>> [(i,bool(i)) for i in [None, 0, 0.0, 3.14, "abc", "", 'a', '',True, False, [1,2,3],[]]]
[(None, False), (0, False), (0.0, False), (3.14, True), ('abc', True), ('', False), ('a', True), ('', False), (True, True), (False, False), ([1, 2, 3], True), ([], False)]

in the case of the motion function it is the same as saying "if motion(x) != 0"
 
  • Like
Likes Arman777
  • #34
Arman777 said:
When I use atan2 for dt = 0.001 I get
526.4046809656061 170.8742588241399 445.23248886773865 256.0652790027961
But for atan I get
341.36661845405075 44.75395042783804 338.65671584881693 84.45754194958526

I don't know why this happens.
What do you mean "you get" these numbers? Both functions return an angle, not position values. Are these the final results of the 10 second run? That is no help at all, with all the questionable stuff happening before the end of the run.
I guess that's the part where two particles collide. Since they have a radius of 20. The collision will happen when they are near then 40. Since we are plotting these datas on the graph this change might have looked like a direction change.
It looks like one ball changes direction, but the other does not. So how can that be a collision?
What do you mean by dump as much as data. Like giving some random meaningful inputs and see what happens ?.
I mean that you should print a lot of detailed data to a file so that you can see exactly what calculations are happening at each step. Put prints at every key point in your code so you can see the exact calculation results. There are some points in the plots where one ball changes direction but I don't see the other ball change direction. You need to see what is happening there. A file of data would help. Until then, we are just blind to what is going on.
 
Last edited:
  • #35
DavidSnider said:
When you use if on a non-boolean object in python it converts it to a boolean

>>> [(i,bool(i)) for i in [None, 0, 0.0, 3.14, "abc", "", 'a', '',True, False, [1,2,3],[]]]
[(None, False), (0, False), (0.0, False), (3.14, True), ('abc', True), ('', False), ('a', True), ('', False), (True, True), (False, False), ([1, 2, 3], True), ([], False)]

in the case of the motion function it is the same as saying "if motion(x) != 0"
Thanks for the info
FactChecker said:
There are some points in the plots where one ball changes direction but I don't see the other ball change direction.
Yes I noticed that too. The thing is one ball changes its direction and other the other one dont. Its really confusing for me.
I also noticed that atan is wrong and atan2 works.
 
  • #36
[CODE lang="python" title="Colliding_Ball"]from math import sqrt, atan2, sin, cos, pi, inf
from numpy import array

W = 600 # width of the table
H = 300 # height of the table
R = 10 # the radius of the ball
A = 0 # deceleration constant
dt = 10 ** -3
ma = mb = 1 # masses of the particles a and bdef vec_magnitude(V1):
return sqrt(V1[0]**2 + V1[1]**2)def collision_test(V1, V2):
if vec_magnitude(V1 - V2) <= 2 * R:
return Truedef dot_product(V1, V2):
return sum(V1 * V2)def after_collision_velocity(Va, Vb, Ra, Rb):
''' the equation that produces the velocity of the objects after the collision'''
Va_new = Va - ((2 * mb * dot_product(Va - Vb, Ra - Rb)) /
((ma + mb) * (vec_magnitude(Ra - Rb))**2) * (Ra - Rb))
Vb_new = Vb - ((2 * ma * dot_product(Vb - Va, Rb - Ra)) /
((ma + mb) * (vec_magnitude(Rb - Ra))**2) * (Rb - Ra))
return Va_new, Vb_newdef check_reflection(P, V_mag, angle, V):
if P[1] < R:
P += array([0, 2 * (R - P[1])])
angle *= -1
return P, V_mag, angle, V
if P[0] < R:
P += array([2 * (R - P[0]), 0])
angle = pi - angle
return P, V_mag, angle, V
if P[1] > H - R:
P += array([0, 2 * (H - R - P[1])])
angle *= -1
return P, V_mag, angle, V
if P[0] > W - R:
P += array([2 * (W - R - P[0]), 0])
angle = pi - angle
return P, V_mag, angle, V
else:
V_mag -= A * dt
Vx = V_mag * cos(angle)
Vy = V_mag * sin(angle)
P += array([Vx * dt, 0])
P += array([0, Vy * dt])
V = array([Vx, Vy])
return P, V_mag, angle, Vfile = open("test_drawing.txt", "w")
for line in open("tex.txt", "r"):
t = 0
Xa, Ya, Xb, Yb, Vxa, Vya, Vxb, Vyb = [
int(i) for i in (line.rstrip()).split(" ")]
Pa = array([Xa, Ya], dtype=float)
Pb = array([Xb, Yb], dtype=float)
Va = array([Vxa, Vya], dtype=float)
Vb = array([Vxb, Vyb], dtype=float)
Va_mag = vec_magnitude(Va)
Vb_mag = vec_magnitude(Vb)
if Vxa == 0:
Vxa = inf
angle_a = atan2(Vya, Vxa)
if Vxb == 0:
Vxb = inf
angle_b = atan2(Vyb, Vxb)
while t <= 10:
Pa, Va_mag, angle_a, Va = check_reflection(Pa, Va_mag, angle_a, Va)
Pb, Vb_mag, angle_b, Vb = check_reflection(Pb, Vb_mag, angle_b, Vb)
if collision_test(Pa, Pb) == True:
Va, Vb = after_collision_velocity(Va, Vb, Pa, Pb)
Va_mag = vec_magnitude(Va)
Vb_mag = vec_magnitude(Vb)
if Va[0] == 0:
Va[0] = inf
angla_a = atan2(Va[1], Va[0])
if Vb[0] == 0:
Vb[0] = inf
angle_b = atan2(Vb[1], Vb[0])
t += dt
file.write(str(Pa[0]) + " " + str(Pa[1]) + " " + str(Pb[0]) + " " + str(Pb[1]) + "\n")
print(Pa[0], Pa[1], Pb[0], Pb[1])
file.close()
[/CODE]

[CODE title="data for a simple collision program"]100 200 140 200 4 4 -4 4[/CODE]

[CODE lang="python" title="Drawing Program"]from pylab import plot, show

Xa = [100]
Ya = [200]
Xb = [140]
Yb = [200]

for line in open("test_drawing.txt", "r"):
data = [float(i) for i in line.split(" ")]
Xa.append(data[0])
Ya.append(data[1])
Xb.append(data[2])
Yb.append(data[3])

plot(Xa, Ya, "-r")
plot(Xb, Yb, "-.g")
show()
[/CODE]

Now when you run this you ll get a data of points for each coordinate (Pa, Pb).

The image is like this
Figure_1.png

Its clear that ball b reflects but ball a does not. Thats really strange... I mean ball b acts like normal but not the a..

Who can spot the error :angel::angel:, cause I cannot.

P is the position vector so Pa and Pb are the position vectors of the ball a and ball b respectively. V is the velocity.
 
  • #37
I wrote angla_a instead of angle_a ... that was the reason.. So simple ..
FactChecker said:
It's my experience that it is possible to stare at code for a long, long time without spotting a simple error
The case has been proved :)
 
Last edited:
  • Like
Likes Klystron, jedishrfu and FactChecker
  • #38
Each of these kinds of mistakes that you've made and fixed gives you a personalized list of things to check in your code.

Interpretive languages often fall down in this respect where any variable name can be defined incorrectly and it will use it.

I once tried to teach a coworker on how to write programs. My first assignment to him was to enter some code I wrote on paper. I told him to see if he could get it working. He successfully got it to compile but it was most certainly wrong. Due to spelling mistakes in variable names, partly my fault and partly his typing, the compiler would indicate variable xyyzy was undefined and so he defined it not realizing that it was already defined as xyzzy. However, he didn't understand the flow of the program and so added a new variable instead of correcting the spelling mistake.

I know in python if you call a variable before it's defined you will get a warning. However, I've seen cases in my own code where I accidentally reused the wrong indexing variable in a loop and nothing was said. It's only through knowing what you wrote and why you wrote it that the error is spotted quickly.

Lastly, try not to get bogged down in the accuracy of your numbers early on. I had a boss once who was always suspicious of the COBOL compiler math that he would insist on looking at the machine code it generated. Later, I found this was due to some hardware issues with the extended math processor that computed using packed decimal format which COBOL routinely used for some datatypes. However, he never found anything wrong.
 
  • Like
Likes Klystron, Arman777 and FactChecker
  • #39
jedishrfu said:
I know in python if you call a variable before it's defined you will get a warning.
This is a good reason to take a very hard look at anything that gives a warning. Otherwise, typos are very hard to spot.
 
  • Like
Likes Klystron, Arman777 and jedishrfu
  • #40
FactChecker said:
Otherwise, typos are very hard to spot.
Indeed they are...I guess I should have noticed it before.
jedishrfu said:
Lastly, try not to get bogged down in the accuracy of your numbers early on.
I agree..Well I run the code and It worked yey!

So the problem is solved. Thank you all for your help
 
  • Like
Likes Klystron
  • #41
Arman777 said:
Indeed they are...I guess I should have noticed it before.
My advice for the future is to get in the habit of following the coding standards that an editor like PyCharm uses. That will minimize the PyCharm warnings due to cosmetic things and it will be easier to spot the remaining serious errors. I brought your code into PyCharm (free version) and it did flag the angla_a typo, but it was among so many other warnings that it was easy to overlook. I am not familiar with PyCharm, but a good editor will allow you to control the types of things that generate a warning. I didn't see a way to control that in the PyCharm free version.

EDIT: The free version of PyCharm has an option under Code => Inspect Code that immediately spotted the 'angla' typo as a serious problem.
 
  • Like
Likes Arman777
  • #42
FactChecker said:
My advice for the future is to get in the habit of following the coding standards that an editor like PyCharm uses. That will minimize the PyCharm warnings due to cosmetic things and it will be easier to spot the remaining serious errors. I brought your code into PyCharm (free version) and it did flag the angla_a typo, but it was among so many other warnings that it was easy to overlook. I am not familiar with PyCharm, but a good editor will allow you to control the types of things that generate a warning. I didn't see a way to control that in the PyCharm free version.

EDIT: The free version of PyCharm has an option under Code => Inspect Code that immediately spotted the 'angla' typo as a serious problem.
When I started coding a year ago I started with python IDE then I switched to PyCharm. PyCharm was great for me back then but it seemed slow to me. Then this year I updated the Pycharm and it was really slow( I guess there was some kind of a bug) then, I discovered VS code. VS code seems ligther and somewhat faster. I noticed that I can easily switch files, create different files just easily in the VS Code etc. But I guess PyCharm is more focused on the python. Maybe I should start to use it. Thanks
 
  • Like
Likes FactChecker