Archimedes and the circumference of a circle

Archimedes had a great idea: find bounds for the circumference of a circle using two regular polygons: one that “inscribes” the circumference, and the other which “circumscribes” the circle. 

We start with a circle of radius 1. Its circumference is 2π. We want to estimate this as Archimedes did (but he had to stop sooner than he would have liked, because he was drawing in sand!:).

The figure above show an inscribed square and a circumscribing square. The perimeter of the outside square is 8, while the perimeter of the “inside” square is 4(Sqrt[2])≈ 5.65685. These are both approximations to 2π. (With thanks to this Wolfram Demonstration project: Archimedes’ Approximation of Pi)

Inscribed and Circumscribing Polygons

The square is a regular polygon -- all sides are equal, all vertices are equivalent. It’s actually easy to find the “corners” of the inscribing polygon, using the trigonometric functions (which are also called the “circular functions”, and here we see why!). 

The coordinates of a corner for the square are given by the ordered pairs (cos(((2π)/n)k),sin(((2π)/n)k)), for n=4 and k from 0 to 3 (=n-1):

n=4;
pointsOnCircle=Table[{Cos[((2π)/n)k],Sin[((2π)/n)k]},{k,0,n-1}]
ListPlot[pointsOnCircle,PlotMarkers->{},AspectRatio->1,PlotRange->{{-1.1,1.1},{-1.1,1.1}}]

Do the same for other values of n, and see if it doesn’t work grand!

n=8;
pointsOnCircle=Table[{Cos[((2π)/n)k],Sin[((2π)/n)k]},{k,0,n-1}];
pointPlot=ListPlot[pointsOnCircle,PlotMarkers->{},AspectRatio->1,PlotRange->{{-1.1,1.1},{-1.1,1.1}}]

inscribedOnCircle=Table[{Cos[((2π)/n)k],Sin[((2π)/n)k]},{k,0,n}];
linePlot=ListLinePlot[inscribedOnCircle,AspectRatio->1]

Show[pointPlot,linePlot]

Now for the circumscribing polygons: this is an interesting problem in tangent lines: we want two lines tangent to the circle, running through adjacent points, to intersect: where they do we have a point on the circumscribing circle.

Let’s take the two adjacent points  (Subscript[P, 1])=(1,0) and  (Subscript[P, 2])=(cos(((2π)/n)),sin(((2π)/n))). The slope of the line joining the center of the circle to (Subscript[P, 2]) is m=tan(((2π)/n)). So the slope of the line tangent to the circle is ((-1)/m), and away we go: we have a point and a slope. And we want that line to intersect the tangent line at (Subscript[P, 1]) (which is just the vertical line x=1).

So the first point on the circumscribing circle is 
	(1, ((-1)/m)(1-cos(((2π)/n)))+sin(((2π)/n))).

m=Tan[2Pi/n]
distanceOut=Norm[{1.0,-(1-Cos[2Pi/n])/m+Sin[2Pi/n]}]

circumscribingCircle=Table[distanceOut{Cos[((2π)/n)k+(π/n)],Sin[((2π)/n)k+(π/n)]},{k,0,n}];
linesOutPlot=ListLinePlot[circumscribingCircle,AspectRatio->1,PlotStyle->Orange]

Show[pointPlot,linePlot,linesOutPlot,Graphics[Circle[]]]

Sequences Approximating Circumference

Now let’s talk about sequences! We’re constructing sequences of objects, inscribing and circumscribing polygons. That sounds weird, doesn’t it? 

And both of these sequences converge on the circle! So they’re convergent sequences. 

But we want to talk about sequences of numbers. We have two sequences of perimeters, which should both be converging on the circumference of the circle (and bounding that circumference -- one an underestimate and the other an overestimate).

The distance between adjacent inscribing points is the Euclidean distance between  (Subscript[P, 1])=(1,0) and  (Subscript[P, 2])=(cos(((2π)/n)),sin(((2π)/n))):

inscribingDistance[n_]:=N[Norm[{1-Cos[((2π)/n)],Sin[((2π)/n)]}]]
inscribingDistance[4]
inscribingCircumference[n_]:=n*inscribingDistance[n]
inscribingCircumference[4]
N[%]

The distance between adjacent circumscribing points is the Euclidean distance between two points on the line x=1, with known “distancesOut” and sine values: so the calculation is a little different:

circumscribingDistance[n_]:=
Module[{m=Tan[2Pi/n],distanceOut},
distanceOut=Norm[{1.0,-(1-Cos[2Pi/n])/m+Sin[2Pi/n]}];
distanceOut * 2*Abs[Sin[(π/n)]]
]
circumscribingCircumference[n_]:=n*circumscribingDistance[n]
circumscribingCircumference[3] (* triangles *)
circumscribingCircumference[4] (* squares *)
circumscribingCircumference[5] (* pentagons *)

Let’s see how these sequences behave over the range of possible values of n (note: n⩾3):

DiscretePlot[{inscribingCircumference[n],2Pi,circumscribingCircumference[n]},{n,3,10},PlotRange->All]

DiscretePlot[{inscribingCircumference[n],2Pi,circumscribingCircumference[n]},{n,3,100}]

Archimedes’s Dream

Now let’s put all this together, creating one function which I have called “ArchimedesWouldBeSoHappy”, because, in fact, ArchimedesWouldBeSoHappy! :)

ArchimedesWouldBeSoHappy[n_]:=
Module[
{pointsOnCircle=Table[{Cos[((2π)/n)k],Sin[((2π)/n)k]},{k,0,n-1}],
inscribedOnCircle=Table[{Cos[((2π)/n)k],Sin[((2π)/n)k]},{k,0,n}],
m=Tan[2Pi/n],
insideEstimate=inscribingCircumference[n],
outsideEstimate=circumscribingCircumference[n],
distanceOut,circumscribingCircle,pointPlot,linePlot,linesOutPlot
},
distanceOut=Norm[{1.0,-(1-Cos[2Pi/n])/m+Sin[2Pi/n]}];
circumscribingCircle=Table[distanceOut{Cos[((2π)/n)k+(π/n)],Sin[((2π)/n)k+(π/n)]},{k,0,n}];
pointPlot=ListPlot[pointsOnCircle,PlotMarkers->{},AspectRatio->1,PlotRange->{{-1.1,1.1},{-1.1,1.1}}];
linePlot=ListLinePlot[inscribedOnCircle];
linesOutPlot=ListLinePlot[circumscribingCircle,PlotStyle->Orange];
Show[
pointPlot,linePlot,linesOutPlot,Graphics[Circle[]],
PlotLabel->{insideEstimate,N[2Pi],outsideEstimate}]
]

ArchimedesWouldBeSoHappy[7]

ArchimedesWouldBeSoHappy[1000]

Manipulate[
ArchimedesWouldBeSoHappy[n],
{n,3,1000,1}
]