-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathscript.js
90 lines (68 loc) · 1.67 KB
/
script.js
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import { Vec2, getRandom, $ } from './utils.js'
const { PI } = Math
const W = 400
, H = 400
, R = (Math.min(W, H) - 200) / 2
, origin = new Vec2(W/2, H/2)
, FPS = 1000 // (0 < FPS <= 1000)
, TIME = 1000 / FPS
, WHITE = '#dfdfdf'
, RED = '#ef6f6f'
, BLUE = '#6f6fef'
function init(ctx) {
ctx.fillStyle = WHITE
ctx.strokeStyle = WHITE
ctx.font = '20px serif'
// x-axis
ctx.beginPath()
ctx.moveTo(0, H/2)
ctx.lineTo(W, H/2)
ctx.stroke()
// y-axis
ctx.beginPath()
ctx.moveTo(W/2, 0)
ctx.lineTo(W/2, H)
ctx.stroke()
// label
ctx.fillText('O', W/2 + 6, H/2 + 20)
ctx.fillText('x', W - 15, H/2 + 20)
ctx.fillText('y', W/2 + 6, 15)
// Rectangle
ctx.strokeRect(W * 1/4, H * 1/4, 2*R, 2*R)
// Circle
ctx.beginPath()
ctx.arc(...origin, R, 0, 2*PI)
ctx.closePath()
ctx.stroke()
const count = {
total: 0,
inCircle: 0,
}
setInterval(draw({ ctx, count }), TIME)
}
const draw = ({ ctx, count }) => () => {
const newPointOffs = new Vec2(
2 * getRandom(R) - R,
2 * getRandom(R) - R,
)
const isInCircle = (newPointOffs.x ** 2) + (newPointOffs.y ** 2) < (R ** 2)
ctx.fillStyle = isInCircle ? BLUE : RED
count.total += 1
count.inCircle += isInCircle
const newPoint = Vec2.add(origin, newPointOffs)
const pi = 4 * count.inCircle / count.total
ctx.beginPath()
ctx.arc(...newPoint, 0.75, 0, 2*PI)
ctx.closePath()
ctx.fill()
piValue.innerHTML = pi
pointsInCircle.innerHTML = count.inCircle
pointsInTotal.innerHTML = count.total
}
$(() => {
if (!canvas.getContext) return
const ctx = canvas.getContext('2d')
canvas.width = W
canvas.height = H
init(ctx)
})