Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Tk_monte_carlo_pi.py
- #!/usr/bin/env python3
- # How this works:
- # Area of the circle = πr²
- # Area of bounding box = (2r)²
- #
- # We know that the chance of selecting inside the circle (P) is area of
- # circle / area of bounding box
- # P = (πr²) / (2r)²
- #
- # We can calculate P by putting a bunch of points into the box and seeing
- # how many are inside of the circle. H is hits, T is tries.
- # P = H / T
- #
- # Now let's move some numbers around
- # P = (πr²) / (2r)²
- # H / T = (πr²) / (2r)² <- P = H / T
- # H / T = πr² / 4r² <- (2r)² = 4r²
- # H / T = π / 4 <- r² cancels out
- # 4 * H / T = π <- Multiply both sides by 4
- # π = 4 * H / T <- Flip the sides
- import math
- import random
- import tkinter as tk
- INTERVAL = 1
- DOT_RADIUS = 2
- RADIUS = 300
- BORDER = 5
- CENTER = BORDER + RADIUS
- MAX_TRIES = 1000000
- class Application(tk.Frame):
- def __init__(self, master=None):
- super().__init__(master)
- self.grid()
- self.create_widgets()
- self.hits = 0
- self.tries = 0
- def create_widgets(self):
- self.pi_label_text = tk.StringVar()
- self.pi_label_text.set('π = ?')
- self.pi_label = tk.Label(self, textvariable=self.pi_label_text)
- self.pi_label.grid(row=1)
- pi = '{:.6f}'.format(math.pi)
- self.pi_label_text2 = tk.StringVar()
- self.pi_label_text2.set(pi)
- self.pi_label2 = tk.Label(self, textvariable=self.pi_label_text2)
- self.pi_label2.grid(row=2)
- self.canv = tk.Canvas(
- self,
- width=(BORDER * 2 + RADIUS * 2),
- height=(BORDER * 2 + RADIUS * 2))
- self.canv.grid(row=3)
- self.canv.create_oval(
- BORDER, BORDER, BORDER + RADIUS * 2, BORDER + RADIUS * 2)
- self.after(INTERVAL, self.add_dots)
- def rand_x_y(self):
- x = random.randint(BORDER, BORDER + RADIUS * 2)
- y = random.randint(BORDER, BORDER + RADIUS * 2)
- return x, y
- def in_circle(self, x, y):
- return math.sqrt((x - CENTER) ** 2 + (y - CENTER) ** 2) <= RADIUS
- def add_dots(self):
- if self.tries >= MAX_TRIES:
- return
- x, y = self.rand_x_y()
- if self.in_circle(x, y):
- self.hits += 1
- color = "#0f0"
- else:
- color = "#f00"
- self.tries += 1
- self.canv.create_oval(
- x - DOT_RADIUS, y - DOT_RADIUS,
- x + DOT_RADIUS, y + DOT_RADIUS,
- fill=color, outline=color)
- pi_guess = 4 * float(self.hits) / (self.tries)
- self.pi_label_text.set('{:.6f}'.format(pi_guess))
- self.after(INTERVAL, self.add_dots)
- root = tk.Tk()
- app = Application(master=root)
- app.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement