У меня уже есть наработки по этому вопросу. Я написал код. Но сколько бы иголок я не "кидал" в каждой итерации, число pi = 3.1415... никогда не достигается. Самое близкое значение, которое я получил это 3.0985, но затем значение отдаляется и в среднем, получается около 2.7, хотя с повышением количества "брошенных" иголок значение должно быть всё ближе к pi. Рекомендую ознакомится с данной статьёй:
https://habr.com/ru/post/172827/
Код, который написал я, смотрите ниже:
from tkinter import Tk, Canvas
from random import randint
from math import sin, cos, pi
# https://habr.com/ru/post/172827/ - сайт, на котором брал инфу
amount_needles = 10
# Параметры полотна
CANVAS_OPTIONS = {
'width': 1220,
'height': 720,
'bg': 'black'
}
# Параметры иголок:
NEEDLES_OPTIONS = {
'fill': '#87939A',
'width': 2,
'length': 20
}
needles_ids = []
lines_ids = []
list_overlapping = []
def draw_lines(distance_bet_lines=NEEDLES_OPTIONS['length']):
global lines_ids
for coord_x in range(distance_bet_lines, CANVAS_OPTIONS['width'], distance_bet_lines):
lines_ids.append(canvas.create_line(coord_x, 0, coord_x, CANVAS_OPTIONS['height'], fill='#1E1E1E',
width=2))
def draw_needles():
global needles_ids
for amount_iterations in range(amount_needles):
coord_x = randint(0, CANVAS_OPTIONS['width'])
coord_y = randint(0, CANVAS_OPTIONS['height'])
random_angle = randint(0, 360)
needles_ids.append(canvas.create_line(coord_x, coord_y,
coord_x - cos(random_angle * pi / 180) * NEEDLES_OPTIONS['length'],
coord_y - sin(random_angle * pi / 180) * NEEDLES_OPTIONS['length'],
fill=NEEDLES_OPTIONS['fill'], width=NEEDLES_OPTIONS['width']))
def paint_needles():
for line in lines_ids:
line_coordinates = canvas.coords(line)
overlaps = canvas.find_overlapping(*line_coordinates)
for overlap_needle in overlaps:
if overlap_needle in needles_ids:
canvas.itemconfig(overlap_needle, fill='yellow')
list_overlapping.append(overlap_needle)
def process():
global amount_needles
global list_overlapping
global needles_ids
root.after(100, process)
draw_needles()
paint_needles()
print(f'Общее кол-во иголок: {len(needles_ids)}')
print(f'Кол-во иголок, которые пересекли нить: {len(list_overlapping)}')
print(f'Вероятность пересечения: {2 / (len(list_overlapping) / len(needles_ids))}')
print('-' * 50)
list_overlapping = []
def draw_chart():
pass
root = Tk()
canvas = Canvas(root, **CANVAS_OPTIONS)
canvas.pack()
draw_lines()
# TODO: за кол-во бросаемых иголок отвечает amount_needles, которая находится в 7 строке!!!!!
# TODO: Если нужно разом "бросить" все иголки:
# draw_needles()
# paint_needles()
# print(f'Общее кол-во иголок: {len(needles_ids)}')
# print(f'Кол-во иголок, которые пересекли нить: {len(list_overlapping)}')
# print(f'Вероятность пересечения: {2 / (len(list_overlapping) / len(needles_ids))}')
# TODO: Если нужно постепенно бросать иголки:
process()
root.mainloop()