forked from trekhleb/javascript-algorithms
-
Notifications
You must be signed in to change notification settings - Fork 8
/
liuHui.js
54 lines (46 loc) · 1.64 KB
/
liuHui.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
/*
* Let circleRadius is the radius of circle.
* circleRadius is also the side length of the inscribed hexagon
*/
const circleRadius = 1;
/**
* @param {number} sideLength
* @param {number} splitCounter
* @return {number}
*/
function getNGonSideLength(sideLength, splitCounter) {
if (splitCounter <= 0) {
return sideLength;
}
const halfSide = sideLength / 2;
// Liu Hui used the Gou Gu (Pythagorean theorem) theorem repetitively.
const perpendicular = Math.sqrt((circleRadius ** 2) - (halfSide ** 2));
const excessRadius = circleRadius - perpendicular;
const splitSideLength = Math.sqrt((excessRadius ** 2) + (halfSide ** 2));
return getNGonSideLength(splitSideLength, splitCounter - 1);
}
/**
* @param {number} splitCount
* @return {number}
*/
function getNGonSideCount(splitCount) {
// Liu Hui began with an inscribed hexagon (6-gon).
const hexagonSidesCount = 6;
// On every split iteration we make N-gons: 6-gon, 12-gon, 24-gon, 48-gon and so on.
return hexagonSidesCount * (splitCount ? 2 ** splitCount : 1);
}
/**
* Calculate the π value using Liu Hui's π algorithm
*
* @param {number} splitCount - number of times we're going to split 6-gon.
* On each split we will receive 12-gon, 24-gon and so on.
* @return {number}
*/
export default function liuHui(splitCount = 1) {
const nGonSideLength = getNGonSideLength(circleRadius, splitCount - 1);
const nGonSideCount = getNGonSideCount(splitCount - 1);
const nGonPerimeter = nGonSideLength * nGonSideCount;
const approximateCircleArea = (nGonPerimeter / 2) * circleRadius;
// Return approximate value of pi.
return approximateCircleArea / (circleRadius ** 2);
}