spoiler - behold a square
Full spoiler is here:
totalPointspointsInsideSCALESHAPE_OFFSET_XSHAPE_OFFSET_YthetasmallRadiuslargeRadiussmallRadiusScaledlargeRadiusScaledsampledAreaunitAreaisInsideShapeangleinWedgeinSmallCircledrawShape
let totalPoints = 0;
let pointsInside = 0;
const SCALE = 100;
const SHAPE_OFFSET_X = -0.2;
const SHAPE_OFFSET_Y = -0.1;
let theta, smallRadius, largeRadius, smallRadiusScaled, largeRadiusScaled;
function setup() {
theta = 1 + PI - sqrt(PI * PI + 1);
smallRadius = 1 / theta - 1;
largeRadius = smallRadius + 1;
smallRadiusScaled = smallRadius * SCALE;
largeRadiusScaled = largeRadius * SCALE;
createCanvas(600, 600);
background(220);
translate(width / 2, height / 2);
drawShape();
translate(-width / 2, -height / 2);
}
function draw() {
for (let i = 0; i < 100; i++) {
let x = random(
width / 2 - largeRadiusScaled,
width / 2 + largeRadiusScaled
);
let y = random(
height / 2 - largeRadiusScaled,
height / 2 + largeRadiusScaled
);
if (isInsideShape(x, y)) {
stroke(0, 0, 0, 100);
pointsInside++;
} else {
stroke(255, 255, 255, 100);
}
point(x, y);
totalPoints++;
}
let sampledArea =
(pointsInside / totalPoints) * (4 * largeRadiusScaled * largeRadiusScaled);
let unitArea = sampledArea / (SCALE * SCALE);
fill(255);
noStroke();
rect(10, height - 70, 250, 60);
fill(0);
text(`Total points: ${totalPoints}`, 20, height - 50);
text(`Estimated area (unit scale): ${unitArea.toFixed(6)}`, 20, height - 30);
}
function isInsideShape(x, y) {
let px = (x - width / 2) / SCALE - SHAPE_OFFSET_X;
let py = (y - height / 2) / SCALE - SHAPE_OFFSET_Y;
let r = sqrt(px * px + py * py);
let angle = atan2(py, px);
if (angle < 0) angle += TWO_PI;
let inWedge = angle <= theta && r <= largeRadius;
let inSmallCircle = px * px + py * py <= smallRadius * smallRadius;
return inWedge || inSmallCircle;
}
function drawShape() {
translate(SHAPE_OFFSET_X * SCALE, SHAPE_OFFSET_Y * SCALE);
noFill();
noStroke();
circle(0, 0, smallRadiusScaled * 2);
arc(0, 0, largeRadiusScaled * 2, largeRadiusScaled * 2, 0, theta);
line(0, 0, largeRadiusScaled * cos(0), largeRadiusScaled * sin(0));
line(0, 0, largeRadiusScaled * cos(theta), largeRadiusScaled * sin(theta));
}