Zone plates in OpenSCAD.

Remember in first-year physics when you inked zone plates onto glass and diffracted spots and images onto a screen further down an optics rail?

Me neither. For some obscure reason my own freshers’ physics neglected to include that experiment. I set out to rectify the problem with a bit of openSCAD code. From the wikipedia description, zone plate rings toggle from transparent to opaque every time the radius r_n satisfies the criteria:

r_n = sqrt{n lambda f + frac{n^2 lambda^2}{4}}

Where n is the ring number, lambda is the wavelength of light, and f is the focus distance.

Feel free to use the code, .svg file, or .png image below for your own zone plates. Everything is available under a Creative Commons Attribution License and can be found on Github:


//This code is provided under a Creative Commons Attribution license ( Feel free to use it any way you like, but please retain this comment header
//Q. Tyrell Davis

lambda = 550*pow(10,-3);
//wavelength of light (in mm). Taken as an average green here.

zones = 15;
//number of zones. With too many zones the width of each zone will be too thin for practical fabrication

focal = 80;
//the focus distance for the zone plate

strutWidth = .75;
//width of the struts holding the zone plate rings

fineness = 68;
//determines how smooth the circles are

random = 1;
// 0 for ordered placement, 1 for random struts. Ordered placement will result in diffraction spikes

uiStruts = 4;
//Number of struts holding zones in place
//End parameters
//Formulae used to define the zone plate are from

vRand = random * rands(0,1,uiStruts*zones);
plateRadius = sqrt((zones+1)*focal*lambda)+2; //sqrt((zones)*focal*lambda+(pow(n,2)*pow(lambda,2))/4);

//uncomment to echo the thinnest ring width
echo(“thinnest ring = “,sqrt((zones)*focal*lambda+(pow(zones,2)*pow(lambda,2))/4)-sqrt((zones-1)*focal*lambda+(pow((zones-1),2)*pow(lambda,2))/4));
//echo(“plate radius = “,plateRadius);

//uncomment to echo the approx resolution

//Building the zone plate
//translate([-55,-27.5]) square([85,55]); //comment the circle above and uncomment this to make a business card

for(n = [0:2:zones]){
circle(r= sqrt((n)*focal*lambda+(pow(n,2)*pow(lambda,2))/4),$fn = fineness);
circle(r= sqrt((n-1)*focal*lambda+(pow(n,2)*pow(lambda,2))/4),$fn = fineness);

for(k = [1:uiStruts]){
square([sqrt((n)*focal*lambda+(pow(n,2)*pow(lambda,2))/4),strutWidth],center = true);



Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.