Public
Edited
Jun 11
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
/**
* Calculates the length of the circum radius of a regular polygon that best approximates a circle
* with an equal area. The degree of the polygon is determined by steps.
*
* @param {number} circleRadiusInMeters The radius of the target circle in meters.
* @param {number} steps The degree of the regular polygon.
* @returns {number} The length of the circum radius.
*/
calculateRegularPolygonCircumRadiusInMetersToBestApproximateEqualAreaCircle = (circleRadiusInMeters, steps = 12) => {
// METHOD: construct a polygon with the same area as the circle, this minimizes the overall distance from the circle to the perimeter of the polygon, and is a better estimate of the circle than say an inscribed polygon
const circleArea = Math.PI * circleRadiusInMeters * circleRadiusInMeters;
const phi = Math.PI / steps; // angle between apothem and radius
// 1. calculate the polygonArea:
// polygonArea = circumRadiusInMeters * sin(phi) * circumRadiusInMeters * cos(phi) * steps
// polygonArea = circumRadiusInMeters * circumRadiusInMeters * 1/2 * sin(2 * phi) * steps // via double angle identity
// 2. set circleArea equal to polygonArea:
// circleArea = polygonArea
// circleArea = circumRadiusInMeters * circumRadiusInMeters * 1/2 * sin(2 * phi) * steps
// 3. solve for the circumRadiusInMeters
// circleArea * 2.0 / (sin(2 * phi) * steps) = circumRadiusInMeters * circumRadiusInMeters
const circumRadiusInMeters = Math.sqrt((circleArea * 2.0) / (Math.sin(2.0 * phi) * steps));

return circumRadiusInMeters;
};
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
/**
* Calculates the number of sides of a regular polygon that best approximates a circle
* with an equal area, while not exceeding an allowable rim error.
*
* This function determines the optimal number of sides for a regular polygon that
* closely matches the area of a given circle while not exceeding an acceptable error
* tolerance in the polygon's circumradius.
*
* @param {number} circleRadiusInMeters The radius of the target circle in meters.
* @param {number} [maxAllowableLinearPolygonRimErrorInMeters=4.0] The maximum allowable error in meters for the polygon's circumradius when approximating the circle.
* @returns {number} The number of sides of the best-fit regular polygon, chosen from predefined values that ensure good meshing and clean angles.
*/
calculateNumberOfRegularPolygonSidesToBestApproximateEqualAreaCircle = (circleRadiusInMeters, maxAllowableLinearPolygonRimErrorInMeters = 4.0) => {
// step 1: assume highest allowable error
const circumRadiusInMeters = circleRadiusInMeters + maxAllowableLinearPolygonRimErrorInMeters;

// step 2: equate the area of the circle to the area of the polygon and solve for the number of sides
// Math.PI * circleRadiusInMeters * circleRadiusInMeters = circumRadiusInMeters * circumRadiusInMeters * 1/2 * sin(2 * Math.PI / numberOfSides) * numberOfSides
// 2 * Math.PI * circleRadiusInMeters * circleRadiusInMeters / circumRadiusInMeters * circumRadiusInMeters = sin(2 * Math.PI / numberOfSides) * numberOfSides
// let x = 2 * pi/numberOfSides
// sin(x)* 2pi/x = 2 * pi * circleRadiusInMeters * circleRadiusInMeters / circumRadiusInMeters * circumRadiusInMeters
// use taylor series to approximate sin(x) * x ≈ 1 - x*x/6
// 1 - x*x/6 ≈ (circleRadiusInMeters * circleRadiusInMeters) / (circumRadiusInMeters * circumRadiusInMeters)
// re-sub and solve for numberOfSides
const approximateNumberOfSides = 2 * Math.PI / Math.sqrt(6 * (1 - ((circleRadiusInMeters * circleRadiusInMeters) / (circumRadiusInMeters * circumRadiusInMeters))));

const numberOfSides = Math.max(4, Math.min(1440, Math.ceil(approximateNumberOfSides)));
return numberOfSides;
};
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more