Skip to content

Instantly share code, notes, and snippets.

@x-or
Created March 20, 2015 13:17
Show Gist options
  • Save x-or/9f16646f226ca9cba276 to your computer and use it in GitHub Desktop.
Save x-or/9f16646f226ca9cba276 to your computer and use it in GitHub Desktop.
### Copyright (c) 2015, Sergey Shishmintzev
### License: Apache/GPLv3
### Examples: http://youtu.be/2kckHKCVvDs https://youtu.be/aFN02gJUJ0o
### Interpreter: Python 2.7.5 with NumPy 1.9.1 and Pillow 2.7.0
power = 19
name = "spiral"
frame_count = 12000
image_width = 1080
image_height = 1080
alpha_z = 55
import numpy as np
import numpy.random as nr
from PIL import Image
import colorsys
np.set_printoptions(linewidth = 180, edgeitems=10, suppress = True)
def additive_binary_construction(components, n):
result = 0
bit_index = 0
while n > 0:
if (n & 1) == 1:
result += components[bit_index]
n >>= 1
bit_index += 1
return result
def multiplicative_binary_construction(components, n):
result = 1
bit_index = 0
while n > 0:
if (n & 1) == 1:
result *= components[bit_index]
n >>= 1
bit_index += 1
return result
# generate palette
palette = [0] * 256
for i, h in enumerate(np.linspace(0, 3, 256)):
c = colorsys.hsv_to_rgb(h, 1.0, 1.0)
palette[i] = (int(c[0]*255), int(c[1]*255), int(c[2]*255))
def alphablend(dst, src, alpha):
return ((dst[0]*(255-alpha) + src[0]*alpha)>>8, (dst[1]*(255-alpha) + src[1]*alpha)>>8, (dst[2]*(255-alpha) + src[2]*alpha)>>8)
spiral_components = np.linspace(1.0/power, 1.0, power) + 1j
print "spiral_components:"
print spiral_components
print "abs:", np.abs(spiral_components)
print "arg:", np.angle(spiral_components)
# Recombination examples
#recombination_components = nr.randint(0, 2, power)
#recombination_components = np.ones(power)
#recombination_components = np.arange(power)+1
#recombination_components = np.array([1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3,])
#recombination_components = np.array([1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1,])
#recombination_components = np.array([1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5,])
recombination_components = np.array([1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10,])
#recombination_components = np.array([5, 4, 4, 3, 3, 2, 2, 1, 1, 0, -1, -1, -2, -2, -3, -3, -4, -4, -5])
assert len(recombination_components) == power, len(recombination_components)
print "recombination_components", recombination_components
hamming_weight_components = np.ones(power)
print "Generate data..."
spiral_points = np.empty(2**power, np.complex128)
hamming_weight = np.empty(2**power, np.uint16)
recombination = np.empty(2**power, np.int32)
for i in xrange(2**power):
spiral_points[i] = multiplicative_binary_construction(spiral_components, i)
hamming_weight[i] = additive_binary_construction(hamming_weight_components, i)
recombination[i] = additive_binary_construction(recombination_components, i)
spiral_magnitude = np.prod(np.abs(spiral_components))
#spiral_magnitude = np.max(np.abs(spiral_points))
print "spiral_magnitude=", spiral_magnitude
print "Render complex plane"
step_x = 1.0*(image_width-1) / (2*spiral_magnitude)
step_y = 1.0*(image_height-1) / (2*spiral_magnitude)
recombination_widdle_factor = np.exp(2j*np.pi*recombination/frame_count)
color_index = np.uint16(255*hamming_weight/power)
for frame in xrange(frame_count+1):
print "frame #", frame
image = Image.new("RGB", (image_width, image_height), (255, 255, 255))
pixels = image.load()
spiral_points_x = np.int32((spiral_points.real+spiral_magnitude)*step_x)
spiral_points_y = np.int32((spiral_magnitude-spiral_points.imag)*step_y)
# range checks
assert np.all(spiral_points_x >= 0)
assert np.all(spiral_points_y >= 0)
assert np.all(spiral_points_x < image_width)
assert np.all(spiral_points_y < image_height)
# render
for i in xrange(2**power):
x = spiral_points_x[i]
y = spiral_points_y[i]
pixels[x, y] = alphablend(pixels[x, y], palette[color_index[i]], alpha_z)
image.save("%s-frame%05d-z.png"%(name, frame), "PNG")
spiral_points *= recombination_widdle_factor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment