-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuffonTest.py
43 lines (36 loc) · 2.14 KB
/
buffonTest.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import random
import math
# Buffon needle 시뮬레이션 함수
def BuffonTest(needleLen, lineInterval, planeWid, simulTimeList):
touchedTimes = 0 # 바늘이 몇 번 선에 닿았는지 저장하는 변수
tmpResultList = []
for i in range(simulTimeList[-1]): # simulTimes[-1]만큼 바늘을 떨어뜨린다
needlePos = random.uniform(0, planeWid) # 바늘이 처음 바닥에 닿는 위치
needleTheta = random.uniform(0, math.pi) # 바늘이 어느 방향으로 넘어지는지 각도(x축 1사분면을 기준으로)
# needleTheta가 90도를 넘느냐 아니냐를 기준으로 needle middle point의 위치를 어떻게 설정하는지
if needleTheta < math.pi / 2:
needlePos += abs(needleLen / 2 * math.cos(needleTheta))
else:
needlePos -= abs(needleLen / 2 * math.cos(needleTheta))
# 가장 가까운 선이 어디인지를 설정한다
closestLine = 0
if needlePos < 0:
closestLine = 0
elif needlePos % lineInterval < lineInterval / 2:
closestLine = needlePos // lineInterval * lineInterval
else:
if needlePos // lineInterval * lineInterval + lineInterval <= planeWid:
closestLine = needlePos // lineInterval * lineInterval + lineInterval
else:
closestLine = needlePos // lineInterval * lineInterval
# closestLine과 needle이 만나지 않았으면 다른 line과도 만나지 않을것이기 때문에 closestLine으로 needle의 crossing 여부를 판단
if (needleLen / 2) * abs(math.cos(needleTheta)) >= abs(closestLine - needlePos):
touchedTimes += 1
print("Success:", i, "번째 바늘은 선에 닿았습니다.")
else:
print("Failure:", i, "번째 바늘은 선에 닿지 못했습니다.")
# simulTimeList에 있는 순간마다 중간 결과를 기록한다
if (i + 1) in simulTimeList:
tmpResultList.append((2 * (i + 1) * needleLen) / (touchedTimes * lineInterval))
# 언제 기록했는지와 기록한 결과를 리턴한다
return simulTimeList, tmpResultList