Skip to content

Commit 7dc9b80

Browse files
mantou132trekhleb
authored andcommitted
feat: Add Liu Hui's π algorithm (trekhleb#61)
1 parent bc17e4e commit 7dc9b80

File tree

4 files changed

+79
-0
lines changed

4 files changed

+79
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
node_modules
22
.idea
33
coverage
4+
.vscode
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Liu Hui's π Algorithm
2+
3+
Multiply one side of a hexagon by the radius (of its circumcircle), then multiply this by three, to yield the area of a dodecagon; if we cut a hexagon into a dodecagon, multiply its side by its radius, then again multiply by six, we get the area of a 24-gon; the finer we cut, the smaller the loss with respect to the area of circle, thus with further cut after cut, the area of the resulting polygon will coincide and become one with the circle; there will be no loss
4+
5+
6+
7+
## References
8+
9+
- [Liu Hui's π Algorithm on Wikipedia](https://en.wikipedia.org/wiki/Liu_Hui's_%CF%80_algorithm)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import pi from '../liu-hui-pi';
2+
3+
describe('Liu Hui\'s π algorithm', () => {
4+
it('Dodecagon π', () => {
5+
expect(pi(1)).toBe(3);
6+
});
7+
it('24-gon π', () => {
8+
expect(pi(2)).toBe(3.105828541230249);
9+
});
10+
it('6144-gon π', () => {
11+
expect(pi(10)).toBe(3.1415921059992717);
12+
});
13+
it('201326592-gon π', () => {
14+
expect(pi(25)).toBe(3.141592653589793);
15+
});
16+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Liu Hui began with an inscribed hexagon.
2+
// Let r is the radius of circle.
3+
// r is also the side length of the inscribed hexagon
4+
const c = 6;
5+
const r = 0.5;
6+
7+
const getSideLength = (sideLength, count) => {
8+
if (count <= 0) return sideLength;
9+
const m = sideLength / 2;
10+
11+
// Liu Hui used the Gou Gu theorem repetitively.
12+
const g = Math.sqrt((r ** 2) - (m ** 2));
13+
const j = r - g;
14+
return getSideLength(Math.sqrt((j ** 2) + (m ** 2)), count - 1);
15+
};
16+
17+
const getSideCount = splitCount => c * (splitCount ? 2 ** splitCount : 1);
18+
19+
/**
20+
* Calculate the π value using Liu Hui's π algorithm
21+
*
22+
* Liu Hui argued:
23+
* Multiply one side of a hexagon by the radius (of its circumcircle),
24+
* then multiply this by three, to yield the area of a dodecagon; if we
25+
* cut a hexagon into a dodecagon, multiply its side by its radius, then
26+
* again multiply by six, we get the area of a 24-gon; the finer we cut,
27+
* the smaller the loss with respect to the area of circle, thus with
28+
* further cut after cut, the area of the resulting polygon will coincide
29+
* and become one with the circle; there will be no loss
30+
* @param {Number} splitCount repeat times
31+
* @return {Number}
32+
*/
33+
const pi = (splitCount = 1) => {
34+
const sideLength = getSideLength(r, splitCount - 1);
35+
const sideCount = getSideCount(splitCount - 1);
36+
const p = sideLength * sideCount;
37+
const area = (p / 2) * r;
38+
return area / (r ** 2);
39+
};
40+
41+
// !test
42+
// for (let i = 1; i < 26; i += 1) {
43+
// const p = pi(i);
44+
// console.log(
45+
// 'split count: %f, side count: %f, π: %f, is Math.PI? %o',
46+
// i,
47+
// getSideCount(i),
48+
// p,
49+
// p === Math.PI,
50+
// );
51+
// }
52+
53+
export default pi;

0 commit comments

Comments
 (0)