Liczbę PI możemy wyznaczyć na bardzo wiele różnych sposobów. Jednym z nich jest zaprzęgnięcie do pracy prostej probabilistyki. Estymacja polega na wybraniu losowo punktów na kwadracie i kole. Świetny przykład jak można użyć prawdopodobieństwa i podstawowej geometrii do robienia niesamowitych rzeczy!
1. Płytka esp8266
2. Wyświetlacz oled
3. Kilka kabli
4. Guzik
1. Komputer z programem Thonny
Na czym polega projekt?
Projekt polega na estymacji liczby pi korzystając z losowo wybranych punktów na kwadracie. Wszystko wyświetlimy na ekranie i dodatkowo będziemy mogli "dodawać" kolejne punkty na rysunku ręcznie (klikając guzik).
Jak to działa?
Wyobraźmy sobie kwadrat o boku 1. Teraz rysujemy wycinek koła w taki sposób, aby połączyć dwa wierzchołki kwadratu, a środek okręgu był w wierzchołku między nimi (patrz obrazek). Jakie jest pole kwadratu? Proste! bok*bok=1*1=1. A jakie jest pole koła? Też proste: PI*R^2. Promień R też jest równy 1, czyli nasze pole to równe PI. Korzystamy z wycinka koła na kwadracie w taki sposób, że mamy narysowaną 1/4 koła, czyli pole naszego wycinka to PI*R^2*(1/4) = PI*1/4.
Robiąc stosunek pola koła do pola kwadratu uzyskamy nasze PI/4 (patrz rysunek).
Teraz wylosujmy położenie np.15000 punktów. Wykorzystamy to czy są wewnątrz okręgu czy na zewnątrz. Stosunek ilości punktów wewnątrz do zewnątrz proporcjonalny do stosunku naszych pól. Czyli PI/4.
W kodzie ten wynik pomnożymy razy 4 uzyskując czyste PI.
Podaję dwa kody:
-kod dzięki któremu możemy dodawać pojedynczo nasze punkty(klikając guzikiem, bardzo wolny)
-kod który automatycznie narysuje wszystkie zadane punkty (na początku kodu można zmieniać ich ilość)
Co zobaczymy na ekranie?
Na ekranie wyświetli się na liczba pi, rysunek wraz z punktami, ilość punktów znajdujących się na rysunku oraz błąd od liczby (czyli jak stosunek naszego PI do poprawnego PI, im dalej od wartości 1 tym bardziej niepoprawny mamy wynik)
#######
#PONIŻEJ ZNAJDUJĄ SIE DWA KODY (AUTOMATYCZNY I RECZNY) DO LOSOWANIA
#######
#KOD PIERWSZY
from machine import Pin,I2C
import ssd1306
import time
from math import sqrt
import random
ilosc=1000 #ile punktów chcemy wybrac, JEDYNIE W TEJ LINIJCE ZMIENIAMY WARTOSC, PRZY OGROMNYCH WARTOSCIACH (>2000) MOGA POJAWIAC SIE BLEDY Z PAMIECIA
i2c=I2C(scl=Pin(5),sda=Pin(4))
oled=ssd1306.SSD1306_I2C(128,64,i2c)
x=64
y=2
x_p=[]
y_p=[]
pin=machine.Pin(12,machine.Pin.IN, machine.Pin.PULL_UP)
def circle(x,y,r):
for i in range(128):
for j in range (64):
if sqrt((x-i-1)*(x-i-1)+(y-j-1)*(y-j-1)) >r-1 and sqrt((x-i-1)*(x-i-1)+(y-j-1)*(y-j-1)) <r+1:
if i>x and j>y:
oled.pixel(i,j,1)
def wkole(x,y,x_l,y_l):
if sqrt((x-x_l-1)*(x-x_l-1)+(y-y_l-1)*(y-y_l-1)) >60:
return 1
if sqrt((x-x_l-1)*(x-x_l-1)+(y-y_l-1)*(y-y_l-1)) <=60:
return 0
oled.rect(x, y, 60, 60, 1)
circle(64,2,60)
w=0
p=0
pi=0
dokladnosc=0
punkty=0
pi_s=str(pi)
dokladnosc_s=str(dokladnosc)
punkty_s=str(punkty)
oled.show()
for i in range(ilosc):
punkty+=1
losowy_x=random.getrandbits(8)%60+64
losowy_y=random.getrandbits(8)%60+2
x_p.append(losowy_x)
y_p.append(losowy_y)
if wkole(x,y,losowy_x,losowy_y)==1:
w+=1
if wkole(x,y,losowy_x,losowy_y)==0:
p+=1
if w>0 and p>0:
pi=(w/p)*4*3
dokladnosc=pi/3.14159
pi_s=str(pi)
dokladnosc_s=str(dokladnosc)
punkty_s=str(punkty)
oled.text(punkty_s,0,30,1)
oled.text(dokladnosc_s,0,50,1)
oled.text(pi_s,0,10,1)
oled.pixel(losowy_x,losowy_y,1)
oled.text('Blad:',0,40,1)
oled.text('Punkty',0,20,1)
oled.text("Pi:",0,0,1)
for i in range(punkty):
oled.pixel(x_p[i],y_p[i],1)
oled.show()
############################
#PONIŻEJ ZACZYNA SIE KOD SŁUŻĄCY LOSOWANIA PUNKTÓW GUZIKIEM PO KOLEJI
############################
#KOD DRUGI RECZNY
from machine import Pin,I2C
import ssd1306
import time
from math import sqrt
import random
i2c=I2C(scl=Pin(5),sda=Pin(4))
oled=ssd1306.SSD1306_I2C(128,64,i2c)
x=64
y=2
x_p=[]
y_p=[]
pin=machine.Pin(12,machine.Pin.IN, machine.Pin.PULL_UP)
def circlefull(x,y,r):
for i in range(128):
for j in range (64):
if sqrt((x-i-1)*(x-i-1)+(y-j-1)*(y-j-1)) >r-1 and sqrt((x-i-1)*(x-i-1)+(y-j-1)*(y-j-1)) <r+1:
oled.pixel(i,j,1)
def circle(x,y,r):
for i in range(128):
for j in range (64):
if sqrt((x-i-1)*(x-i-1)+(y-j-1)*(y-j-1)) >r-1 and sqrt((x-i-1)*(x-i-1)+(y-j-1)*(y-j-1)) <r+1:
if i>x and j>y:
oled.pixel(i,j,1)
def wkole(x,y,x_l,y_l):
if sqrt((x-x_l-1)*(x-x_l-1)+(y-y_l-1)*(y-y_l-1)) >60:
return 1
if sqrt((x-x_l-1)*(x-x_l-1)+(y-y_l-1)*(y-y_l-1)) <=60:
return 0
oled.rect(x, y, 60, 60, 1)
circle(64,2,60)
w=0
p=0
pi=0
dokladnosc=0
punkty=0
pi_s=str(pi)
dokladnosc_s=str(dokladnosc)
punkty_s=str(punkty)
oled.text("Pi:",0,0,1)
oled.text(pi_s,0,10,1)
oled.text('Points:',0,20,1)
oled.text(punkty_s,0,30,1)
oled.text('Blad:',0,40,1)
oled.text(dokladnosc_s,0,50,1)
oled.show()
while True:
print(pin.value())
if pin.value()==0:
punkty+=1
oled.fill(0)
losowy_x=random.getrandbits(8)%60+64
losowy_y=random.getrandbits(8)%60+2
x_p.append(losowy_x)
y_p.append(losowy_y)
if wkole(x,y,losowy_x,losowy_y)==1:
w+=1
print(w)
if wkole(x,y,losowy_x,losowy_y)==0:
p+=1
print(p)
for i in range(punkty):
circlefull(x_p[i],y_p[i],1)
oled.text('Blad:',0,40,1)
oled.text('Punkty',0,20,1)
oled.text("Pi:",0,0,1)
if w>0 and p>0:
pi=(w/p)*4*3
dokladnosc=pi/3.14159
oled.rect(x, y, 60, 60, 1)
circle(64,2,60)
pi_s=str(pi)
dokladnosc_s=str(dokladnosc)
punkty_s=str(punkty)
oled.text(punkty_s,0,30,1)
oled.text(dokladnosc_s,0,50,1)
oled.text(pi_s,0,10,1)
oled.show()