16 Replies Latest reply on Dec 9, 2010 12:50 PM by Harbs.

    [CS4/JS] Spirographs -- a.k.a. "Guillochés

    [Jongware] Most Valuable Participant

      A discussion of the spiral graphics as seen on money (and postal cheques, and some of the more expensive lottery bills) on Typophile prompted me to try this in InDesign. It turned out not to be beyond my capabilities! Here is a nice concise script that draws these intricate patterns -- now you can design your own $3 bill!

       

      Using the formulaes from Wolfram on hypotroichoids. Vary the variables at the top for nice patterns; a is the "outer", main radius, b is the "inner" rotating radius, and h is the thickness of the outer rim. (Wrapping it up with a nice dialog is "left as an exercise", meaning I didn't feel like doing it.)

      http://mathworld.wolfram.com/Hypotrochoid.html

      http://mathworld.wolfram.com/Hypotrochoid.html

       

      Not explained on that web page, but the number of rotations to get a complete curve seems to be the greatest common factor of a and b -- I discovered that empirically so I might be wrong about that.

       

      Written using CS4, but I can see no reason it should not work all the way down to 1.0, or up to CS5. Best appreciated with your measurements set to millimeters. Warning: the Greatest Common Factor function does not work well with fractions!

      The number of points per path is clipped to a measly 10,000, because I suspect InDesign will suffer from overly long paths.

       

      app.activeDocument.zeroPoint = [ app.activeDocument.documentPreferences.pageWidth/2, app.activeDocument.documentPreferences.pageHeight/2 ];
      
      a = 80;
      b = 13;
      h = 20;
      
      path = [];
      
      nLoop = b/greatestCommonFactor(a,b);
      
      p = null;
      
      for (t=0; t<=nLoop*360; t+= 0.5)
      {
      
           x = (a - b) * Math.cos(t*Math.PI/180) + h * Math.cos (t*((a - b)/b)*Math.PI/180);
           y = (a - b) * Math.sin(t*Math.PI/180) - h * Math.sin (t*((a - b)/b)*Math.PI/180);
           
           path.push ([x,y]);
           if (path.length > 10000)
           {
                if (p == null)
                {
                     p = app.activeDocument.graphicLines.add().paths[0];
                     p.parent.strokeWeight = 0.1;
                } else
                     p = p.parent.paths.add();
                p.entirePath = path;
                path = [ [x,y] ];
           }
      }
      
      if (path.length > 1)
      {
           if (p == null)
           {
                p = app.activeDocument.graphicLines.add().paths[0];
                p.parent.strokeWeight = 0.1;
           } else
                p = p.parent.paths.add();
           p.entirePath = path;
      }
      
      function greatestCommonFactor (x,y)
      {
           while (y != 0)
           {
                w = x % y;
                x = y;
                y = w;
           }
           return x;
      }