Spiro Applet Help  >  Spiro Operation

# Amazing Spiro Applet Help:How the Program Works

### Mechanics of the Spirograph

The Spiro Applet performs a relatively simple simulation of the spirograph mechanics. The mechanics and the math used to support the simulation are described below for each of the applet's two main drawing modes. (Note: in all the diagrams and mathematics below, I'm assuming a coordinate system with the Y axis inverted; this is how most computer windowing systems, including Java Swing, draw.)

#### Outside Mode

When the position of the moving circle is set to "Outside", the mechanics are that of a wheel rolling clockwise along the outside of a fixed circle or other fixed shape. The diagram below shows how this work. (Note: in Spiro version 1.1 and earlier, the pen was always attached to the mobile at the same position. In Spiro 2.0, you can set that position.)

Spiro draws a line by compute a series of position for the pen, by smoothly varying the angular distance travelled by the mobile. Each pen position is computed using the following basic procedure:

• Given the angular distance A in radians rolled by the mobile, and the radius of the mobile R, compute the linear distance L:  L = A * R.
• Using the distance L and the shape and size of the Stabile, compute the normal angle N in radians to the stabile at that distance. How this is computed depends on the shape, but for a circle Stabile of radius RS, it is:  N = L / RS.
• Using the distance L, normal angle N, the design center point (X,Y), and the shape and size of the Stabile, compute the point (CX,CY) where the Mobile and Stabile are in contact. How this is computed depends on the shape, but for a circle Stabile of radius RS, it is:  CX = X + RS * cos(N)    CY = Y + RS * sin(N).
• Using all the previous information, plus the radial distance of the pen from the center of the Mobile D, find the location of the pen (PX,PY) on the Mobile:  PX = CX + R * cos(N) + D * cos(A)     PY = CY + R * sin(N) + D * sin(A).

For a typical drawing, Spiro goes through this procedure about 20000-50000 times, drawing a dot for each location of the pen. When the dots are close enough together, they form a continuous smooth line.

#### Inside Mode

When the position of the mobile is set to Inside, the mechanics are that of a wheel rolling counterclockwise along the inside rim of another wheel (or other shape). The diagram below shows how this work. Note that, in Spiro version 0.98, the pen is always attached to the mobile at the same angle.

The mathematics for the Inside mode are very similar to those described for outside.

#### ~Inside Mode

The Spiro applet also supports a third mode of operation, called quasi-inside. This mode does not receive an explanatory diagram, because it doesn't really correspond to any physical system. In fact, the quasi-nside mode was a programming bug that happened to make cool-looking pictures, so it was honored with the status of a special mode.

## How Spiro Draws Smooth Lines with Fuzzy Dots

The Java programming language does not have any builtin mechanisms for drawing fancy lines or curves. In general, the best a Java applet can hope for is to draw straight lines with a thickness of one pixel. For the Spiro applet, that was clearly inadequate, so Spiro uses fuzzy-edged dots to do its drawing.

The picture at right shows a close-up of how the dots work. Notice that the dots normally have soft edges, this gives a much smoother look to the line. For a typical drawing, Spiro draws from 6000-60000 individual dots. Each dot has a maximum radius set by the pen "Fade" size; that determines how many screen pixels are affected by each dot.

Internally, Spiro draws each design into an in-memory buffer in grayscale, then combines that buffer with canvas using the pen color.

## How Spiro Saves Your Drawings

When Spiro is running as a Java application, it uses the Java ImageIO package to save your drawing as a Portable Network Graphics (.png) format file. The PNG format was chosen for Spiro 2.0 because it supports 24-bit color, because it is supported by every modern browser and image viewing program, and because it provides good compression.

When Spiro is running as an applet, it has a much harder job to do. Java applets run under some heavy security restrictions inside your web browser. These security restrictions help protect you from network attacks, but they make it impossible for Java applets to save data directly on your computer. To overcome this problem, the Spiro applet depends on a specially-built system installed at the web server, the CGI Image Reflector.

When you click on the "Save Image.." button, Spiro works with the CGI Image Reflector and your browser to display your image in a browser window. The operation is implemented in five steps.

1. Spiro generates an internal representation of your image using the simple PPM format, then compresses it.
2. Spiro opens a connection to the CGI Image Reflector in 'store' mode, selects a unique ID, and uploads the compressed PPM format image using the ID. The CGI Image Reflector stores the compressed PPM format file.
3. Spiro instructs the browser to open a new window, using a URL that invokes the CGI Image Reflector in 'download page' mode.
4. The browser contacts the CGI Image Reflector in 'download page' mode. The CGI Image Reflector constructs an HTML page that includes a reference to itself, but in 'download image' mode. The browser receives the HTML page and displays it.
5. While displaying the page, the browser encounters an image reference to the CGI Image Reflector, and contact the Reflector in 'image download' mode. The Reflector converts the compressed PPM image into a compressed PNG image, and sends that to the browser. The browser displays the image in the page.

## How Spiro Draws Elliptical Designs

Spiro 2.0 is unusual among Spirograph-like rendering systems because it can use geometric figures other than circles as the fixed shape (stabile). Spiro 1.1 supported rounded squares and rounded bars; these are composed of straight lines and sections of circles. Spiro 2.0 added support for pre-defined ellipses. (James Blevins implemented a PHP program that would create elliptical spirographs in 2004. I expressed skepticism about it in an earlier version of this file, because I could not find the application or any information about it. He has since ported it to Javascript and it is available here. Very impressive work, and quite fast. The algorithm is implemented in an obfuscated Javascript file, so I don't know how it works.)

Anyway, circles are very easy to work with, mathematically. Drawing a mathematically accurate spirograph based on a circle can be done in several ways, but they all depend on the fact that the curvature of a circle is constant. The curvature of an ellipse varies. There does not appear to be any closed-form parametric equation for an elliptical hypotrochoid or epitrochoid (and I looked!). Spiro doesn't use such equations, it draws by simulating the moving circle rolling around the fixed shape, then computing the position of the pen. Doing that accurately requires two things:

1. Compute the circumference of an ellipse.
2. The ability to compute a position (x,y) on the ellipse, given an arc length s along the ellipse.
3. The ability to compute the normal angle φ at a point (x,y) on the ellipse.

No. 3 is easy; the normal angle at a point on an ellipse is simply the average of the two angles θ1 and θ2 from each focus of the ellipse to the point. (There are other simple ways to compute this too.)

No. 1 is a little tricky. There is no simple closed-form expression for the circumference of an ellipse. Fortunately, there is an approximation for the circumference that is accurate to about 1/10000 for the kind of ellipses Spiro uses. That works fine for graphics, because the error will be too small to see in a drawing.

No. 2 is hard. There is no simple expression for the arc length along an ellipse, and no simple approximation either. The only ways to compute arc length on an ellipse is to compute an incomplete elliptical integral of the second kind (MathWorld defn). I could not find any Java implementations of this somewhat obscure special function, and the C and Fortran implementations I was able to find did not look reasonable to port to Java. Also, a typical Spiro drawing would require evaluating this integral, numerically, tens of thousands of times! Even on a fast computer, that would have made drawing pretty slow.

Think about how people computed transcendental functions in the days before computers and calculators -- they used numerical tables! If you needed the value for sin(0.1463), you looked up your Sine function table, found the value for 0.146 and 0.147, and took a weighted average (also called linear interpolation). Looking up a value in a table is fast, and pretty accurate as long as your table is big enough and the entries themselves are highly accurate. Also, and this is very important, the way Spiro works does not cause the errors to combine or add up.

The best interactive math packages, such as Mathematica(tm) and Maple(tm), can evaluate every kind elliptical integral known to man. Unfortunately, they are very expensive. The interactive math program Sage has the ability to evaluate most kinds of elliptical integrals, and it is free. So, a program was written in Sage to compute and write out tables of arc length and subtended angle φ values for several differently shaped ellipses. Each table contained 200 entries describing one quadrant of its ellipse. The tables took about 3 minutes each to compute (Sage is not very fast for this particular computation) but that was okay because it only had to be done once.

When Spiro starts up, it reads the arc length tables from text files stored in the program Jar file, and loads them into memory. Before computing a design using an ellipse, it creates a four-quadrant table scaled to the size of ellipse being used. This scaled table permits fast computation of approximate (but very close to correct) subtended angle values using a binary search followed by simple linear interpolation.

Below is a sample. Enjoy!

This applet and accompanying back-end web system were written by Neal Ziring, this document last modified 2/2/09.