delta = [[-1,0],[1,0],[0,-1],[0,1]]

def com(T):
  W = [[],[]]
  for r in T:
    W[0].append(r[0])
    W[1].append(r[1])
  
  return map(average, W)

def canon_translate(T):
  m = [min([r[i] for r in T]) for i in range(2)]
  tmp = [tuple([t[i]-m[i] for i in range(2)]) for t in T]
  tmp.sort()
  return tuple(tmp)
  
def rotations(T):
  T2 = [[u[1],-u[0]] for u in T]
  T3 = [[-u[0],-u[1]] for u in T]
  T4 = [[-u[1],u[0]] for u in T]
  return map(tuple,[T] + map(canon_translate, [T2,T3,T4]))

def mirror(T):
  return [tuple([-u[0],u[1]]) for u in T]

def rotflections(T):
  return rotations(T) + rotations(mirror(T))

def average(L):
  return sum(L)/float(len(L))

def canonical_representative(n, oper):
  M = map(canon_translate,oper(n))
  S = map(com, M)
  xlist = [M[r] for r in range(len(S)) if S[r] == min(S)]
  return min(xlist)

def growpoly(cset, mirror):
  if mirror:
    oper = rotations
  else:
    oper = rotflections

  ncs = []
  for t in cset:
   for cell in t:
    for d in delta:
     dd = tuple(map(sum,zip(cell,d)))
     if not (dd in t):
      ncs.append(t + tuple([dd]))
  
# that was the easy bit. canonicalisation is the difficult bit
  
# make origins uniform
  ct = [tuple(canon_translate(t)) for t in ncs]
  ct.sort()

# pick one from each class under rotations / rotflections
  rsf = {}
  nncs = []
  num = 1

  for r in ct:
    if not (r in rsf):
      nncs.append(canonical_representative(r, oper))
      for u in map(canon_translate, oper(r)):
        rsf[u] = num
      num = 1+num
  
  return nncs

def drawsquare(id, tl, side):
  id.polygon([tl, (tl[0]+side, tl[1]), (tl[0]+side, tl[1]+side+1), (tl[0],tl[1]+side+1)], fill=(0,0,0))

def render_polyom(id, x, T, scal):
  for u in T:
    drawsquare(id, (x[0]+scal*u[0], x[1]+scal*u[1]), scal-1)

import Image, ImageDraw
im = Image.new("RGB", (1000, 800),(255,255,255))
id = ImageDraw.Draw(im)

row = 0
for strong in [False]:
  cset = [((0,0),(0,1))]
  for u in range(3,9):
    cset = growpoly(cset, strong)
    print u, len(cset)
    offset = 0
    for c in range(len(cset)):
      render_polyom(id, (u*c*3 - offset, row), cset[c], 3)
      if ((u*c*3 - offset) > (900 - u*3)):
        row = row + 3*u + 10
        offset = (u*c*3) - 50
    row = row + 3*u + 25
    im.save("whee.png")

