mirror of
https://github.com/trekhleb/javascript-algorithms.git
synced 2025-07-08 02:14:56 +08:00
Refactor README.
This commit is contained in:
@ -1,9 +0,0 @@
|
||||
# Liu Hui's π Algorithm
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
## References
|
||||
|
||||
- [Liu Hui's π Algorithm on Wikipedia](https://en.wikipedia.org/wiki/Liu_Hui's_%CF%80_algorithm)
|
@ -1,16 +0,0 @@
|
||||
import pi from '../liu-hui-pi';
|
||||
|
||||
describe('Liu Hui\'s π algorithm', () => {
|
||||
it('Dodecagon π', () => {
|
||||
expect(pi(1)).toBe(3);
|
||||
});
|
||||
it('24-gon π', () => {
|
||||
expect(pi(2)).toBe(3.105828541230249);
|
||||
});
|
||||
it('6144-gon π', () => {
|
||||
expect(pi(10)).toBe(3.1415921059992717);
|
||||
});
|
||||
it('201326592-gon π', () => {
|
||||
expect(pi(25)).toBe(3.141592653589793);
|
||||
});
|
||||
});
|
92
src/algorithms/math/liu-hui/README.md
Normal file
92
src/algorithms/math/liu-hui/README.md
Normal file
@ -0,0 +1,92 @@
|
||||
# Liu Hui's π Algorithm
|
||||
|
||||
Liu Hui remarked in his commentary to The Nine Chapters on the Mathematical Art,
|
||||
that the ratio of the circumference of an inscribed hexagon to the diameter of
|
||||
the circle was `three`, hence `π` must be greater than three. He went on to provide
|
||||
a detailed step-by-step description of an iterative algorithm to calculate `π` to
|
||||
any required accuracy based on bisecting polygons; he calculated `π` to
|
||||
between `3.141024` and `3.142708` with a 96-gon; he suggested that `3.14` was
|
||||
a good enough approximation, and expressed `π` as `157/50`; he admitted that
|
||||
this number was a bit small. Later he invented an ingenious quick method to
|
||||
improve on it, and obtained `π ≈ 3.1416` with only a 96-gon, with an accuracy
|
||||
comparable to that from a 1536-gon. His most important contribution in this
|
||||
area was his simple iterative `π` algorithm.
|
||||
|
||||
## Area of a circle
|
||||
|
||||
Liu Hui argued:
|
||||
|
||||
> 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
|
||||
|
||||

|
||||
|
||||
Liu Hui's method of calculating the area of a circle.
|
||||
|
||||
Further, Liu Hui proved that the area of a circle is half of its circumference
|
||||
multiplied by its radius. He said:
|
||||
|
||||
> Between a polygon and a circle, there is excess radius. Multiply the excess
|
||||
radius by a side of the polygon. The resulting area exceeds the boundary of
|
||||
the circle
|
||||
|
||||
In the diagram `d = excess radius`. Multiplying `d` by one side results in
|
||||
oblong `ABCD` which exceeds the boundary of the circle. If a side of the polygon
|
||||
is small (i.e. there is a very large number of sides), then the excess radius
|
||||
will be small, hence excess area will be small.
|
||||
|
||||
> Multiply the side of a polygon by its radius, and the area doubles;
|
||||
hence multiply half the circumference by the radius to yield the area of circle.
|
||||
|
||||

|
||||
|
||||
The area within a circle is equal to the radius multiplied by half the
|
||||
circumference, or `A = r x C/2 = r x r x π`.
|
||||
|
||||
## Iterative algorithm
|
||||
|
||||
Liu Hui began with an inscribed hexagon. Let `M` be the length of one side `AB` of
|
||||
hexagon, `r` is the radius of circle.
|
||||
|
||||

|
||||
|
||||
Bisect `AB` with line `OPC`, `AC` becomes one side of dodecagon (12-gon), let
|
||||
its length be `m`. Let the length of `PC` be `j` and the length of `OP` be `G`.
|
||||
|
||||
`AOP`, `APC` are two right angle triangles. Liu Hui used
|
||||
the [Gou Gu](https://en.wikipedia.org/wiki/Pythagorean_theorem) (Pythagorean theorem)
|
||||
theorem repetitively:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
From here, there is now a technique to determine `m` from `M`, which gives the
|
||||
side length for a polygon with twice the number of edges. Starting with a
|
||||
hexagon, Liu Hui could determine the side length of a dodecagon using this
|
||||
formula. Then continue repetitively to determine the side length of a
|
||||
24-gon given the side length of a dodecagon. He could do this recursively as
|
||||
many times as necessary. Knowing how to determine the area of these polygons,
|
||||
Liu Hui could then approximate `π`.
|
||||
|
||||
## References
|
||||
|
||||
- [Wikipedia](https://en.wikipedia.org/wiki/Liu_Hui%27s_%CF%80_algorithm)
|
19
src/algorithms/math/liu-hui/__test__/liuHui.test.js
Normal file
19
src/algorithms/math/liu-hui/__test__/liuHui.test.js
Normal file
@ -0,0 +1,19 @@
|
||||
import liuHui from '../liuHui';
|
||||
|
||||
describe('liHui', () => {
|
||||
it('Dodecagon π', () => {
|
||||
expect(liuHui(1)).toBe(3);
|
||||
});
|
||||
|
||||
it('24-gon π', () => {
|
||||
expect(liuHui(2)).toBe(3.105828541230249);
|
||||
});
|
||||
|
||||
it('6144-gon π', () => {
|
||||
expect(liuHui(10)).toBe(3.1415921059992717);
|
||||
});
|
||||
|
||||
it('201326592-gon π', () => {
|
||||
expect(liuHui(25)).toBe(3.141592653589793);
|
||||
});
|
||||
});
|
@ -11,6 +11,7 @@ const getSideLength = (sideLength, count) => {
|
||||
// Liu Hui used the Gou Gu theorem repetitively.
|
||||
const g = Math.sqrt((r ** 2) - (m ** 2));
|
||||
const j = r - g;
|
||||
|
||||
return getSideLength(Math.sqrt((j ** 2) + (m ** 2)), count - 1);
|
||||
};
|
||||
|
||||
@ -27,27 +28,15 @@ const getSideCount = splitCount => c * (splitCount ? 2 ** splitCount : 1);
|
||||
* 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
|
||||
* @param {Number} splitCount repeat times
|
||||
* @return {Number}
|
||||
*
|
||||
* @param {number} splitCount repeat times
|
||||
* @return {number}
|
||||
*/
|
||||
const pi = (splitCount = 1) => {
|
||||
export default function liuHui(splitCount = 1) {
|
||||
const sideLength = getSideLength(r, splitCount - 1);
|
||||
const sideCount = getSideCount(splitCount - 1);
|
||||
const p = sideLength * sideCount;
|
||||
const area = (p / 2) * r;
|
||||
|
||||
return area / (r ** 2);
|
||||
};
|
||||
|
||||
// !test
|
||||
// for (let i = 1; i < 26; i += 1) {
|
||||
// const p = pi(i);
|
||||
// console.log(
|
||||
// 'split count: %f, side count: %f, π: %f, is Math.PI? %o',
|
||||
// i,
|
||||
// getSideCount(i),
|
||||
// p,
|
||||
// p === Math.PI,
|
||||
// );
|
||||
// }
|
||||
|
||||
export default pi;
|
||||
}
|
Reference in New Issue
Block a user