First let us make a really nice donat. We use Povray for that with Phong shading. These commands work only, if you have installed Povray properly.

>load povray; >povstart(angle=0,height=40°);

The following is a function to make donats.

>function povdonat (r1,r2,look="") := "torus {"+r1+","+r2+look+"}"; >writeln(povobject(povdonat(1,0.5),povlook(red,>phong),xrotate(90°))); >povend();

The torus is the image of a cylinder under the following mapping.

>function phi(x,t,z) &= [x*cos(t),x*sin(t),z]

[cos(t) x, sin(t) x, z]

For Euler, we need the x-, y-, and z-coordinates of this mapping.

>function phix(x,t,z) &= phi(x,t,z)[1]; >function phiy(x,t,z) &= phi(x,t,z)[2]; >function phiz(x,t,z) &= phi(x,t,z)[3];

Now we generate a cylinder with a circle centered at x=R, y=0, z=0 of height 2pi.

>s=linspace(0,2pi,40); t=s'; >R=1; r=0.5; >x=R+r*cos(s); y=t; z=r*sin(s); >pov3d(x,y,z,zoom=4);

The transformation phi maps this cylinder to the donat. Each point is mapped with phi.

>X=phix(x,y,z); Y=phiy(x,y,z); Z=phiz(x,y,z); >pov3d(X,Y,Z,zoom=3.8);

Here is the same image in Euler. We take -Z, since the default Euler shading is based on the correct side of the surface.

>plot3d(X,Y,-Z,>hue,zoom=3.6):

The following image is an Anagylph for red/cyan glasses showing the wire frame of torus with less details

>s=linspace(0,2pi,10); t=s'; ... R=1; r=0.5; ... X=phix(R+r*cos(s),t,r*sin(s)); ... Y=phiy(R+r*cos(s),t,r*sin(s)); ... Z=phiz(R+r*cos(s),t,r*sin(s)); ... plot3d(X,Y,Z,>wire,zoom=5,<frame,>anaglyph):

You need red/cyan glasses to appreciate the image.

The volume of a Donat can be computed with the Pappus' centroid theorem. It states for an area A in a plane rotated around one axis, which does not intersect the area and is in the same plane, that

where A is the area, and d is the length of the circle which the center of gravity of A travels along at one rotation.

For the donat with major radius 1 and minor radius 1/2, we rotate the following area A.

>t=linspace(0,2pi,100); ... plot2d(1+cos(t)/2,sin(t)/2,>filled,r=2); ... ctext("A",toscreen(1,0)); ... plot2d(-1+cos(t)/2,sin(t)/2,>filled,>add,style="O",r=2); ... insimg;

With major radius R and minor radius r, we get

Pappus' formula can be derived by elementary means, if we think of a small element dA of the area A at radius r. Rotating it yields a small tube of volume

Summing up, we see that we have to integrate r over A, which is equal to the mean value of r on A. Indeed

is the x-coordinate of the center of gravity of A.

>2*pi^2*1*0.5^2

4.93480220054

Using the transformation formula

is also easy. In fact the determinant is equal to x.

>&jacobian(phi(x,y,z),[x,y,z]), &det(%)|trigreduce

[ cos(y) - x sin(y) 0 ] [ ] [ sin(y) x cos(y) 0 ] [ ] [ 0 0 1 ] x

So we have to integrate x over the cylinder.

The surface of the Torus can be computed with the second theorem of Pappus.

where L is the length of path around A, and sc is the center of gravity of the path. For our Torus we get

>4*pi^2*1*0.5

19.7392088022

For a Torus (like for a sphere) changing the minor radius by some small value dr changes the Volume by Sdr. Thus the surface is the derivative of the Volume to r.

>&diff(2*pi^2*R*r^2,r)

2 4 pi r R

We like to cut the donat with planes y=c, and to study these cuts.

The following commands call Povray to produce a sliced version of our donat.

>povstart(angle=0°,height=40°,light=[0,-0.1,1],zoom=3.6);

First the donat.

>donat=povobject(povdonat(1,0.5),xrotate(90°));

Now we define a function, which produces the cylinders for the cut.

>function cut(y1,y2) := povcylinder([0,y1,0],[0,y2,0],2);

Now a vector for the cuts.

>a=linspace(-1.5,1.5,21);

The cutting cylinders are stored in a vector of strings.

>s=[]; for i=1 to (length(a)-1)/2; s=s|cut(a[2*i],a[2*i+1]); end;

Form the union of the cuts.

>cuts=povunion(s);

And write the donut minus the cuts to the file.

>writeln(povdifference(donat,cuts,povlook(red))); >povend();

We cannot do the same in Euler. But there is an implicit plot, which needs a formula for the surface of the donat. To derive this formula we compute the distance of a point to the center circle of the donat.

This must be equal to r.

>expr &= (sqrt(x^2+y^2)-R)^2+z^2-r^2

2 2 2 2 2 (sqrt(y + x ) - R) + z - r

>plot3d(expr,implicit=1,r=1.5,<frame,zoom=5,>user,title="Turn the image"):

For the following, you need your red/cyan glasses again.

>plot3d(expr,implicit=1,r=1.5,<frame,zoom=5,height=40°,n=20,>anaglyph):

For the implicit plots of the cuts, we need to substitute y=c and then transform with z=y into the x-y-plane.

>expr1 &= expr with y=c with z=y

2 2 2 2 2 (sqrt(x + c ) - R) + y - r

Here are some cuts for y=0.4,0.5,0.6,0.7.

>figure(2,2); ... for k=1:4; figure(k); plot2d(&expr1 with c=0.3+k*0.1,r=1.5,level=0); end; ... figure(0):