Here's a deceptively challenging geometry puzzle for you!
Given a circle A
, and n
other circles B[n]
, find the total area contained within A
that is not within any circle of B
.
Your code should be as short as possible.
Input
Your input should contain the following information:
- A floating-point number to represent the radius of circle
A
. - A list of floating-point numbers to represent the radii of circles in
B
. - A list of the centers of circles in
B
. Your program may expect the centers in either polar or Cartesian coordinates. - Optionally, you may receive the number
n
of circles in B. This input is not required.
It shall be assumed that the center of circle A
is the origin, that is, the point (0, 0)
.
It is guaranteed that no two circles in B
are identical, but it is not guaranteed that: all circles of B
intersect A
, all centers of B
are outside A
, or no two circles in B
intersect each other. Ensure that your solution can handle various edge cases.
You may receive input in any order, and in the form of text input (through stdin or your language's equivalent), function parameters, or command-line arguments.
If you choose to receive text input, there should be one or two-character printable ASCII delimiters between pieces of input.
Output
Your program or function should output a single floating-point number representing the total area of A
not within any of the circles of B
. Your answers should be accurate to at least three significant figures for all test cases.
General code-golf rules apply.
Your solution should not rely on sampling points within the circles to determine an area.
Built-ins that automatically locate intersections of circles, find areas within intersections of circles, or solve this problem immediately are disallowed.
Test Cases
In each image, circle A
is outlined in blue, with circles B
outlined in green and filled black. The area that should be returned is filled red.
(Special thanks to Rainer P. for checking my solutions)
Test case 1:
A = {x: 0, y: 0, rad: 50}
B[0] = {x: 0, y: 0, rad: 100}
Result: 0.00
Test case 2:
A = {x: 0, y: 0, rad: 100.000000}
B[0] = {x: 100.000000, y: 0.000000, rad: 50.000000}
B[1] = {x: 30.901699, y: -95.105652, rad: 50.000000}
B[2] = {x: -80.901699, y: -58.778525, rad: 50.000000}
B[3] = {x: -80.901699, y: 58.778525, rad: 50.000000}
B[4] = {x: 30.901699, y: 95.105652, rad: 50.000000}
Result: 1.3878e+04
Test case 3:
A = {x: 0, y: 0, rad: 138}
B[0] = {x: 100, y: 0, rad: 100}
B[1] = {x: -50, y: -86, rad: 100}
B[2] = {x: -93, y: 135, rad: 50}
Result: 1.8969e+04
Test case 4:
A = {x: 0, y: 0, rad: 121.593585}
B[0] = {x: 81.000000, y: 107.000000, rad: 59.841457}
B[1] = {x: -152.000000, y: -147.000000, rad: 50.000000}
B[2] = {x: 43.000000, y: -127.000000, rad: 105.118980}
B[3] = {x: 0.000000, y: -72.000000, rad: 57.870545}
B[4] = {x: -97.000000, y: -81.000000, rad: 98.488578}
B[5] = {x: -72.000000, y: 116.000000, rad: 66.468037}
B[6] = {x: 2.000000, y: 51.000000, rad: 50.000000}
Result: 1.1264e+04
Test case 5:
A = {x: 0, y: 0, rad: 121.605921}
B[0] = {x: 0.000000, y: -293.000000, rad: 250.000000}
B[1] = {x: 0.000000, y: -56.000000, rad: 78.230429}
B[2] = {x: 0.000000, y: -102.000000, rad: 100.000000}
Result: 2.6742e+04
Suggested reading:
Fewell, M. P. "Area of Common Overlap of Three Circles." Oct. 2006. Web. http://dspace.dsto.defence.gov.au/dspace/bitstream/1947/4551/4/DSTO-TN-0722.PR.pdf.
B
contains another. Might be worth adding that. \$\endgroup\$1.8970e+04
. \$\endgroup\$B[0] - A intersection: 20653.659515
,B[1] - A intersection: 20757.824115
,B[1] - B[0] intersection: 1841.847766
,B[2] - A intersection: 1289.164541
, which yields18969.69009
as the answer. \$\endgroup\$