-
Notifications
You must be signed in to change notification settings - Fork 8
/
PI.js
62 lines (51 loc) · 1.7 KB
/
PI.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
/*
* @Author: Liuxin 微信: L2315496341 欢迎交流
* @Date: 2019-01-11 14:37:41
* @Last Modified by: Liuxin
* @Last Modified time: 2019-01-11 14:37:41
*/
// PI = 4 * cirleArea / squareArea
// 用蒙特卡罗算法的思想就是随机往正方形里打点,圆内的点个数之和近似于圆的面积,打点总数近似于正方形的面积
// PI = 4 * 圆内的点 / 打点总数
const _inCircle = Symbol('inCircle')
const _calcPI = Symbol('calcPI')
const _addPoint = Symbol('addPoint')
class PI {
constructor(N = 1000000000, consoleInterval = 100000000) {
this.N = N // 预计打点次数
this.r = 100 // 半径
this.cirleArea = 0 // 圆内点个数
this.squareArea = 0 // 已打点个数
this.consoleInterval = consoleInterval // 每打多少个点打印一次PI
}
// 判断是否落在圆内 包含圆边上的点
[_inCircle](x, y) {
return Math.pow(this.r - x, 2) + Math.pow(this.r - y, 2) <= Math.pow(this.r, 2)
}
// 计算目前的PI值
[_calcPI]() {
// SquareArea不包含4条边上的点 所以加上4条边的长度
return 4 * this.cirleArea / (this.squareArea + 8 * this.r)
}
// 随机打点
[_addPoint]() {
// 正方形内随机打点的坐标 结果没有包含四天边上的点
let x = Math.random() * 2 * this.r
let y = Math.random() * 2 * this.r
this.squareArea++
if (this[_inCircle](x, y)) {
this.cirleArea++
}
}
// 获取并打印PI
getPI() {
for (let i = 1; i < this.N + 1; i++) {
this[_addPoint]()
if (i % this.consoleInterval === 0) {
console.log(this.cirleArea, this.squareArea, 'PI', this[_calcPI]())
}
}
}
}
// 实例化PI 获取PI值
new PI().getPI()