From: helthuis@cs.utwente.nl (Bert Helthuis)
Subject: Re: Spyrograph Kinematics
Organization: University of Twente, Dept. of Computer Science
Date: Thu, 15 Oct 1992 08:17:37 GMT

In article <67621@cup.portal.com>, Chris_F_Chiesa@cup.portal.com writes:

   lines deleted ..
|> 
|> I'd be interested in seeing the program whose originator started this thread
|> just now; what language is it and on what platform does it operate?
|> 
|> Anyone interested in an executable ReGIS-outputting Spirograph simulator
|> for VAX/VMS, or to discuss the wonders of Spirograph and its kinematics in
|> general, be sure to write me at the e-mail address below.  One cool thing
|> about SIMULATING Spirograph in a computer is that you need not be bound
|> by physical constraints, for instance you can make the "inner wheel" BIGGER
|> than the "outer ring" in which it revolves, for some physically-impossible 
|> effects...  And there's lots more where that comes from...
|> 
|> Chris Chiesa
|>    Chris_F_Chiesa@cup.portal.com


The following spirograph program in PostScript was posted somewhere
in october 1990 in (I believe) comp.lang.postscript. Maube you like it ..

Bert
--------------8<--------8<---------8<-----------
%!PS-Adobe-1.0

%   This program generates a Spirograph(tm) image centered on the page
%   according to the three parameters bigR, littleR, and a.  Images are
%   generated by calculating successive positions of the cycloid generated
%   by rolling a small disk inside a larger ring, with a "pen" placed some
%   distance from the center of the disk.
%
%   bigR is the radius of the "outer" circle (the ring, in Spirograph(tm))
%   littleR is the radius of the "inner" circle (the disk)
%   a is the distance of the "pen" from the center of the inner circle.
%
%   Since the program calculates the total angle through which to
%   parameterize (i.e. how long it has to roll the disk around in the
%   ring) by looking for a greatest common divisor, the values of the
%   parameters bigR, littleR, and a MUST be integers.
%
%   If you're interested, the parametric equations which describe a
%   Spirograph(tm) image are given by:
%
%         x = (R - r) * cos(theta) + a * cos(phi)
%         y = (R - r) * sin(theta) + a * sin(phi),
%
%   where phi = ((R - r) / r) * theta.
%
%   This program was written by Christopher Tate, and is hereby placed
%   into the public domain.  Anyone may freely borrow from or modify
%   this program without permission.  Have fun!

/bigR 200 def         % just change these to define a new image
/littleR 81 def       % littleR should be less than bigR
/a 120 def            % a need not be smaller than littleR

% Euclid's Greatest Common Divisor algorithm to find gcd(m, n)
% Calling process:  m n *gcd* result

/gcd
{
   3 dict begin      % isolate these variables from the rest of the program
   /m exch def /n exch def
   /r m n mod def
   {
      r 0 eq {exit} if      % quit when r equals zero
      /m n def
      /n r def
      /r m n mod def
   } loop
   n                        % put result on the stack
   end                      % restore the original dictionary context
} def

clippath pathbbox      % find the bounding box of the page

/ury exch def          % remember Upper Right y
/urx exch def          % remember URx
/lly exch def          % remember LLy
/llx exch def          % remember LLx

urx llx sub 2 div llx add
ury lly sub 2 div lly add
translate              % move the origin to the center of the page

/diff bigR littleR sub def              % diff = R - r
/frac 1.0 bigR littleR div sub def      % frac = 1.0 - (R/r)

.08 setlinewidth           % sufficiently thin lines
newpath
diff a add 0 moveto        % set initial position

/limit 360 littleR mul bigR littleR gcd div def    % how far we need to go

0 3 limit                  % this is the main loop
{
   dup frac mul /phi exch def       % calculate phi
   /theta exch def                  % recalculate theta
   theta cos diff mul phi cos a mul add   % this is x
   theta sin diff mul phi sin a mul add   % this is y
   2 copy lineto stroke moveto      % same as x y lineto stroke x y moveto
} for

showpage


Newsgroups: comp.graphics,sci.space