Computer Programming 150

(April 28, 2008)

 

The Mandelbrot Set

 

 

 

1.         Mandelbrot.py

 

#

#   Name: Mandelbrot.py

#   Date: April 27, 2008

#

 

from graphics import *

from math import *

from button import *

 

class Grid401:

    #

    #  401 x 401 pixel window

    #

    def __init__(self, win, xmin, ymin, xmax, ymax):

        self.CP_x = 0

        self.CP_y = 0

        self.CD = 0.0

        self.color = "black"

        self.p1 = Point(39, 441)   #  lower left  

        self.p2 = Point(441, 39)   #  upper right

        self.grid = win

        self.grid.setBackground("white")

        #

        #   world to screen coefficients

        #

        self.A = 400.0 / (xmax – xmin)         

        self.B = -400.0 * xmin / (xmax - xmin)

        self.C = 400.0 / (ymax - ymin)

        self.D = -400.0 * ymin /(ymax - ymin)   

   

    def clear(self):

        #

        #  Clear window

        #

        window = Rectangle(self.p1, self.p2)

        window.setFill("white")

        window.draw(self.grid)

 

    def setPixel(self, x0, y0):

        #

        #  Set pixel at world coordinates x0, y0

        #

        x = self.A * x0 + self.B

        y = self.C * y0 + self.D

        self.grid.plotPixel(40+x, 440-y, self.color)

 

    def update(self, xmin, ymin, xmax, ymax):

        #

        #  update world to screen transformation coefficients

        #

        self.A = 400.0 / (xmax - xmin)

        self.B = -400.0 * xmin / (xmax - xmin)

        self.C = 400.0 / (ymax - ymin)

        self.D = -400.0 * ymin /(ymax - ymin)   

            

    def drawLine(self, x0, y0, x1, y1):

        #

        #   draws line given world coordinates

        #  

        x0 = self.A * x0 + self.B

        y0 = self.C * y0 + self.D

        x1 = self.A * x1 + self.B

        y1 = self.C * y1 + self.D

        line = Line(Point(40+x0, 40+y0), Point(40+x1,40+y1))

        line.setOutline(self.color)  # current color

        line.draw(self.grid)

 

    def setColor3i(self, r, g, b):

        self.color = color_rgb(r, g, b)

 

    def setColor(self, color):

        self.color = color

     

def main():

 

    screenWidth = 640

    screenHeight = 480

 

    win = GraphWin("The Mandelbrot Set" , screenWidth, screenHeight) # window size

    win.setCoords(0, 0, screenWidth, screenHeight)

 

    #  initial world coordinates for Mandelbrot set

 

    xmin, ymin  = -2.25, -1.5

    xmax, ymax  =  0.75,  1.5

 

    #  create the Grid401 object

   

    myGrid = Grid401(win, xmin, ymin ,xmax, ymax)

   

    #   create and activate buttons

 

    quitButton = button(win, Point(500, 50), 80, 20, " QUIT  ")

    clearButton = button(win, Point(500, 80), 80, 20, " CLEAR ")

    drawButton = button(win , Point(500, 110), 80, 20,  " DRAW  ")

    resetButton = button(win, Point(500, 140), 80, 20, "RESET")

    quitButton.activate()

    clearButton.activate()

    drawButton.activate()

    resetButton.activate()

 

    myGrid.clear()

 

#   event handling loop

 

    while (True):

        p = win.getMouse()         

 

        #  check for zoom point

 

        if (40 < p.getX() < 440) and (40 < p.getY() < 440):

            xLength = xmax - xmin

            yLength = ymax - ymin

            xCenter = xmin + ((p.getX()-40)/400.0) * (xmax - xmin)

            yCenter = ymin + ((p.getY()-40)/400.0) * (ymax - ymin)

            xmin, xmax = xCenter - xLength/4.0, xCenter + xLength/4.0

            ymin, ymax = yCenter - yLength/4.0, yCenter + yLength/4.0

            myGrid.update(xmin, ymin, xmax, ymax)

 

        #  reset to original world coordinates

 

        elif resetButton.clicked(p):

            xmin, ymin  = -2.25, -1.5

            xmax, ymax  =  0.75,  1.5

            myGrid.update(xmin, ymin, xmax, ymax)       

       

        #  draw Mandelbrot set – using escape algorithm

 

        elif drawButton.clicked(p):

            deltaX = (xmax - xmin)/400.0

            deltaY = (ymax - ymin)/400.0

            for j in range(401):

                for i in range(401):

                    c = complex(xmin + i*deltaX, ymin + j*deltaY)

                    z = complex(0.0, 0.0)

                    for k in range(201):

                        z = z*z + c

                        if abs(z) >= 2:

                            break;

                    if k == 200:

                        myGrid.setColor("black")

                    elif (0 <= k < 20):

                        myGrid.setColor("red")

                    elif (0 <= k < 40):

                        myGrid.setColor("darkred")

                    elif (40 <= k < 60):  

                        myGrid.setColor("orange")

                    elif (60 <= k < 80):

                        myGrid.setColor("brown")

                    elif (80 <= k < 100):

                        myGrid.setColor("yellow")

                    elif (100 <= k < 120):

                        myGrid.setColor("green")

                    elif (120 <= k < 140):

                        myGrid.setColor("cyan")

                    elif (140 <= k <= 160):

                        myGrid.setColor("blue")

                    elif (160 <= k < 180):

                        myGrid.setColor("violet")

                    elif (180 <= k < 200):

                        myGrid.setColor("magenta")

                    else:

                        myGrid.setColor("black")

 

                    myGrid.setPixel(c.real, c.imag)                

 

        elif clearButton.clicked(p):

            myGrid.clear()

           

        elif quitButton.clicked(p):

            break

 

    win.close()               

 

main()