Mandelbrot evolution

As promised in my previous post, here is a more evolved version of my Python simple Mandelbrot generator. This version adds color and zoom support, but it remains limited — it is meant to be simple, plus I’m still a Python beginner.

Python Mandelbrot evolved

Read more to get the commented source :)

[python]import mathfrom Tkinter import *# Global variablescwidth = 300        # Width of the canvascheight = 300        # Height of the canvasloops = 200         # Maximum number of iterationszoomf = 4           # Zoom factorcomputing = False   # Wether we're being computing the fractal or not# Global mandelbrot window coordinatesmx1 = -2my1 = 2mx2 = 2my2 = -2# Create a simple (and ugly) color palettedef make_palette(loops):        # Create an empty array    palette = []        for i in range (0, loops):                # Generate an hex color code biased toward red        c = ((i * 1000) + 0xDD9900) % 0xFFFFFF                # Format the color code as #FFFFFF        color = "#%06X" % c        palette.append(color)            # The end of the palette must be black...    palette[loops-1] = "#000"    # ... and the start too    palette[0] = "#000"    palette[1] = "#000"        # Return the palette array    return palette# Mandelbrot function# cv : canvas# palette : the color palette array# x1, y1 : coordinates of the uper left point of the window# x2, y2 : coordinates of the bottom right point of the windowdef mandel(cv, palette, x1, y1, x2, y2):    # Clear the canvas    cv.delete(ALL)    # Compute the x and y increment    dx = float(abs(x2 - x1)) / cwidth    dy = float(abs(y2 - y1)) / cheight        # Let's start the maths    y = y1    for j in range(0, cheight):        x = x1        for i in range(0, cwidth):                        x = x + dx            c = complex(x, y)            a = 0            # Core loop : x = x^2 + c, loop n times, see if the number escape a circle centered on 0            for k in range(0, loops):                a = a*a + c                if abs(a) > 4:                    break                        # Draw a plot of a color from the palette,            # depending of when the point escaped from the loop            cv.create_line(i, j, i, j + 1, fill = palette[k])                    y = y - dy        cv.update()# Compute a rectangular zoom window from the zoom factor# cx, cy : coordinates of the center of the zoom window# unZoom : specifies if we're unzooming instead of the default zoomingdef computeZoomRect(cx, cy, unZoom = False):    global mx1, mx2, my1, my2, zoomf    if unZoom:        width = abs(mx2 - mx1) * float(zoomf)        height = abs(my2 - my1) * float(zoomf)    else:        width = abs(mx2 - mx1) / float(zoomf)        height = abs(my2 - my1) / float(zoomf)    mousex = (cx / float(cwidth)) * abs(mx2 - mx1) + mx1    mousey =  -(cy / float(cheight)) * abs(my2 - my1) + my1            zoomRect = [0, 0, 0, 0]    zoomRect[0] = mousex - (width / float(2))    zoomRect[1] = mousey + (height / float(2))    zoomRect[2] = mousex + (width / float(2))    zoomRect[3] = mousey - (height / float(2))    return zoomRect# Draw a preview of the zoom window on the canvasdef mouseMove(event):    global c, cwidth, cheight, zoomf, zoomRect, computing        # Draw rectangle only if we finished to compute the fractal    if computing == True:        return        # Compute rect half-width and half-height    hwidth = (cwidth / zoomf) / 2    hheight = (cheight / zoomf) / 2    # Delete previous zoom Rect    c.delete(zoomRect)        # Create a new zoomRect around the current mouse location    zoomRect = c.create_rectangle(event.x - hwidth, event.y - hheight, event.x + hwidth, event.y + hheight, width=1)        return# Zoom functiondef zoom(event):    global mx1, mx2, my1, my2, c, palette, computing        # If we are already computing, do nothing and return    if computing == True:        return        # Compute a zoom window    rect = computeZoomRect(event.x, event.y)        # Update the global coordinates    mx1 = rect[0]    my1 = rect[1]    mx2 = rect[2]    my2 = rect[3]        # Draw the fractal    computing = True    mandel(c, palette, mx1, my1, mx2, my2)    computing = False        return    # Unzoom functiondef unzoom(event):    global mx1, mx2, my1, my2, c, palette        # If we are already computing, do nothing and return    if computing == True:        return        # Compute a zoom window    rect = computeZoomRect(event.x, event.y, True)        # Update the global coordinates    mx1 = rect[0]    my1 = rect[1]    mx2 = rect[2]    my2 = rect[3]        # Draw the fractal    computing = True    mandel(c, palette, mx1, my1, mx2, my2)    computing = False        return# Create window and canvasroot = Tk()c = Canvas(root,width = cwidth, height = cheight)zoomRect = c.create_rectangle(0,0,0,0)c.pack()# Register eventsc.bind('', zoom)c.bind('', unzoom)c.bind('', mouseMove)# Create the palettepalette = make_palette(loops)# Draw first mandelbrotcomputing = Truemandel(c, palette, mx1, my1, mx2, my2)computing = False# Run event looproot.mainloop()

Christmas Night

Mon fond d’écran actuel provient de l’excellent Vladstudio — méfiez vous des imitations. Pleins de beaux fonds d’écrans, dont certains déjà postés dans ces colonnes.

En ce moment, donc, une variante de Christmas Night.

Vladstudio wallpaper — Christmas Night
2

A noter la publication par Vlad d’un tutoriel Photoshop basé sur ce wallpaper, ce qui est vraiment chouette — je vais y jeter un œil, ça a l’air tout bien.

Simple Mandelbrot generator using Python

I was looking for a programming language for beginners, that I could teach to my little sister — something different from Basic, which is a bit outdated. I finally looked at Python, and I wrote a small Fractal generator for testing purpose. As I didn’t found a simple example on the Internet, I give my version here.

It is only a simple example, which generate the Mandelbrot fractal. At first, no zoom, no colors — I implemented that later, but here is the first and simplest version. And it works on Mac and Windows, of course.

Simple Mandelbrot fractal using
Python

And here is the code :

[python]from Tkinter import *# Global variablescwidth = 300         # Width of the canvascheight = 300        # Height of the canvasloops = 200          # Maximum number of iterations# Mandelbrot function# cv : canvas# x1, y1 : coordinates of the uper left point of the window# x2, y2 : coordinates of the bottom right point of the windowdef mandel(cv, x1, y1, x2, y2):    # Compute the x and y increment    dx = float(abs(x2 - x1)) / cwidth    dy = float(abs(y2 - y1)) / cheight        # Let's start the maths    y = y1    for j in range(0, cheight):        x = x1        for i in range(0, cwidth):                        x = x + dx            c = complex(x, y)            a = 0            # Core loop : x = x^2 + c, loop n times,            # and see if the number escape from a circle centered on 0            for k in range(0, loops):                a = a*a + c                if abs(a) > 4:                    break                        # Draw a plot if we didn't escape the loop            if k == (loops - 1):                cv.create_line(i, j, i, j + 1)                    y = y - dy        cv.update()# Create window and canvasroot = Tk()c = Canvas(root,width = cwidth, height = cheight)c.pack()# Draw the Mandelbrot fractalmandel(c, -2, 2, 2, -2)# Run event looproot.mainloop()

Next week we’ll see how to add some colors and zoom support without hassle.

Synchronisation iCal / Google Calendar

Logo iCalSi vous gérez votre emploi du temps avec Google Calendar, vous seriez peut-être content de pouvoir utiliser également l’excellent iCal sous Mac, en synchronisant les deux. Pour récupérer les agendas Google dans iCal, pas de soucis : une simple URL à copier dans iCal suffit. Mais que faire quand on veut également envoyer les événements iCal vers Google Calendar ?

Deux solutions existent : premièrement, l’excellent Spanning Sync, qui est simple, bien fait, fonctionne comme il faut… et cher, 65$ environ. Mais si vous geekez un peu, il existe un petit utilitaire en Java qui peut faire le même travail, gratuitement : GCALDaemon. L’installation est un peu délicate, mais un bon tutoriel décrit la marche à suivre, bien mieux que ne le fait le site officiel. Cela fonction parfaitement chez moi — le pied :)

Installer GCALDaemon sous Mac OS X

Edit: A noter toutefois que suite à des changements dans la gestion des calendriers par iCal, ce tutoriel n’est pas compatible avec Leopard. Mais ce n’est pas très grave, puisque l’on peut désormais se passer de GCALDaemon en utilisant directement la synchronisation CalDAV mise en place par Google :)

De retour

De retour après deux semaines de vacances — une dans le désert marocain, et une dans le Midi, hehey. Et le désert, c’est beau. Très.

Edit: j’ai mis en ligne quelques photos.