#!/usr/bin/env python # -*- coding: utf8 -*- # Copyright (c) 2008, Thomas Hourdel # All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of Thomas Hourdel nor the names of its contributors # may be used to endorse or promote products derived from this software # without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # Don't use the code "as is", it's absolutly unoptimized for the sake of # readability. And it's damn ugly, which doesn't fit with the previous # readability purpose. # I was about to make a full program with command line parameters and such, # but I got bored. try: import psyco psyco.profile() except: pass try: from PIL import Image, ImageDraw except: print "requires the PIL module (http://www.pythonware.com/products/pil/)" raise SystemExit from math import cos, sin from time import time # Generate a chaotic map # @param maptype Map type (see --help for more informations - not implemented) # @param p Parameters for the given map # @param filename Output image file name # @param size Image size (tuple) # @param scale Map scale # @param move Absolute move offsets (tuple) # @param n Number of iterations def chaotic_map(maptype, p, filename, size, scale, move, n): image = Image.new('L', size, 51) drawer = ImageDraw.Draw(image) pixel = image.load() half_w = size[0] / 2. half_h = size[1] / 2. x_old, y_old = .1, .1 for i in xrange(n): x, y = .0, .0 if maptype == "tinkerbell": x = x_old**2 - y_old**2 + p[0] * x_old + p[1] * y_old y = 2. * x_old * y_old + p[2] * x_old + p[3] * y_old elif maptype == "peterdejong": x = sin(p[0] * y_old) - cos(p[1] * x_old) y = sin(p[2] * x_old) - cos(p[3] * y_old) elif maptype == "henon": x = 1 + y_old - p[0] * x_old**2 y = p[1] * x_old elif maptype == "clifford": x = sin(p[0] * y_old) - p[2] * cos(p[0] * x_old) y = sin(p[1] * x_old) - p[3] * cos(p[1] * y_old) else: return x_old, y_old = x, y xi = half_w + x * scale + move[0] yi = half_h + y * scale + move[1] if -1 < xi < size[0] and -1 < yi < size[1]: color = min(pixel[xi, yi] + 1, 255) pixel[xi, yi] = color drawer.text((10, 5), "%s map" % (maptype), 200) if maptype == "tinkerbell" or maptype == "peterdejong" or maptype == "clifford": drawer.text((10, 18), "a=%0.2f b=%0.2f c=%0.2f d=%0.2f" % (p[0], p[1], p[2], p[3]), 200) elif maptype == "henon": drawer.text((10, 18), "a=%0.2f b=%0.2f" % (p[0], p[1]), 200) image.save(filename) del(pixel) # Main entry point if __name__ == "__main__": start_time = time() chaotic_map("tinkerbell", [0.9, -0.6, 2, 0.5], "TinkerbellMap.png", (500, 500), 225., (100, 100), 300000) print "Tinkerbell map generated in %.2f seconds." % (time() - start_time) start_time = time() chaotic_map("henon", [1.4, 0.3], "HenonMap.png", (500, 500), 175., (0, 0), 150000) print "Henon map generated in %.2f seconds." % (time() - start_time) start_time = time() chaotic_map("peterdejong", [-0.9, 1.6, 1.85, 2.2], "PeterDeJongMap1.png", (500, 500), 115., (35, 0), 800000) print "PeterDeJong map 1 generated in %.2f seconds." % (time() - start_time) start_time = time() chaotic_map("peterdejong", [-2., -2., -1.2, 2.], "PeterDeJongMap2.png", (500, 500), 110., (0, 0), 800000) print "PeterDeJong map 2 generated in %.2f seconds." % (time() - start_time) start_time = time() chaotic_map("clifford", [-1.4, 1.6, 1., .7], "CliffordMap1.png", (500, 500), 120., (35, 0), 800000) print "Clifford map 1 generated in %.2f seconds." % (time() - start_time) start_time = time() chaotic_map("clifford", [1.5, -1.8, 1.6, .9], "CliffordMap2.png", (500, 500), 80., (0, 0), 800000) print "Clifford map 2 generated in %.2f seconds." % (time() - start_time)