Archive for August 5th, 2015

HP 7475A Plotter: Superformula Demo

Setting n2=n3=1.5 generates smoothly rounded shapes, rather than the spiky ones produced by n2=n3=1.0, so I combined the two into a single demo routine:

HP 7475A - SuperFormula patterns

HP 7475A – SuperFormula patterns

A closer look shows all the curves meet at the points, of which there are 37:

HP 7475A - SuperFormula patterns - detail

HP 7475A – SuperFormula patterns – detail

The spikes suffer from limited resolution: each curve has 10 k points, but if the extreme end of a spike lies between two points, then it gets blunted on the page. Doubling the number of points would help, although I think this has already gone well beyond the, ah, point of diminishing returns.

I used the three remaining “disposable” liquid ink pens for the spiked curves; the black pen was beyond repair. They produce gorgeous lines, although the magenta ink seems a bit thinned out by the water I used to rinse the remains of the last refill out of the spiral vent channel.

I modified the Chiplotle supershape() function to default to my choices for point_count and travel, then copied the superformula() function and changed it to return polar coordinates, because I’ll eventually try scaling the linear value as a function of the total angle, which is much easier in polar coordinates.

The demo code produces the patterns in the picture by iterating over interesting values of n1 and n2=n3, stepping through the pen carousel for each pattern. As before, m should be prime/10 to produce a prime number of spikes / bumps. You could add more iteration values, but six of ’em seem entirely sufficient.

A real demo should include a large collection of known-good parameter sets, from which it can pick six sets to make a plot. A legend documenting the parameters for each pattern, plus the date & time, would bolster the geek cred.

The Python source code with the modified Chiplotle routines:

from chiplotle import *
from math import *

def superformula_polar(a, b, m, n1, n2, n3, phi):
   ''' Computes the position of the point on a
   superformula curve.
   Superformula has first been proposed by Johan Gielis
   and is a generalization of superellipse.
   Tweaked to return polar coordinates

   t1 = cos(m * phi / 4.0) / a
   t1 = abs(t1)
   t1 = pow(t1, n2)

   t2 = sin(m * phi / 4.0) / b
   t2 = abs(t2)
   t2 = pow(t2, n3)

   t3 = -1 / float(n1)
   r = pow(t1 + t2, t3)
   if abs(r) == 0:
      return (0,0)
 #     return (r * cos(phi), r * sin(phi))
     return (r,phi)

def supershape(width, height, m, n1, n2, n3,
   point_count=10*1000, percentage=1.0, a=1.0, b=1.0, travel=None):
   '''Supershape, generated using the superformula first proposed
   by Johan Gielis.

   - `points_count` is the total number of points to compute.
   - `travel` is the length of the outline drawn in radians.
      3.1416 * 2 is a complete cycle.
   travel = travel or (10*2*pi)

   ## compute points...
   phis = [i * travel / point_count
      for i in range(1 + int(point_count * percentage))]
   points = [superformula_polar(a, b, m, n1, n2, n3, x) for x in phis]

   ## scale and transpose...
   path = [ ]
   for r, a in points:
      x = width * r * cos(a)
      y = height * r * sin(a)
      path.append(Coordinate(x, y))

   return Path(path)


if __name__ == '__main__':
   paperx = 8000
   papery = 5000
   if  not False:
     pen = 1
     for m in [3.7]:
        for n1 in [0.20, 0.60, 0.8]:
          for n2 in [1.0, 1.5]:
              n3 = n2
              e = supershape(paperx, papery, m, n1, n2, n3)
              if pen < 6:
                 pen += 1
                 pen = 1
     e = supershape(paperx, papery, 1.9, 0.8, 3, 3)