mirror of
https://github.com/trekhleb/javascript-algorithms.git
synced 2025-12-08 19:06:00 +00:00
55 lines
1.6 KiB
JavaScript
55 lines
1.6 KiB
JavaScript
/*
|
|
* 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);
|
|
}
|