import sys from math import floor from pprint import pprint class HSV: def __init__(self, h, s, v): self.hue = h self.saturation = s self.value = v def Hi(hsv): return floor(hsv.hue / 60) % 6 def f(hsv): return hsv.hue / 60 - Hi(hsv) def p(hsv): return (1 - hsv.saturation) * hsv.value def q(hsv): return (1 - f(hsv) * hsv.saturation) * hsv.value def t(hsv): return (1 - ((1 - f(hsv)) * hsv.saturation)) * hsv.value def hsv2rgb(hsv): h = Hi(hsv) if h == 0: return [hsv.value, t(hsv), p(hsv)] elif h == 1: return [q(hsv), hsv.value, p(hsv)] elif h == 2: return [p(hsv), hsv.value, t(hsv)] elif h == 3: return [p(hsv), q(hsv), hsv.value] elif h == 4: return [t(hsv), p(hsv), hsv.value] else: return [hsv.value, p(hsv), q(hsv)] width = 640 height = 480 max_color = 360 zoom_fact = 0.8 max_iterations = 40 center = -0.65 x_inc = width / (200000 * zoom_fact) y_inc = height / (150000 * zoom_fact) def scale(x): return int(x * 255) def scale_rgb(rgb): return [scale(rgb[0]),scale(rgb[1]),scale(rgb[2])] sat = 0.85 val = 0.85 def make_color_map(nb_cols): out = [] for i in xrange(0,nb_cols): out.insert(len(out),''.join(map(chr,scale_rgb(hsv2rgb(HSV((360.0 * i) / (nb_cols + 1),sat,val)))))) return out color_map = make_color_map(min(max_iterations,max_color)) def c(i,j): return complex(x_inc * i + center - x_inc * width / 2, y_inc * j - y_inc * height / 2) def absq(z): return z.real * z.real + z.imag * z.imag def pixel(c): z = complex(0.0,0.0) for i in xrange(max_iterations,1,-1): z = z * z + c if absq(z) >= 4.0: return i return False def color(iterations): if iterations: return color_map[iterations % len(color_map)] else: return "\0\0\0" def render(): for j in xrange(0,height): for i in xrange(0,width): sys.stdout.write(color(pixel(c(i,j)))) def ppm_header(): sys.stdout.write("P6\n") sys.stdout.write(str(width)) sys.stdout.write(" ") sys.stdout.write(str(height)) sys.stdout.write("\n255\n") def run(): ppm_header() render() run()