我知道有很多关于如何使用Buffon's needles来计算pi的教程,但是我在tkinter中没有找到任何教程。
我是一个初学者,对脏代码很抱歉,但是稍后我将带您逐步了解。
绘制设置后,它将为直线的起点生成随机的x1和y1坐标。请注意,我希望线长为50个单位。因此,我生成了x_rel
,其范围在-50到50之间。之后,使用毕达哥拉斯定理,我计算了y_rel
。可以随机将其设为负,也可以保持正。要获得行的结束坐标,只需将x_rel
和x1
相加,即y。
为了检测与板上起始线之一的碰撞,我比较了y1和y2的第一个数字。如果它们相同,则不会发生冲突(这是可行的,因为板上的每条起始线之间的间隙为100)。计算完冲突后,我只需计算pi并打印即可。但它通常返回〜2,6。但是我在网上找到的其他类似程序可以用这种方法计算出pi的准确度。我的错误在哪里?
import tkinter as tk
import random
import math
count = 0
class App:
def __init__(self, root):
self.root = root
root.title("PI calculator")
c = tk.Canvas(root, height=700, width=700)
c.pack()
c.create_line(100, 100, 600, 100)
c.create_line(100, 200, 600, 200)
c.create_line(100, 300, 600, 300)
c.create_line(100, 400, 600, 400)
c.create_line(100, 500, 600, 500)
c.create_line(100, 600, 600, 600)
for x in range(100000):
c.create_line(self.generate_coords(), fill="red", width=1.5)
def generate_coords(self):
choices = [1, 0]
x1 = random.randint(100, 600)
y1 = random.randint(100, 600)
x_rel = random.randint(-50, 50)
y_rel = math.sqrt(50**2 - x_rel**2)
if random.choice(choices) == 1:
y_rel = -abs(y_rel)
if random.choice(choices) == 0:
y_rel = abs(y_rel)
x2 = x1 + x_rel
y2 = y1 + y_rel
col = self.detect_collision(y1, y2)
if col == True:
global count
count += 1
return x1, y1, x2, y2
def detect_collision(self, y1, y2):
first_num_1 = math.floor(y1/100)
first_num_2 = math.floor(y2 / 100)
if first_num_1 != first_num_2:
return True
else:
return False
root = tk.Tk()
window = App(root)
pi = (2*50*100000)/(100*count)
print(count)
print(pi)
root.mainloop()
38243
2.6148576210025363
答案 0 :(得分:0)
我试用了您的代码,并将其与类似的程序进行了比较,得出的结论是,您的图钉掉落没有应有的随机性,这使您的结果不正确。下面,我重新设计了掉线逻辑,结果似乎有所改善:
import tkinter as tk
import random
import math
NUMBER_STICKS = 250
LINE_DISTANCE = 100
STICK_LENGTH = 83
class App:
def __init__(self, root):
self.root = root
root.title("PI calculator")
self.collisions = 0
c = tk.Canvas(root, height=700, width=700)
c.pack()
for y in range(1, 7):
c.create_line(100, y * LINE_DISTANCE, 600, y * LINE_DISTANCE)
for _ in range(NUMBER_STICKS):
collision, *coords = self.generate_coords()
c.create_line(coords, fill="red" if collision else "green", width=1.5)
def generate_coords(self):
x1 = random.randint(100, 600)
y1 = random.randint(100, 600)
angle = random.randrange(360)
x2 = x1 + STICK_LENGTH * math.cos(math.radians(angle))
y2 = y1 + STICK_LENGTH * math.sin(math.radians(angle))
collision = self.detect_collision(y1, y2)
if collision:
self.collisions += 1
return collision, x1, y1, x2, y2
def detect_collision(self, y1, y2):
num_1 = y1 // LINE_DISTANCE
num_2 = y2 // LINE_DISTANCE
return num_1 != num_2
def get_collisions(self):
return self.collisions
root = tk.Tk()
application = App(root)
collisions = application.get_collisions()
print((2 * STICK_LENGTH * NUMBER_STICKS) / (LINE_DISTANCE * collisions))
root.mainloop()
输出
% python3 test.py
3.516949152542373
%
我还修改了程序,以将引脚的颜色编码为交叉或不交叉: