Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c536aa2

Browse files
committed
Refactor liuHui.
1 parent 1e2fdc6 commit c536aa2

File tree

2 files changed

+46
-34
lines changed

2 files changed

+46
-34
lines changed
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
import liuHui from '../liuHui';
22

3-
describe('liHui', () => {
4-
it('Dodecagon π', () => {
3+
describe('liuHui', () => {
4+
it('should calculate π based on 12-gon', () => {
55
expect(liuHui(1)).toBe(3);
66
});
77

8-
it('24-gon π', () => {
8+
it('should calculate π based on 24-gon', () => {
99
expect(liuHui(2)).toBe(3.105828541230249);
1010
});
1111

12-
it('6144-gon π', () => {
12+
it('should calculate π based on 6144-gon', () => {
1313
expect(liuHui(10)).toBe(3.1415921059992717);
1414
});
1515

16-
it('201326592-gon π', () => {
16+
it('should calculate π based on 201326592-gon', () => {
1717
expect(liuHui(25)).toBe(3.141592653589793);
1818
});
1919
});

‎src/algorithms/math/liu-hui/liuHui.js

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,54 @@
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;
1+
/*
2+
* Let circleRadius is the radius of circle.
3+
* circleRadius is also the side length of the inscribed hexagon
4+
*/
5+
const circleRadius = 1;
6+
7+
/**
8+
* @param {number} sideLength
9+
* @param {number} splitCounter
10+
* @return {number}
11+
*/
12+
function getNGonSideLength(sideLength, splitCounter) {
13+
if (splitCounter <= 0) {
14+
return sideLength;
15+
}
16+
17+
const halfSide = sideLength / 2;
618

7-
const getSideLength = (sideLength, count) => {
8-
if (count <= 0) return sideLength;
9-
const m = sideLength / 2;
19+
// Liu Hui used the Gou Gu (Pythagorean theorem) theorem repetitively.
20+
const perpendicular = Math.sqrt((circleRadius ** 2) - (halfSide ** 2));
21+
const excessRadius = circleRadius - perpendicular;
22+
const splitSideLength = Math.sqrt((excessRadius ** 2) + (halfSide ** 2));
1023

11-
// Liu Hui used the Gou Gu theorem repetitively.
12-
const g = Math.sqrt((r ** 2) - (m ** 2));
13-
const j = r - g;
24+
return getNGonSideLength(splitSideLength, splitCounter - 1);
25+
}
1426

15-
return getSideLength(Math.sqrt((j ** 2) + (m ** 2)), count - 1);
16-
};
27+
/**
28+
* @param {number} splitCount
29+
* @return {number}
30+
*/
31+
function getNGonSideCount(splitCount) {
32+
// Liu Hui began with an inscribed hexagon (6-gon).
33+
const hexagonSidesCount = 6;
1734

18-
const getSideCount = splitCount => c * (splitCount ? 2 ** splitCount : 1);
35+
// On every split iteration we make N-gons: 6-gon, 12-gon, 24-gon, 48-gon and so on.
36+
return hexagonSidesCount * (splitCount ? 2 ** splitCount : 1);
37+
}
1938

2039
/**
2140
* Calculate the π value using Liu Hui's π algorithm
2241
*
23-
* Liu Hui argued:
24-
* Multiply one side of a hexagon by the radius (of its circumcircle),
25-
* then multiply this by three, to yield the area of a dodecagon; if we
26-
* cut a hexagon into a dodecagon, multiply its side by its radius, then
27-
* again multiply by six, we get the area of a 24-gon; the finer we cut,
28-
* the smaller the loss with respect to the area of circle, thus with
29-
* further cut after cut, the area of the resulting polygon will coincide
30-
* and become one with the circle; there will be no loss
31-
*
32-
* @param {number} splitCount repeat times
42+
* @param {number} splitCount - number of times we're going to split 6-gon.
43+
* On each split we will receive 12-gon, 24-gon and so on.
3344
* @return {number}
3445
*/
3546
export default function liuHui(splitCount = 1) {
36-
const sideLength = getSideLength(r, splitCount - 1);
37-
const sideCount = getSideCount(splitCount - 1);
38-
const p = sideLength * sideCount;
39-
const area = (p / 2) * r;
47+
const nGonSideLength = getNGonSideLength(circleRadius, splitCount - 1);
48+
const nGonSideCount = getNGonSideCount(splitCount - 1);
49+
const nGonPerimeter = nGonSideLength * nGonSideCount;
50+
const approximateCircleArea = (nGonPerimeter / 2) * circleRadius;
4051

41-
return area / (r ** 2);
52+
// Return approximate value of pi.
53+
return approximateCircleArea / (circleRadius ** 2);
4254
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /