Advertisement
here2share

# wave_collapse_function.py

Apr 23rd, 2021
785
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.74 KB | None | 0 0
  1. # wave_collapse_function.py
  2.  
  3. from collections import Counter
  4. from itertools import chain
  5. from random import choice
  6.  
  7. w, h = 40, 25
  8. N = 3
  9.  
  10. def setup():
  11.     size(w*20, h*20, P2D)
  12.     background('#FFFFFF')
  13.     frameRate(1000)
  14.     noStroke()
  15.  
  16.     global W, A, H, patterns, freqs, npat, mat, xs, ys
  17.  
  18.     img = loadImage('Flowers.png')
  19.     iw, ih = img.width, img.height
  20.     xs, ys = width//w, height//h
  21.     kernel = [[i + n*iw for i in xrange(N)] for n in xrange(N)]
  22.     mat = ((-1, 0), (1, 0), (0, -1), (0, 1))
  23.     all = []
  24.  
  25.     for y in xrange(ih):
  26.         for x in xrange(iw):
  27.             cmat = [[img.pixels[((x+n)%iw)+(((a[0]+iw*y)/iw)%ih)*iw] for n in a] for a in kernel]
  28.             for r in xrange(4):
  29.                 cmat = zip(*cmat[::-1])
  30.                 all.append(cmat)
  31.                 all.append(cmat[::-1])
  32.                 all.append([a[::-1] for a in cmat])
  33.  
  34.     all = [tuple(chain.from_iterable(p)) for p in all]
  35.     c = Counter(all)
  36.     patterns = c.keys()
  37.     freqs = c.values()
  38.     npat = len(freqs)
  39.  
  40.     W = [set(range(npat)) for i in xrange(w*h)]
  41.     A = [[set() for dir in xrange(len(mat))] for i in xrange(npat)]
  42.     H = [100 for i in xrange(w*h)]
  43.  
  44.     for i1 in xrange(npat):
  45.         for i2 in xrange(npat):
  46.             if [n for i, n in enumerate(patterns[i1]) if i%N!=(N-1)] == [n for i, n in enumerate(patterns[i2]) if i%N!=0]:
  47.                 A[i1][0].add(i2)
  48.                 A[i2][1].add(i1)
  49.             if patterns[i1][:(N*N)-N] == patterns[i2][N:]:
  50.                 A[i1][2].add(i2)
  51.                 A[i2][3].add(i1)
  52.  
  53.  
  54. def draw():    
  55.     global H, W
  56.  
  57.     emin = int(random(w*h)) if frameCount <= 1 else H.index(min(H))
  58.  
  59.     if H[emin] == 'c':
  60.         print 'finished'
  61.         noLoop()
  62.  
  63.     id = choice([idP for idP in W[emin] for i in xrange(freqs[idP])])
  64.     W[emin] = [id]
  65.     H[emin] = 'c'
  66.  
  67.     stack = set([emin])
  68.     while stack:
  69.         idC = stack.pop()
  70.         for dir, t in enumerate(mat):
  71.             x = (idC%w + t[0])%w
  72.             y = (idC/w + t[1])%h
  73.             idN = x + y * w
  74.             if H[idN] != 'c':
  75.                 possible = set([n for idP in W[idC] for n in A[idP][dir]])
  76.                 if not W[idN].issubset(possible):
  77.                     intersection = possible & W[idN]
  78.                     if not intersection:
  79.                         print 'contradiction'
  80.                         noLoop()
  81.                         return
  82.  
  83.                     W[idN] = intersection
  84.                     lfreqs = [freqs[i] for i in W[idN]]
  85.                     H[idN] = (log(sum(lfreqs)) - sum(map(lambda x: x * log(x), lfreqs)) / sum(lfreqs)) - random(.001)
  86.                     stack.add(idN)
  87.  
  88.     fill(patterns[id][0])
  89.     rect((emin%w) * xs, (emin/w) * ys, xs, ys)
  90.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement