Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

Subphase rotation of 2D sinewave

By: a guest on May 4th, 2012  |  syntax: Python  |  size: 2.71 KB  |  views: 52  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. # (c) Computational Alchemy
  2. # Works on Python 2.7
  3. power_x = 10
  4. power_y = 10
  5. steps = 2000
  6.  
  7. filename = "trig-1"
  8.  
  9. import math, cmath, numpy
  10. import colorsys
  11. from PIL import Image
  12. import os.path
  13.  
  14. def BaseSelect(base, n):
  15.   accumulator = 1
  16.   bit = 0
  17.   while n > 0:
  18.     if (n & 1) == 1:
  19.       accumulator = accumulator * base[bit]
  20.     n = n >> 1
  21.     bit = bit + 1
  22.   return accumulator
  23.  
  24. #make palette
  25. palette = [0] * 256
  26. for i in range(256):
  27.   c = colorsys.hsv_to_rgb(math.pi*i/256, 1.0, 1.0)
  28.   palette[i] = (int(c[0]*256), int(c[1]*256), int(c[2]*256))
  29.  
  30. print "Calculate number sequencies..."
  31.  
  32. W = 2**power_x
  33. H = 2**power_y
  34. base_x = [cmath.exp(2j*math.pi*2**(i+1)/2**power_x) for i in range(power_x)]
  35. base_y = [cmath.exp(2j*math.pi*2**(i+1)/2**power_y) for i in range(power_y)]
  36. print "base_x=", base_x
  37. print "base_y=", base_y
  38. n_x = [BaseSelect(base_x, i) for i in range(2**power_x)]
  39. n_y = [BaseSelect(base_y, i) for i in range(2**power_y)]
  40.  
  41. print "Find boundaries..."
  42.  
  43. max_int = 1.e+10
  44. min_int = -max_int
  45. real_min = max_int
  46. real_max = min_int
  47. imag_min = max_int
  48. imag_max = min_int
  49. mag_min = max_int
  50. mag_max = min_int
  51. arg_min = max_int
  52. arg_max = min_int
  53. for y in range(H):
  54.   for x in range(W):
  55.     n = (n_x[x] * n_y[y])
  56.     real_min = min(real_min, n.real)
  57.     real_max = max(real_max, n.real)
  58.     imag_min = min(imag_min, n.imag)
  59.     imag_max = max(imag_max, n.imag)
  60.     r, phi = cmath.polar(n)
  61.     mag_min = min(mag_min, r)
  62.     mag_max = max(mag_max, r)
  63.     arg_min = min(arg_min, phi)
  64.     arg_max = max(arg_max, phi)
  65.  
  66.  
  67. print "Generating images..."
  68. templates = [
  69.   (real_min, real_max, lambda n: n.real, "real"),
  70.   #(imag_min, imag_max, lambda n: n.imag, "imag"),
  71.   #(mag_min, mag_max, lambda n: cmath.polar(n)[0], "mag"),
  72.   #(arg_min, arg_max, lambda n: cmath.polar(n)[1], "arg"),
  73. ]
  74.  
  75. angle = cmath.exp(2j*math.pi/steps)
  76.  
  77. for step in range(steps):
  78.   print "*** Step", step
  79.   n_x = [BaseSelect(base_x, i) for i in range(2**power_x)]
  80.   n_y = [BaseSelect(base_y, i) for i in range(2**power_y)]
  81.   for template in templates:
  82.     min_n, max_n, num_part, name = template
  83.     magnitude = max_n - min_n
  84.     print "Generating image", name, "..."
  85.     print "min_n=", min_n
  86.     print "max_n=", max_n
  87.     print "magnitude=", magnitude
  88.  
  89.     im = Image.new("RGB", (W, H), (0,0,0))
  90.     pix = im.load()
  91.  
  92.     for y in range(H):
  93.       for x in range(W):
  94.         pix[x, y] = palette[int(255*(num_part(n_x[x] * n_y[y])-min_n)/(magnitude))]
  95.  
  96.     dstfilename, _ = os.path.splitext(filename)
  97.     dstfilename = "%s-%s-%04d.png" % (dstfilename, name, step)
  98.     print "Saving image to", dstfilename
  99.     im.save(dstfilename, "PNG")
  100.  
  101.   base_x = [p*angle for p in base_x]
  102.   base_y = [p*angle for p in base_y]