#### Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

# Playing pool with Pi

Posts: 7,599

I saw this topic on another forum and thought I’d try it with Codea. The subject is calculating the value of Pi by counting the number of collisions using 2 balls and a wall. What this program shows is a red ball moving towards a blue ball. I count the number of collisions that the blue ball has with the wall and the red ball. That count gives the value of Pi. Using M1 mass of 100 and M2 mass of 1, I can only get Pi to 1 decimal position. To get 2 positions, M1 has to be 1,000. 3 positions, M1 has to be 10,000, etc. The Codea Physics engine doesn’t work right if I use M1 mass with 1,000 or higher. That’s just too much of a mass difference between the 2 balls. This example for 1 digit is sufficient to show how this works. For more info, do a Google search on “Playing pool with Pi”.

``````displayMode(FULLSCREEN)

function setup()
physics.continuous=true
cnt=0
pi=0
nbr=2

b1=physics.body(CIRCLE,20)
b1.x=WIDTH
b1.y=140
b1.linearVelocity=vec2(-200,0)
b1.friction=0
b1.restitution=1
b1.info="ball"
b1.mass=10^nbr

b2=physics.body(CIRCLE,20)
b2.x=250
b2.y=140
b2.friction=0
b2.restitution=1
b2.mass=1

e1=physics.body(EDGE,vec2(0,120),vec2(WIDTH,120))
e2=physics.body(EDGE,vec2(0,0),vec2(0,HEIGHT))
e2.info="edge"
end

function draw()
background(40, 40, 50)
noStroke()
fill(255,0,0)
ellipse(b1.x,b1.y,40)
fill(0,0,255)
ellipse(b2.x,b2.y,40)
fill(255)

strokeWidth(2)
stroke(255)
line(0,120,WIDTH,120)
line(0,0,0,HEIGHT)
text("Calculate pi using physics collisions.",WIDTH/2,HEIGHT-100)
text('Do a Google search for "Playing pool with pi".',WIDTH/2,HEIGHT-140)
text("Count = number of blue ball collisions with the wall or red ball.",WIDTH/2,HEIGHT-200)
text("M1 = mass of red ball     100",WIDTH/2,HEIGHT-250)
text("M2 = mass of blue ball    1",WIDTH/2,HEIGHT-280)
text("Count = "..cnt,WIDTH/2,HEIGHT-350)
text("pi = Count/sqrt(M1)",WIDTH/2,HEIGHT-390)
text("pi = "..pi,WIDTH/2,HEIGHT-420)
end

function collide(c)
if c.state==BEGAN then
if c.bodyA.info=="edge" or c.bodyA.info=="ball" then
cnt=cnt+1
pi=cnt/10
end
end
end
``````

• Posts: 4,956

Hah I just watched a video on this. So cool to see that it actually works in code.

Though I notice if I increase the order of magnitude to 3 it does not simulate correctly

• edited January 18 Posts: 7,599

@Simeon I guess the Codea Physics engine can’t handle a mass that high (1,000) with collisions. The speed of the blue ball is just to great.

• Posts: 4,956

Yeah I think it breaks it This is like the most inefficient way to compute Pi, but really fun that it works

• edited January 19 Posts: 7,599

@Simeon Here’s a mathematical version of the graphics. This code was originally written in TiBasic by redsmith in another forum that I visit. I tried the original code on my TI 84 Plus SE and it worked, but was extreamly slow even for a few digits. I rewrote the code to run on the iPad. Use the slider to select the number of digits then press calc. It takes about 20 seconds to calculate 8 digits on my iPad Air. Each additional digit results in an increase of 10x. So 9 digits will take around 200 seconds.

``````function setup()
s=require("socket")
parameter.integer("digits",1,14,1,function() C=0 en,st=0,0 end)
parameter.action("calc",calc)
calc()
end

function draw()
background(0)
text("Pi "..C/(10^(digits-1)),WIDTH/2,HEIGHT/2)
text("Calc time  "..en-st,WIDTH/2,HEIGHT/2-100)
end

function calc()
en,st=0,0
output.clear()
print("start")
Z,C=0,0
M1=1
M2=100^(digits-1)
V1,V2=0,-1
cnt=0
st=s.gettime()
repeat
cnt=cnt+1
U=V1
Y=V2
V1=(M1-M2)/(M1+M2)*U+2*M2/(M1+M2)*Y
V2=2*M1/(M1+M2)*U+(M2-M1)/(M1+M2)*Y
if (V2-V1)<0 or V1<0 then
C=C+1
else
Z=1
end
V1=V1*-1
if (V2-V1)<0 or V1<0 then
C=C+1
else
C=C+1
Z=1
end
until Z==1
print("done")
en=s.gettime()
end
``````