Let there be two circular beer coasters of equal area. The two coasters are moved on top of each other such that the area of the overlapping region is half the area of any one of the coasters, as illustrated below: (Try hovering)
Give an algorithm, with the usual desirable properties and expressed as pseudocode, for solving the problem. The solution will include finding the angle a, as illustrated in the following figure.

// Finds the angle between the two equal sides of an isoceles triangle // formed within a circular segment that has an area equal to 1/4th of the total circle's area // Input: Circle's radius (optional*) // Output: the height of the triangle and the angle between the two equal sides r <- user input radius RHS <- 0 LHS <- (pi * r^2)/4 step <- 1.0 previousActionWasAdd <- true while RHS != LHS if LHS > RHS if (previousActionWasAdd) height <- height + step else step <- step / 2 height <- height + step previousActionWasAdd <- true if LHS < RHS if (previousActionWasAdd) step <- step / 2 height <- height - step previousActionWasAdd <- false else height <- height - step // Calulcate the RHS based on the formula of a circular segment RHS = ( r^2*arccos((r-height)/r) ) - ( (r-height)*sqrt(2*r*height - height^2) ); // Now that we found the height, let's find the chord halfChord <- sqrt( height * (2*r - height)); // Find r-h distanceToCenter <- r - height; // Find the angle times two angle <- 2 * arctan(halfChord / distanceToCenter);
function calculateAngle( radius ) {
$('#demoOutput').html(''); // clear from last run
// 1/4 of the area, rounded to 8 decimal places
var LHS = (Math.PI * Math.pow(radius, 2)) / 4
LHS = round(LHS, 8);
var RHS = 0.0;
var height = 0.0;
var step = 1.0;
var previousActionWasAdd = true;
var iterator = 0;
$('#demoOutput').append("Brute forcing the height value");
// Brute force to find what value of h makes the LHS == RHS
while ( RHS != LHS ){
if (iterator++ > 100) // Shouldn't loop this long
break;
// If h is too small
if (LHS > RHS) {
// If we added previously don't change the step
if (previousActionWasAdd)
height += step;
// Otherwise, reduce the step by half and add it to h
else {
step /= 2;
height += step;
previousActionWasAdd = true;
}
// If h is too big
} else if ( LHS < RHS ) {
// If we added previous, reduce the step by half and subtract
if (previousActionWasAdd){
step /= 2;
height -= step;
previousActionWasAdd = false;
// Otherwise, subtract again
} else
height -= step;
}
// Calulcate the RHS based on the formula of a circular segment
RHS = Math.pow(radius,2) * Math.acos( (radius - height) / radius) -
( radius - height) * Math.sqrt(2*radius*height
- Math.pow(height, 2));
// Round it to 8 decimal places
RHS = round(RHS, 8);
// Log our work
$('#demoOutput').append('Iteration #'+iterator +
' - Height = ' +
height + 'LHS = ' +
LHS+ 'RHS = ' +
RHS + '');
}
// Now that we found the h, let's find the chord
var halfChord = Math.sqrt( height * (2*radius - height));
$('#demoOutput').append("Half the Cord is: " + halfChord);
// Find r-h
var distanceToCenter = radius - height;
$('#demoOutput').append('radius - segmentHeight is: ' + distanceToCenter);
// Find the angle times two
var angle = 2 * Math.atan(halfChord / distanceToCenter);
$('#demoOutput').append("Answer is: " +
angle*(180/Math.PI) + " °, or " +
angle + " radians.");
}
// This functions rounds a num to any given dec places
function round(num, dec) {
return Math.round(num*Math.pow(10,dec))/Math.pow(10,dec);
}
All the code for this can be found on my github.
