How to get Moire from your computer. Mark Gardner.
Would you like some out-of-the-ordinary computer art to decorate your office, country club, or refrigerator door? say no moire! This article is for you. Stack up a supply of paper and get a new ribbon in your printer, I have found that this pursuit is habit forming. And besides proviing some nice printouts, the programs presented may help you in related endeavors of your own.
Moire (mwah-ray) patterns are those sometimes surprising patterns that appear when two similar images (overlays) are laid one over the other. You can see moire patterns easily by looking through two combs held together but slightly askew, or by looking through the folds of the sheer draperies on your windows.
Moire patterns are graphics, but even with straight alphanumeric screens and printers, some very good patterns can be produced. More spectacular images can be made on graphics terminals and dot matrix graphics printers. This article leaves no one out. Figure 1 shows an example of line printer and graphic printer moire patterns.
I've done this work mostly in MBasic under CP/M on a Toshiba T100. Some of the patterns were produced with Toshiba TBasic, with graphics commands similar to those (CIRCLE, LINE, PSET, etc.) found in Basic on the IBM PC. Some examples were made using a Kaypro with a Vectrix VX384. I used a variety of equipment and approaches to generate the patterns presented here, so you should be able to use parts of the article immediately. For the rest, the principles are clear, and you can easily adapt the procedures to your own system. Everyone Does It
Almost everywhre you look these days you see samples of computer art--from siple string drawings to sophisticated animated graphics in full color. Most common are string drawings. Also prevalent are pleasant geometric patterns and simple drawings, as on computer printed Christmas calendars and wall-wide Happy New Year printouts. Less common are examples of random and ordered dithering and random placement of identical patterns.
Of all these, moire patterns are perhaps closes in spirit to the string drawings, but are fundamentally different. In string drawings, the illusion of curves is given by placing straight lines tangential to the implied curves. In moire patterns, the implied curves "appear"; they are related to the intersections of the lines or curves in the overlays. Who Was Moire?
With a name like that, it is easy to guess that moire patterns must be named after some famous French mathematician, right? Wrong! Moire is from the French word for "watered" or "wetted" and has long been used to describe textiles, particularly silk, treated specially to give the surface a water-wave look. The original process may have been an oriental invention, thousands of years ago, but moire textiles are still popular and available. Heavier moire textiles are common as drapery material.
British physicist Lord Rayleigh (ca. 1974) seems to get credit as the first to suggest practical uses for the patterns (as if the art possibilities were impractical).
In fact, moire patterns, carefully done, can represent solutions to a wide number of physical problems--the field surrounding a magnetic dipole, for example. If you have more interest in this, check my best reference, G. Oster and N. Nishijima, "Moire Patterns," Scientific American, 208(5):54-63, 1963. That article gives excellent examples. I have tried to reproduce some of the effects of that reference for this article. What Are Moire Patterns?
Moire patterns result when two or more sets of curves or lines are placed one over the other and viewed together. In a sense, the moire pattern is an optical illusion, since you can claim it really doesn't exist, but you can see it.
The illusion comes from the eye's perception of increased and decreased boldness of pattern density produced by intersections of the two overlays. This is similar to physical interference in wavefronts and hysteresis (beating) between sounds: when two waves are in phase they add for a large amplitude, and when out of phase they subtract for low amplitude. Moire patterns are a little different; two overlays exactly in phase match precisely, and no pattern emerges. The moire comes when lines are close, but not exactly line up. The moire patterns in textiles are authentically produced by folding a cloth, then pressing it to impose the weaving pattern against itself. Absolute alignment is impossible, so the classical moire is produced.
The overlays used to create moire patterns are usually regular, repetitive, and similar. The two are slightly different, but not too different. The following are options that create moire patterns:
* Identical overlays, but offset lightly (good for concentric patterns--squares, circles, ellipses).
* Identical overlays, but rotated slightly (good for overlays composed of straight lines).
* Overlays not identical, but with similar contents (circles with ellipses, squares with rectangles, hyperbolas with parabolas).
* Overlays different only in scale (cross hatching).
* Overlays similar, but where spacing is controlled by different functions. This is variable scale (interesting with straight lines).
* Overlays similar, but where shape is modified slightly by some function (a family of ellipses overlead on circles, where each ellipse in the first overlay has a slightly different aspect).
* Miscellaneous other pairings of overlays, some no doubt yet undiscovered. In my work, I accidentally produced a "non-existent" moire pattern. More later. Using Character Displays
As computer hobbyists, we have two media in which to paint our moire patterns: our display screens and our printers. Either may be a "graphics" product, i.e., using pixels rather than character locations. This certainly makes for more interesting patterns, but some good patterns can be produced on ordinary screens and printers, too. The examples presented in this section were made under MBasic and printed on a Pro Writer printer at 10 pitch.
Plotting with characters on a screen gives a resolution of about 80 x 24. On a character printer, that increases to roughly 80 x 66. Screen character displays are usually fixed, but often a printer can be changed easily to an elite or condensed font and eight lines per inch, which might increase the 80 x 66 limit to 132 x 88. That is not super, but let's see what even the lower printer limit can do. (The examples shown here are all printed. To see them on a screen, use PRINT instead of LPRINT in the programs.)
The first problem I encountered was how to embolden the intersections for CRT display or printing. After some experimentation, I settled on using a period to show the curves by themselves and an H to show points of intersection. I found also in my experiments that the low resolution would often keep curves from intersecting, that is, from crossing a horizontal character line in the same column position. Consequently, I decided to use the character pair ][ in the two adjacent columns where "near inter-sections" occurred. This is a little like an H centered between two columns. The results of these choices can be seen in the example of Figure 1A.
Second, I faced the problem of getting the curves into shape for meaningful printing. Rather than calculate directly to a line of print or screen display, I chose to work with an array of numbers sized to match a printed page. Hence, in the programs presented here, there is a PRINTARRAY dimensioned into (80,63) elements. The program sets the 1 bit of any element that is a member of overlay 1, and the 2 bit of any element that is a member of overlay 2. When finished, then, any element that is at an intersection has the value 3. After all the array calculations are finished, it is quite easy to plot it out with H's and ]['s according to the previous decisions.
In the low resolution of character graphics, overlays of just straight lines don't work very well, by which I mean that the resulting patterns are not very obvious or interesting. Curves work better. Further, if the lines in two overlays cross at steep angles, the effect is not very good; it is better that the lines be nearly parallel. The step or distance between overlay lines is critical, too, and should not be too small, or the display will be cluttered or too large, or the moire pattern will not be easily visible. All of these considerations apply to pixel pattern moires as well.
I wrote two sorts of program, both using the PRINTARRAY technique. The first kind of program used generating functions to locate the elements of each curve. For example, Y = X/2-I is a generating function for a family of straight lines (remember the math, y = mx + b). The counter I is stepped in the program to generate each member of the family of curves in the overlay.
The second sort of program was developed because I wanted to work with "zone plate" (to be described). There was no easy generating function, so the alternate approach was to determine for each element of the PRINTARRAY whether or not it was a member of the pattern.
Listing 1 shows the program that generated the character example of Figure 1A. The program has three main sections. Lines 10 through 110 define the print array and the generating functions. Lines 130 through 370 fill the array with the overlays. Lines 390 through 510 print the array (interpreted to H's and ]['s) to the line printer. To get other moire patterns with this program it is necessary only to change lines 100 and 110, and sometimes lines 180 and 290, since the range and step in the index I may need revision for the specified family to cover the printed page.
The work with "Fresnel zone plates" required a different approach to the generation of the print array. In a zone plate, the pattern is made up of concentric rings in which the area of each ring is the same, including the non-shaded rings and the central circle. The moire patterns made with zone plate overlays have remarkable properties, and I wanted to see if they would be evident even with low-resolution character graphics.
The program in Listing 3 fills the print array with a zone plate image by what I call "brute force." It is not amazingly clever, but it gets the job done. It examines each element of the array, determines what band of the zone plate it is in, and assigns the element to be light (a space, 0 in the array), or dar (a period, 1 in the array). The program actually calculates two zone plates, one offset from the other by the amount B in each axis. The equations in lines 44 and 46 are the generating functions, solved to determine the distance from the center; that distance is then compared against the list of bounding radii in the data statement, while a count is kept to determine the light/dark decision. The same print routine as before copies the array out to the printer.
The four patterns in Figure 2 are the output from this program. The first pattern shown gives only the zone plate overlay, accomplisedh by deleting lines 72 to 92 of the program. The second pattern is from the unaltered program, with a lateral offset of 10 lines. The striking thing about zone plate patterns is that the result is a set of straight lines, which are evident even at this resolution.
The third pattern has the second zone plate offset by 10 lines and 10 columns. There are still the straight line results, but now they are tilted. The lines were close enough together that the ]['s associated with near intersections seemed to clutter up the picture, so I modified the print routine for the version shown in the fourth to eliminate them, and the result shows the moire lines much more clearly.
This ended my work with character moires, but there is plenty of opportunity for other generating functions and criteria, and I have shown you two different ways to fill the print array. On now, to more dense dot matrix patterns. Dot Matrix Displays
I had available three means to try for higher resolution moire patterns. First, I used the dot graphic capability of my printer, using the same programming procedures that I have already described. Second, under TBasic on my computer there is a set of graphics commands that makes circles, ellipses, and line segments very simply. These commands are essentially identical to the set provided with the IBM PC Basic. Third, I had access to a Vectrix VX384 controlled by a Kaypro II, which allowed me to check out a little of what my reference said about color illusions associated with moire patterns.
For the graphics printer, I used essentially the same approach as for the character patterns. However, the amount of memory required to hold an entire page in advance of printing is phenomenal (72 x 160 dots per inch). Consequently, I modified the print array to be only a single line of graphics print, 8 dots high by 1280 dots wide. The X-Y axes are effectively swapped, so that each 1280-dot line corresponds to a single X value of the generating function. The final program is shown in Listing 2. Added at the beginning of the program now is an assembly code routine that sends individual characters to the printer. This is because my MBasic patiently counts everything sent to the printer and inserts a carriage return and linefeed after every 132 characters, whether you like it or not. Your Basic may or may not do this, but with lines 1280 characters long, it was plain annoying.
This particular program generated the example in Figure 1. Figure 3 shows four additional examples, again showing the lines changed from the origin program in Listing 2. The first pattern is the traditional wetted silk look. The generating functions gives simple parallel straight lines, each set with a slightly different slope (2.1 and 2), but with the spacing of one set controlled as a function of the index.
The second pattern has one set of lines with variable slope involving an absolute value, thus putting an interesting series of corners in the resultant pattern. The third is generated with some pythagorean promises and deserves a title.
The last pattern is made from a generating pattern with variable slope, as well as with spacing that is a function of the index. Note in those two programs with variable steps, that I had to rewrite the FOR I loop, since my MBasic would not recognize recalculation of the STEP size once the loop was started.
I should point out that these patterns take from one to five hours per page to print, depending on the complications of the generating functions and the range and step of the generating index.
Figure 4 shows a pattern that didn't work very well and a pattern that shouldn't have worked at all, but did. The first one was an attempt to recreate the visual effect I often see driving on the freeway, looking through the two chain-link fences on pedestrian overcrossings. The fence wires are too fine for me to see, but I can often see a moire pattern, and it is always diamonds, just like the generating overlay.
In the printed pattern of Figure 4A, two sets of squares overlay, one set only slightly smaller than the other. The resultant square (actually, double square) pattern can be discerned, but it is not as exciting as I had hoped. The reason it didn't turn out well, I believe, was that I could not print real squares of two different sizes on my printer given the resolutions 160 and 72, the quotient of which is not integral.
The other pattern in Figure 4B is a fluke. I did two dumb things that turned out as you see. The first thing was to make the generating functions both give straight lines with the same slope, but with the interline spacing of one set variable with the index. Without the other change, this would have resulted in the wholly uninteresting arrangement of which just a snatch is shown in Figure 4C. But I wasn't satisfied, at the time with the horrendous length of time that each print was taking, and I executed my very good idea of limiting the index values to just those of use in a particular X line.
This required solving the generating equations for I with Y=0 and Y=1280. Then the index could be merely stepped between the determined limits. This worked fine, but the initial limit was not always a nice round number as it was when simply set in the DO loop. Hence, each 8-bit wide print line contains pieces of different family members different from the ones on either side. The lines in this pattern are all parallel; there is not a single intersection on the printout; yet you see the striking pattern.
Zone plates in this high-resolution mode also required changes. The brute force approach would take forever--every line would require 10,000 times through the loop.
So, I designed the program shown in Listing 4 to determine by direct calculation the points on each line that were boundaries of the equal-area rings. Then, it was much faster and easier to fill in between pairs of boundaries. The first pattern in Figure 5, a zone plate, was printed with this approach in about 45 minutes. I was able to take advantage of the higher resolution and put nearly five times as many rings as for the character-based zone plate. There is a little bug evident near the bottom of the pattern. It was not obtrusive, so I didn't attack it; no doubt it relates to ordering of the ring boundaries in the YPOINTS array.
The first pattern by itself can be used to create an optical illusion of a moire, that is, an illusion of an illusion. In moderate light, view the single zone plate, then move the image sideway or tilt it. You will see, or seem to see, motion along the lines of the zone plate. This is a moire forming on your retina from the current image and the latent image. This also works well with radial line patterns.
In the second pattern of Figure 5, I have simply printed the second zone plate on top of the first by repositioning the paper (this saved enlarging the program, as I did for the previous approach). The resultant straight line pattern is obvious and well defined. The last pattern shows a zone plate overlaid with simple straight lines. Amazingly, the moire pattern that results is a multiple replication of the zone plate.
This concluded my work with the high-resolution printer, except as described below. I moved on to screen based graphics with Basic graphics commands, which draws circle much, much faster, and so made experimentation much easier. Basic Graphics Command
My toshiba T100 has an alternate operating/programming system called TBasic. It boots directly from disk and is similar to an Atari or Commodore that has only Basic available. It is really an evil environment in which to work, compared to CP/M and MBasic, but since TBasic has some useful graphics commands, I thought it would be interesting to try a few things with it. It was certainly faster; in the previous approaches it was necessary to calculate individual pixels on lines and curves. The graphics commands take care of all of that automatically.
I have included the individual programs with each of the patterns I generated under TBasic. None are commented, because TBasic provides no nice development tools for programs. With CP/M I use WordStar to write programs; a processing program turns these into Basic programs with or without the source file comments. This makes program writing much easier and encourages comments. None of these tools is available under TBasic. The article text will explain as little as necessary.
Getting the generated patterns printed is extremely easy. In TBasic, the COPY key on the computer keyboard is active and prints the screen image directly to the printer. All that is necessary is to provide some control to overcome the dimension squishing that the print operation causes. This can be done in two ways; put the printer in high resolution (160 dots per inch), which makes circles on the screen print as circles on the printer, though the whole screen image then occupies only about half the page width; or, plot ellipses on the screen, narrow vertically, which then get pulled out to circles when printed at the normal 80 dots per inch.
The patterns in Figure 6 are printed at 80 dots per inch. The first is akin to the fence problem I tried with the printer in graphics mode, except the overlays are a dense pattern of small, adjacent circles, with a smaller center to center spacing in the second set. A pattern of circles should emerge. To some extent it does, but again it is not as striking as one would like. The remaining patterns in Figure 6 show an untrodden path. I decided to see what would happen if spirals were overlaid. Pattern 6B shows two simple spirals (radius a linear function of angle) overlaid, one clockwise, and one counter-clockwise. The program for this has an interesting complication. As the calculated elements got further from the center, the initial one-degree angle step was too big, and there were gaps in the lines. Hence, the three groupings shown allow the step to be changed to one-half and then one-quarter degree as the spiral reaches its larger radii.
In pattern 6C, the two simple spirals are offset by 20 dots (see lines 240 and 260 of the program). The pattern looks like radial straight lines, which is as surprising to me as were the parallel straight lines of the zone plates. In pattern 6D, I took another bold step and used a more complex spiral, where the radius is proportional to the square of the angle (see line 210). A pattern emerged that looks something like the field around the poles of a magnet. Color Graphics
It is not likely that you have an expensive, high-resolution, infinite color palette, graphics system in your home. But one refernece made some comments about color illusions that I wanted to check. I had access (courtesy of MAC-I, Calabasas, CA) to a Vectrix VX384 with 672 x 480 dots resolution and a choice of any 512 of 16 million colors. Trying moire patterns with such a marvelous machine was irresistible. The Vectrix was controlled by a Kaypro II, and I was able to program in MBasic, this time using the MBasic line editor, since I did not have my tools on the Kaypro.
Figure 7 shows three of the many patterns I made, two with the standard overlapping circles. In the second pattern, the illusion of white (from green and purple) is clear in the center of the pattern. In the third pattern (shown on page 174), radial straight lines of alternating color, the hoped for illusion was not striking, but the detail near the center of the pattern was very rewarding anyway. That's Not All Folks
This article presents but a fraction of all the moire patterns I have seen. Now it's time for you to start that stack of paper running through your printer.