Mandelbrot Set in Python

On the 20th of July 2016, I visited Cedar Point.

 

Near noon, I found myself standing in line with an estimated 1:15 wait. And I was bored. Lucky for me, I had just installed this neat android app called QPython that allowed me to work in python on my phone.

Before the sun set on that day, I created a Mandelbrot generator. I continued to refine it until almost midnight. I was nearly out of data, so I created this only with the knowledge I had gained at Operation Catapult. Some of my solutions are crazy.

class FractalViewer:

    def __init__(self):
        self.raster = []
        self.raster = ""
        self.pos = (0.0,0.0)
        self.zoom = 0.22
        self.ar = 2
        self.res = 48
        self.ycro = 14
        self.escape = 9.0
        self.limit = 128
        self.chars = ['.', '-', '=', '#', '&']
        self.charScale = 4

    def resolveDisplay(self):
        self.raster = ""
        for y in range(self.ycro, self.res-self.ycro):
            self.raster += "\n["
        for x in range(self.res * self.ar):
            self.raster += (self.getPixel((x,y)))
            self.raster += ']'

    def display(self):
        print(self.raster)

    def getPixel(self, xy):
        ri = self.getCoordsOf(xy)
        return self.toChar(self.solvePoint(ri))

    def getCoordsOf(self, xy):
        return(((((xy[0]/(1.0*self.res*self.ar))-0.5)/self.zoom)+self.pos[0],(((xy[1]/(1.0*self.res))-0.5)/self.zoom)+self.pos[1]))

    def solvePoint(self, pt):
        z = [pt[0], pt[1]]
        c = [pt[0], pt[1]]
        for iter in range(self.limit):
            z = [z[0]**2-1*z[1]**2+c[0],2*z[0]*z[1]+c[1]]
        if (z[0]**2 + z[1]**2) > self.escape:
            return iter
        return self.limit + 2

    def toChar(self, value):
        return self.chars[int((value / self.charScale) % 5)] if value < self.limit else " "

fractView = FractalViewer()
sensZoom = 0.5
sensMove = 0.25

while (1==1):
    fractView.resolveDisplay()
    fractView.display()
    print("move:wasd; zoom:tu; zoom scale:op; move scale:kl; new iter count:i###")
    control = (input(">"))
    test = control[0]
    if test=='i':
        fractView.limit = int(control[1:len(control)])
    else:
        for index in range(len(control)):
            test = control[index]
            if test=='u':
                fractView.zoom *= 1 + sensZoom
            elif test=='t':
                fractView.zoom /= 1 + sensZoom
            elif test=='w':
                fractView.pos = (fractView.pos[0], fractView.pos[1] - sensMove/fractView.zoom)
            elif test=='a':
                fractView.pos = (fractView.pos[0] - sensMove/fractView.zoom, fractView.pos[1])
            elif test=='s':
                fractView.pos = (fractView.pos[0], fractView.pos[1] + sensMove/fractView.zoom)
            elif test=='d':
                fractView.pos = (fractView.pos[0] + sensMove/fractView.zoom, fractView.pos[1])
            elif test=='k':
                sensMove -= 0.05
            elif test=='l':
                sensMove += 0.05
            elif test=='o':
                sensZoom -= 0.05
            elif test=='p':
                sensZoom += 0.05

 

features:

  • move and zoom
  • adjustable sensitivity for movement
  • adjustable sensitivity for zoom controls
  • input multiple controls before calculating
  • set any iteration limit with the control i###
  • low memory usage
  • pixels come in 5 vibrant colors:   .  –  =  #  &

Leave a comment