Application Center - Maplesoft

App Preview:

Classic Curves - the Nephroid

You can switch back to the summary page by clicking here.

Learn about Maple
Download Application


 

Image 

Classic Curves - the Nephroid 

David A Harrington
Chemistry Department, University of Victoria
Canada
dharr@uvic.ca, http://web.uvic.ca/~dharr 

Introduction 

The nephroid is a classic curve, named after its kidney shape by Procter in 1878. In this worksheet, I show how to generate it via several different construction methods. 

 

Most of the geometric construction commands are from the geometry package, see ?geometry. (An alternative would have been to use commands from the plottools package.) The common ones we use are reviewed here. For most of the construction commands the first argument is the name of the object being constructed. 

  point(p1,x,y)                          construct point p1 with coordinates (x,y) 

  circle(c1,top,bottom)                  construct circle c1 with diameter between points top and bottom 

  circle(c1,[centre,radius])             construct circle c1 with center point "centre" and radius of length "radius" 

  segment(s1,p1,p2)                                construct line segment s1 between points p1 and p2
  line(s1,[p1,p2])                                  construct line s1 of infinite extent through points p1 and p2  

  rotation(r2,q1,theta,clockwise,centre) make object r2 by rotating object q1 clockwise by angle theta around point "centre" 

  coordinates(p1)                        returns coordinates [x,y] of point p1
  DefinedAs(s1)                                                    returns [p1,p2], the names of the two points at the end of line segment s1 

As the package requires all objects to be named, and so within loops with index i the concatenation operator "||" is used to generate new names, e.g., point(p||i,...) generates points p1, p2, p3,... as the index i goes 1,2,3,... 

Initialization 

After running this initialization section, any of the sections below may be run independently of each other. 

> restart;with(geometry):with(plots):
 

The nephroid has one parameter, Typesetting:-mrow(Typesetting:-mi(, that determines its size. The base circle in some of the constructions below has radius Typesetting:-mrow(Typesetting:-mn(, in others Typesetting:-mrow(Typesetting:-mn(. Here we choose a value for the purposes of the plots. 

> a:=1;
 

1 (2.1)
 

The draw command sometimes cuts off labels, so to force a larger viewing area, a white square border with sides of length s is defined 

> border:=proc(s);
         square(sq,[point(sq1,-s/2,s/2),point(sq2,s/2,s/2),
                    point(sq3,s/2,-s/2),point(sq4,-s/2,-s/2)]);
         sq(colour=white,printtext=false);
       end proc:
 

>
 

 

Parametric plot 

The nephroid can be plotted simply in parametric form, Typesetting:-mrow(Typesetting:-mi(. 

> plot([3*a*cos(t)+a*cos(3*t),3*a*sin(t)+a*sin(3*t),t=0..2*Pi],scaling=constrained,axes=none);
 

Plot_2d
 

>
 

Envelope of circles around a base circle 

The first construction is based around a circle, the base circle, centered at the origin O with radius Typesetting:-mrow(Typesetting:-mn(. This is easiest to define via its vertical diameter, which is terminated in points named "top" and "bottom". 

> point(top,0,2*a):point(bottom,0,-2*a):
circle(basecircle,[top,bottom],centername=O):
segment(vertical,top,bottom):
draw([border(5*a),basecircle(colour=blue),vertical(colour=blue)],printtext=true,axes=none);
 

Plot_2d
 

We now construct a circle c1 with its centre on the base circle. Choose an angle Typesetting:-mrow(Typesetting:-mi( clockwise around the base circle from 12 o'clock (the yellow region). The point p1 at the end of the radius at this angle has coordinates Typesetting:-mrow(Typesetting:-mi( and is the centre of the circle c1. The circle also touches the vertical line at p2, so that the horizontal distance between p1 and the vertical is Typesetting:-mrow(Typesetting:-mi(. So this circle is defined with centre at p1 and radius Typesetting:-mrow(Typesetting:-mi( Try changing theta in the line below to see other possible circles. 

> theta:=1.2;
point(p1,2*a*sin(theta),2*a*cos(theta)):
circle(c1,[p1,abs(2*a*sin(theta))]):
segment(s1,p1,point(p2,0,2*a*cos(theta))):
display(plottools[pieslice]([0,0],2*a,Pi/2..Pi/2-theta,colour=yellow),
       draw([border(5*a),basecircle(colour=blue),vertical(colour=blue),p1,c1,s1],
            printtext=true),
      axes=none);
 

 

1.2
Plot_2d
 

Now we do it many times, for many circles around the base circle. Note that negative and zero radii generate an error, so we take the absolute value of the x coordinate of p1 when defining the circle, and avoid circles at Typesetting:-mrow(Typesetting:-mi( or Typesetting:-mrow(Typesetting:-mi( The envelope of these circles is the nephroid. 

> n:=30: #number of circles to draw
circles:=NULL:
for i to n-1 do
  theta:=i*2*Pi/n;
  if theta=Pi then next end if;
  point(p||i,2*a*sin(theta),2*a*cos(theta));
  circle(c||i,[p||i,abs(2*a*sin(theta))]);
  circles:=circles,c||i;  # collect the circles in a sequence
end do:
draw([basecircle(colour=blue),vertical(colour=blue),circles],axes=none);
 

Plot_2d
 

>
 

Epicycloid 

The nephroid is also an epicycloid, i.e., the locus of a point on the circumference of a circle that rolls around another circle. If the radius of the base circle is Typesetting:-mrow(Typesetting:-mn(, then the locus of a point on a circle of radius Typesetting:-mrow(Typesetting:-mi( rolling around the base circle is a nephroid. We start with the circle at the top: 

> point(top,0,2*a):point(bottom,0,-2*a):
circle(basecircle,[top,bottom],centername=O):
point(centre,0,3*a): #centre of rolling circle
circle(c1,[centre,a]): #rolling circle
point(b1,0,2*a):   #bottom of circle
segment(s1,centre,b1): #vert. down radius of circle
draw([basecircle(colour=blue),b1,s1,c1],printtext=true,axes=none);
 

Plot_2d
 

At an angle theta around the base circle, we have traversed a distance Typesetting:-mrow(Typesetting:-mi( around the circumference of the base circle (yellow region). So the rolling circle has rotated by the same circumference, or by an angle Typesetting:-mrow(Typesetting:-mi( (green region). This angle is added to Typesetting:-mrow(Typesetting:-mi( to give the angle from the downward vertical of the radius that ends at b2 . Point b2 is on the nephroid. Try changing theta to see the rolling circle at different points around its travel. 

> theta:=0.2;
point(centre,3*a*sin(theta),3*a*cos(theta)): #centre of rolling circle
circle(c2,[centre,a]): #rolling circle
point(bb2,3*a*sin(theta),3*a*cos(theta)-a): #bottom of rolling circle
segment(ss2,centre,bb2): #vert. down radius of circle
phi:=theta*2: #angle to rotate above segment by
rotation(sss2,ss2,phi+theta,clockwise,centre): #rotate it
point(b2,coordinates(DefinedAs(sss2)[2])): #point at end of rotated segment
segment(s2,centre,b2): #redefine segment to get nice endpoint names
display(plottools[pieslice]([0,0],2*a,Pi/2..Pi/2-theta,colour=yellow),
       plottools[pieslice](coordinates(centre),a,3*Pi/2..3*Pi/2-theta,colour=yellow),
       plottools[pieslice](coordinates(centre),a,3*Pi/2-theta-phi..3*Pi/2-theta,
                 colour=green),
       draw([basecircle(colour=blue),b2,s2,c2],printtext=true),
       axes=none);
 

 

.2
Plot_2d
 

Now put this in a loop and animate the sequence of drawings formed. Accumulate the points into a curve. To see the animation, click on the plot and choose play on the toolbar. 

> n:=52: #number of pictures to draw
pics:=NULL:pts:=[0,2*a]:
for i from 0 to n do
  theta:=i*2*Pi/n;
  point(centre,3*a*sin(theta),3*a*cos(theta)):
  circle(c||i,[centre,a]):
  point(bb||i,3*a*sin(theta),3*a*cos(theta)-a):
  segment(ss||i,centre,bb||i):
  phi:=theta*2:
  rotation(s||i,ss||i,phi+theta,clockwise,centre):
  b||i:=DefinedAs(s||i)[2]:
  pts:=pts,coordinates(b||i):
  pics:=pics,display(pointplot([pts],style=line),
                     draw([border(5*a),basecircle(colour=blue),b||i,s||i,c||i])):
end do:
display([pics],insequence=true,axes=none,scaling=constrained,view=[-4*a..4*a,-4*a..4*a]);
 

Plot_2d
 

>
 

Epicycloid, second form 

The nephroid is also an epicycloid in a second sense. This time the rolling circle is radius Typesetting:-mrow(Typesetting:-mn(, larger than the base circle and the "inside" of the rolling circle rolls around the base circle.We start with the rolling circle touching at the top. 

> point(top,0,2*a):point(bottom,0,-2*a):
circle(basecircle,[top,bottom],centername=O):
point(touch,0,2*a): #rolling circle touches base circle
segment(baseradius,O,touch): #radius of base circle
expansion(rr1,baseradius,3/2,touch): #stretch radius to make rolling circle radius
point(centre,coordinates(DefinedAs(rr1)[1])): #centre of rolling circle
segment(r1,centre,touch): #redo stretch radius with nice endpoint names
circle(c1,[centre,3*a]): #rolling circle
draw([basecircle(colour=blue),r1,c1],printtext=true,axes=none);
 

Plot_2d
 

At an angle Typesetting:-mrow(Typesetting:-mi( around the base circle, the rolling circle touches at the end of the radius at angle theta (yellow slice). Expand this radius by 3/2 (back from the touch point) to get the rolling circle radius. We have traversed a distance Typesetting:-mrow(Typesetting:-mi( around the circumference of the base circle. So the rolling circle has rolled by the same circumference, or by an angle Typesetting:-mrow(Typesetting:-mi((green region). This angle is subtracted from Typesetting:-mrow(Typesetting:-mi( to find the point p2 on the nephroid. Try different values of theta to see the rolling circle at different possible positions. 

> theta:=1;
point(touch,2*a*sin(theta),2*a*cos(theta)): #rolling circle touches base circle
segment(baseradius,O,touch): #radius of base circle at angle theta
expansion(rr2,baseradius,3/2,touch): #stretch radius to make rolling circle radius
point(centre,coordinates(DefinedAs(rr2)[1])): #centre of rolling circle
segment(r2,centre,touch): #redo stretch radius with nice endpoint names
circle(c2,[centre,3*a]): #rolling circle
phi:=theta*2/3;
rotation(s2,rr2,phi,counterclockwise,centre): #rotate the stretched radius by phi
point(p2,coordinates(DefinedAs(s2)[2])): #here is its endpoint
display(draw([basecircle(colour=blue),touch,c2,r2,p2],printtext=true,axes=none),
       plottools[pieslice]([0,0],2*a,Pi/2..Pi/2-theta,colour=yellow),
       plottools[pieslice](coordinates(centre),3*a,Pi/2-theta..Pi/2-theta+phi,colour=green),            view=[-4*a..4*a,-4*a..4*a]);
 

 

 

1
`/`(2, 3)
Plot_2d
 

Now put this in a loop and animate the sequence of drawings formed. We need to go to Typesetting:-mrow(Typesetting:-mi( to get the full curve, as shown by the red radius.  To see the animation, click on the plot and choose play on the toolbar. 

The green radius of the rolling circle points to the point on the circumference tracing out the nephroid.  

> n:=52: #number of pictures to draw
pics:=NULL:pts:=[0,2*a]:
for i from 0 to n-1 do
  theta:=i*6*Pi/n;
  point(touch||i,2*a*sin(theta),2*a*cos(theta)):
  segment(baseradius||i,O,touch||i):
  expansion(rr||i,baseradius||i,3/2,touch||i):
  point(centre||i,coordinates(DefinedAs(rr||i)[1])):
  segment(r||i,centre||i,touch||i):
  circle(c||i,[centre||i,3*a]):
  phi:=theta*2/3;
  rotation(ss||i,rr||i,phi,counterclockwise,centre||i):
  point(p||i,coordinates(DefinedAs(ss||i)[2])):
  segment(s||i,p||i,centre||i):
  pts:=pts,coordinates(p||i):
  pics:=pics,display(pointplot([pts],style=line),
                draw([border(5*a),basecircle(colour=blue),O(colour=blue),centre||i,
                   c||i,r||i,p||i,s||i(colour=green)]));
end do:
display([pics],insequence=true,axes=none,scaling=constrained,view=[-4*a..4*a,-4*a..4*a]);
 

Plot_2d
 

>
 

Envelope of tangents 

This construction is based around a base circle centered at the origin O, with a vertical diameter, as before except that this time the radius is Typesetting:-mrow(Typesetting:-mn(. We choose a point R on the vertical diameter, and construct a circle with R as centre that passes through the origin. We then find the points T1 and T2 where this circle intersects the base circle, and construct the line segments R-T1 and R-T2Typesetting:-mrow(Typesetting:-mi(Note that there will be no intersection if R is closer to the origin than it is to the top point. On the other hand, it is possible to have R outside the base circle on an extension of the vertical diameter. The intersection command below returns the two points of intersection between the circles "c1" and "basecircle" and names them "T1" and "T2". 

> point(top,0,4*a):point(bottom,0,-4*a):
circle(basecircle,[top,bottom],centername=O):
segment(vertical,top,bottom):
h:=2.4*a;  # height of point R
point(R,0,h):
circle(c1,[R,h]):
intersection('T1T2',c1,basecircle,['T1','T2']):
segment(RT1,R,T1):
segment(RT2,R,T2):
draw([basecircle(colour=blue),vertical(colour=blue),c1,RT1,RT2],printtext=true,axes=none);
 

 

2.4
Plot_2d
 

Now we draw the line segments R-T1 and R-T2 for many points R along the top and bottom quarters of the vertical diameter and and also on the extension of the vertical diameter outside the base circle. The envelope of these lines is the nephroid. The picture looks better if the R's are more closely spaced near Typesetting:-mrow(Typesetting:-mn( than further out, hence the use of Typesetting:-mrow(Typesetting:-mi( in the calculation of Typesetting:-mrow(Typesetting:-mi(, the distance of R above the origin. The value of Typesetting:-mrow(Typesetting:-mi( is taken as positive; the top R-T1 and R-T2 are then calculated from Typesetting:-mrow(Typesetting:-mi( and the bottom ones are calculated using Typesetting:-mrow(Typesetting:-mo(. 

> n:=25: #number of points along the vertical diameter
segments:=NULL:i:=0:
for i to n do
  h:=radius(basecircle)/2+(i/n)^2*30*radius(basecircle)/n;  
  point(Rtop||i,0,h);
  circle(ctop||i,[Rtop||i,h]);
  intersection('T1T2',ctop||i,basecircle,[T1top||i,T2top||i]);
  segments:=segments,segment(RT1top||i,Rtop||i,T1top||i),segment(RT2top||i,Rtop||i,T2top||i):
  point(Rbot||i,0,-h);
  circle(cbot||i,[Rbot||i,h]);
  intersection('T1T2',cbot||i,basecircle,[T1bot||i,T2bot||i]);
  segments:=segments,segment(RT1bot||i,Rbot||i,T1bot||i),segment(RT2bot||i,Rbot||i,T2bot||i):
end do:
draw([basecircle(colour=blue),segments],axes=none);
 

Plot_2d
 

>
 

Envelope of tangents, second form 

This construction is based around a base circle, centered at the origin O with radius Typesetting:-mrow(Typesetting:-mn(. The circumference is marked off at equal intervals, e.g., 10 degrees, and these points are numbered 0, 1, 2, ... . Point 1 is joined to point 3, points 2 to 6, points 3 to 9, and in general point Typesetting:-mrow(Typesetting:-mi( to Typesetting:-mrow(Typesetting:-mn(. The envelope of these lines is the nephroid. 

> point(top,0,4*a):point(bottom,0,-4*a):
circle(basecircle,[top,bottom],centername=O):
n:=36;
pts:=NULL:
for i to 9 do
  theta:=i*2*Pi/n;
  point(p||i,4*a*cos(theta),4*a*sin(theta));
  pts:=pts,p||i;
end do:
segment(s13,p1,p3):
segment(s26,p2,p6):
segment(s39,p3,p9):
draw([border(9*a),basecircle(colour=blue),pts,s13(printtext=false),
      s26(printtext=false),s39(printtext=false)],printtext=true,axes=none);
 

 

36
Plot_2d
 

Now do it many times. The intial points need only go a quarter of the way around the circle. For symmetry, we run both clockwise and anticlockwise. The left half of the nephroid is obscured by the lines and so we do not generate its envelope. 

> n:=100;
segments:=NULL:
for i from 1 to 3*n/4 do  # make the points
  theta:=i*2*Pi/n;
  point(p||i,4*a*cos(theta),4*a*sin(theta)); # going counter clockwise
  point(m||i,4*a*cos(-theta),4*a*sin(-theta)); # clockwise
end do:
for i from 1 to n/4 do
  j:=3*i;
  segment(sp||i,p||i,p||j);
  segment(sm||i,m||i,m||j);
  segments:=segments,sp||i,sm||i;
end do:
display(draw([basecircle(colour=blue),segments],axes=none),view=[-6*a..6*a,-6*a..6*a]);
 

 

100
Plot_2d
 

>
 

Reflection of parallel rays by a circle 

If parallel rays hit a circle and are reflected (angle of incidence = angle of reflection), then the envelope of the reflected rays is a nephroid. In technical language, the nephroid is the caustic of a circle with radiant point at infinity. A ray entering from the top (black) hits at point P and is reflected (red). Note the ease of programming this using the reflection command, where "ref" is the result of "ray" reflected in the line "rad". 

> h:=2.1*a: # horizontal location of incoming ray
point(top,0,4*a):point(bottom,0,-4*a):
circle(basecircle,[top,bottom],centername=O):
point(inh,h,8*a): # ray comes in from this point
point(P,h,-sqrt((4*a)^2-h^2)): # point where hits circle
segment(ray,inh,P):
line(rad,[O,P]): # radius O-P
reflection(ref,ray,rad):
draw([border(9*a),basecircle(colour=blue),P,ray(colour=black,printtext=false),ref(printtext=false)],printtext=true,axes=none);
 

Plot_2d
 

Now do it many times. 

> n:=15;
point(top,0,4*a):point(bottom,0,-4*a):
circle(basecircle,[top,bottom],centername=O):
rays:=NULL:
for i from -n to n do
  h:=i*4*a/n;
  point(inh||i,h,8*a): # ray comes in from this point
  point(P||i,h,-sqrt((4*a)^2-h^2)): # point where hits circle
  segment(ray||i,inh||i,P||i):
  line(rad||i,[O,P||i]): # radius O-P
  reflection(ref||i,ray||i,rad||i);
  rays:=rays,ray||i,ref||i;
end do:
draw([border(9*a),rays,basecircle(colour=blue)],axes=none);
 

 

15
Plot_2d
 

This reflection can be seen in diluted milk in a cooking pot on the floor, with the sun coming in a window, as in the image below. 

Image 

>
 

Polar and cartesian equations and plots 

The polar equation can be written in several forms. Simplest is perhaps Typesetting:-mrow(Typesetting:-mi(  Another form is Typesetting:-mrow(Typesetting:-mi(, which needs to run to Typesetting:-mrow(Typesetting:-mn( to produce the whole closed curve. 

> plot(2^(1/2)*a*((1+sin('theta'))^(1/3)+(1-sin('theta'))^(1/3))^(3/2),'theta'=0..2*Pi,coords=polar,scaling=constrained,axes=none);
plot(2*a*(sin('theta'/2+Pi/4)^(2/3)+cos('theta'/2+Pi/4)^(2/3))^(3/2),'theta'=0..4*Pi,coords=polar,scaling=constrained,axes=none);
 

 

Plot_2d
Plot_2d
 

And the cartesion equation is Typesetting:-mrow(Typesetting:-mi(, which can be plotted using implicitplot. 

> implicitplot((x^2+y^2-4*a^2)^3=108*a^4*x^2,x=-4..4,y=-3..3,grid=[100,100],scaling=constrained,axes=none);
 

Plot_2d
 

References 

Lockwood, E.H. A Book of Curves, Cambridge University Press, London, 1961. Instructions for the drawing exercises include dimensions for getting nice looking results. In some cases several Maple commands replicate a simple drawing action, but sometimes the Maple is very simple, for example, the reflection command in generating the caustic. The Cartesian equation and one of the polar forms are found in Lawrence, J.D. A Catalog of Special Plane Curves, Dover, NY, 1972, though they are rotated 90 degrees from those given here. 

Conclusions 

The nephroid can be generated in a variety of interesting and beautiful ways, which can be implemented in Maple using the geometry package. The analytical capabilities of Maple allow the curve to be plotted and analysed for things that we have not attempted here, e.g., for deriving the arc length, but it is interesting to generate the curves using envelopes of circles and lines, as was done historically. 

 

Legal Notice: The copyright for this application is owned by the author(s). Neither Maplesoft nor the author are responsible for any errors contained within and are not liable for any damages resulting from the use of this material. This application is intended for non-commercial, non-profit use only. Contact the author for permission if you wish to use this application in for-profit activities.
 

Image