Advertisements

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.
   see: http://en.wikipedia.org/wiki/Superformula
   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)
   else:
 #     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)

## RUN DEMO CODE

if __name__ == '__main__':
   paperx = 8000
   papery = 5000
   if  not False:
     plt=instantiate_plotters()[0]
     plt.set_origin_center()
     plt.write(hpgl.VS(10))
     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)
              plt.select_pen(pen)
              if pen < 6:
                 pen += 1
              else:
                 pen = 1
              plt.write(e)
     plt.select_pen(0)
   else:
     e = supershape(paperx, papery, 1.9, 0.8, 3, 3)
     io.view(e)
Advertisements

  1. #1 by Jason Doege on 2015-08-05 - 09:09

    Can you dynamically change the number of points based on the rate of change of the vector?

    • #2 by Ed on 2015-08-05 - 10:11

      That’s left as an exercise for the student… [evil grin]

      It’d also be handy to discard successive points falling within epsilon of the previously plotted point, mostly to increase the pen speed near the middle of the figure where the angle increases continuously as the radius muddles along.

      As it stands, the program whacks the formula against a list of equally spaced points and plots whatever comes out. You could postprocess the whole list (maybe starting with 10x more points) or generate angles on the fly to satisfy a spacing parameter.

      So many projects…

    • #3 by madbodger on 2015-08-05 - 11:43

      Alternatively, if you’re doing the calculations in polar coördinates, you can arrange for the angles to align with the points.