Mandelbrot Set with Different Paramaters (Source Code)

Using the center coordinate and zoom factor to draw the following Mandelbrot Set visualizations.

(-0.75, 0), Zoom=1
(-0.103865, -0.9584393), Zoom=167466.7.
(-0.761574, -0.0847596) Zoom=3125
(-0.761574, -0.0847596) Zoom=78125
(-0.59990625, -0.4290703125) Zoom=1024
(-1.62917, -0.0203968) Zoom=3125
(0.2613577, -0.002018128) Zoom=3354.786

Source Code:

from PIL import Image
import colorsys
import math

px, py = -0.7746806106269039, -0.1374168856037867 #Tante Renate
px, py, zoom = -0.74384935657398, -0.13170134084746293, 5788441.443619884
px, py, zoom = 2.613577e-1, -2.018128e-3, 3.354786e+3
px, py, zoom = -0.59990625, -0.4290703125, 1024
px, py, zoom = -1.038650e-1, -9.584393e-1, 1.674667e+5
px, py, zoom = -0.761574, -0.0847596, 78125
px, py, zoom = -1.62917,-0.0203968, 3125
px, py, zoom = -0.75,0,1
R = 3 
max_iteration = 512
w, h = 1250,1250
mfactor = 1

def Mandelbrot(x,y,max_iteration,minx,maxx,miny,maxy):
    zx = 0
    zy = 0
    RX1, RX2, RY1, RY2 = px-R/2, px+R/2,py-R/2,py+R/2
    cx = (x-minx)/(maxx-minx)*(RX2-RX1)+RX1
    cy = (y-miny)/(maxy-miny)*(RY2-RY1)+RY1
    i=0
    while zx**2 + zy**2 <= 4 and i < max_iteration:
        temp = zx**2 - zy**2
        zy = 2*zx*zy + cy
        zx = temp + cx
        i += 1
    return i

def gen_Mandelbrot_image():
  bitmap = Image.new("RGB", (w, h), "white")
  pix = bitmap.load()
  for x in range(w):
    for y in range(h):
      c=Mandelbrot(x,y,max_iteration,0,w-1,0,h-1)
      v = c**mfactor/max_iteration**mfactor
      hv = 0.67-v*2
      #if hv<0: hv+=1
      r,g,b = colorsys.hsv_to_rgb(hv,1,1-(v-0.1)**2/0.9**2)
      r = min(255,round(r*255))
      g = min(255,round(g*255))
      b = min(255,round(b*255))
      pix[x,y] = int(r) + (int(g) << 8) + (int(b) << 16)
  bitmap.save("Mandelbrot_"+str(px)+"_"+str(py)+"_"+str(zoom)+".jpg")
  bitmap.show()
  
R=3/zoom
gen_Mandelbrot_image()

Zooming 10^13 Times into Julia Set Animation

Write a Python program to generate hundreds of images of Julia Set with ever zooming ranges. Please note that Turtle is not used in this project for speed consideration. Then use an external software to combine the images into a video:

Zooming 10^13 Times into Julia Set

The video above zooms into the center at 0.0958598997051 + 1.1501990019993i with c = 0.355 + 0.355i. In each iteration the range shrinks by 5% until the range becomes 1/10^13 the size of the original range. You can modify the code to try different centers and c. The following is the source code:

from PIL import Image
import colorsys

cx = -0.7269
cy = 0.1889
R = (1+(1+4*(cx**2+cy**2)**0.5)**0.5)/2+0.001
max_iteration = 512
print(R)

w, h, zoom = 1500,1500,1

def julia(cx,cy,RZ,px,py,R,max_iteration,x,y,minx,maxx,miny,maxy):
    zx = (x-minx)/(maxx-minx)*2*RZ-RZ+px
    zy = (y-miny)/(maxy-miny)*2*RZ-RZ+py
    i=0
    while zx**2 + zy**2 < R**2 and i < max_iteration:
        temp = zx**2 - zy**2
        zy = 2*zx*zy + cy
        zx = temp + cx
        i += 1
    return i

def gen_julia_image(sequence,cx,cy,RZ):
  bitmap = Image.new("RGB", (w, h), "white")
  pix = bitmap.load()
  for x in range(w):
    for y in range(h):
        # smllaer: right,down
      c=julia(cx,cy,RZ,0.0958598997051,1.1501990019993,R,max_iteration,x,y,0,w-1,0,h-1)
      v = c/max_iteration
      hv = 0.67-v*0.67
      r,g,b = colorsys.hsv_to_rgb(hv,1,v/2+0.45)
      r = min(255,round(r*255))
      g = min(255,round(g*255))
      b = min(255,round(b*255))
      pix[x,y] = int(r) + (int(g) << 8) + (int(b) << 16)
  bitmap.save("julia_"+str(sequence)+".jpg")
#  bitmap.show()

f = 0.95
RZF = 1/1000000000000
RZ = 1
k=1
while RZ>RZF:
  print(k,RZ)
  gen_julia_image(k,0.355,0.355,RZ)
  RZ *= f
  k+=1

Related Projects:

Julia Set Fractal Animation

Julia Set with Different Parameters

N Overlapping Circle with Python and Turtle (Source Code)

Generalize the three overlapping circles project by letting it draw any number of overlapping circles. The following is the overlapping circles from size 2 to size 7.

Solution

import turtle
import math

screen = turtle.Screen()
screen.title('N Overlapping Circles - PythonTurtle.Academy')
screen.setup(1000,1000)
turtle.hideturtle()
turtle.speed(0)
turtle.pensize(2)

def draw_circle(x,y,radius):
  turtle.up()
  turtle.goto(x,y-radius)
  turtle.seth(0)
  turtle.down()
  turtle.circle(radius,steps=360)

r = 150
n = 3
r2 = r/2/math.sin(math.radians(180/n))
angle = 90
for _ in range(n):
  draw_circle(r2*math.cos(math.radians(angle)),
              r2*math.sin(math.radians(angle)),
              r)
  angle += 360/n

Three Overlapping Circles with Python and Turtle (Tutorial)

Draw the following overlapping circles. Please note that each circle passes through the center of the other two circles.

Three Overlapping Circles

Solution

We observe that the centers of the three circles form an equilateral triangle and the length of the equilateral triangle is the radius of the circle. So, the first step is to figure out the coordinates of the vertices of the equilateral triangle (with some math), and then draw three circles given the these three coordinates as the centers. So, it will be helpful to create a function that draws circle based on the center and radius. The following is the source code:

import turtle

screen = turtle.Screen()
screen.title('Three Circles - PythonTurtle.Academy')
screen.setup(1000,1000)
turtle.hideturtle()
turtle.speed(0)

def draw_circle(x,y,radius):
  turtle.up()
  turtle.goto(x,y-radius)
  turtle.seth(0)
  turtle.down()
  turtle.circle(radius,steps=360)

r = 150
draw_circle(0,r,r*3**0.5)
draw_circle(-r/2*3**0.5,-r/2,r*3**0.5)
draw_circle(r/2*3**0.5,-r/2,r*3**0.5)

What’s next?

Draw any number of overlapping circles.

Julia Set with Different Parameters

In this project, we are generate several Julia Sets by varying the constant c in the normal Julia Set function. Turtle will be too slow to do this work. Instead we are going to use the PIL library. Please check out Julia Set Animation project for source code.

c = -0.618 (Max Iteration=38)
c = 0.355534-0.337292i (Max Iteration=4064)
c = 0.355+0.355i (Max Iteration=512)
c = 0.285+0.01i (Max Iteration=204)
c = -0.8+0.156i (Max Iteration=924)
c = -0.835+0.2321i (Max Iteration=104)
c = 0.7269+0.1889i (Max Iteration=1024)

Related Projects:

Zooming 10^13 Times into Julia Set Animation

Julia Set Fractal Animation

6-Line Snowflake Fractal with Python and Turtle (Tutorial and Source Code)

Use recursion to draw the following snowflake shape generated from 6 sub-fractals of splitting lines.

Recursion Depth 5

The following figures show recursion depths ranging from 0 to 4.

Solution:

To solve this problem, you want to start from a function that draws a line given starting point (x,y), length, direction, and pensize. The following is the code for this function:

def line(x,y,length,direction,pensize):
  turtle.up()
  turtle.pensize(pensize)
  turtle.goto(x,y)
  turtle.down()
  turtle.seth(direction)
  turtle.fd(length)

Now you can define the recursive function that keeps branching out the shorter pair of lines. The starting point of the branch is about 2/5 of way from the original starting point. One branch is turning right about 25 degrees and the other branch is turning left about 25 degrees. Pen size should decrease proportionally too. The following is the code for this function:

def line_fractal(x,y,length,direction,pensize,n):
  if n==0: return
  line(x,y,length,direction,pensize)
  line_fractal(x+math.cos(direction*math.pi/180)*length*2/5,
               y+math.sin(direction*math.pi/180)*length*2/5,
               length*3/5,
               direction-25,
               pensize*3/5,
               n-1)
  line_fractal(x+math.cos(direction*math.pi/180)*length*2/5,
               y+math.sin(direction*math.pi/180)*length*2/5,
               length*3/5,
               direction+25,
               pensize*3/5,
               n-1)

The last function is the easiest. Just call the function above 6 times with 6 evenly spaced lines across 360 degrees. The following is the complete code for this project:

import turtle
import math

screen = turtle.Screen()
screen.title('6 Line Snowflake Fractal - PythonTurtle.Academy')
screen.setup(1000,1000)
screen.tracer(0,0)
turtle.hideturtle()
turtle.speed(0)

def line(x,y,length,direction,pensize):
  turtle.up()
  turtle.pensize(pensize)
  turtle.goto(x,y)
  turtle.down()
  turtle.seth(direction)
  turtle.fd(length)

def line_fractal(x,y,length,direction,pensize,n):
  if n==0: return
  line(x,y,length,direction,pensize)
  line_fractal(x+math.cos(direction*math.pi/180)*length*2/5,
               y+math.sin(direction*math.pi/180)*length*2/5,
               length*3/5,
               direction-25,
               pensize*3/5,
               n-1)
  line_fractal(x+math.cos(direction*math.pi/180)*length*2/5,
               y+math.sin(direction*math.pi/180)*length*2/5,
               length*3/5,
               direction+25,
               pensize*3/5,
               n-1)

def snowflake():
  for i in range(6):
    line_fractal(0,0,400,i*60,5,5)

snowflake()
screen.update()

Gardi Fractal with Python and Turtle (Source Code)

Lori Gardi created this nested overlapping circle fractal in the paper ‘The Universe is a Fractal’. The fractal according to the paper looks similar to a supernova. A simple version to draw is to let the overlapping circles to pass through the centers of the other circle.

Gardi Fractal

To draw this, it will be helpful to create a basic function that draw a circle given the center and radius. Then, create a function that draws the overlapping circles in horizontal and vertical orientations. With these two functions, the recursive function just need to flip the orientation and reduce the radius size in each recursive call. You need do a little geometry to figure out the radius of the smaller circles. The following is the source code that draw this fractal:

import turtle

screen = turtle.Screen()
screen.title('Gardi Fractal - PythonTurtle.Academy')
screen.setup(1000,1000)
screen.tracer(0,0)
turtle.hideturtle()
turtle.speed(0)
turtle.color('teal')

def circle(x,y,radius):
  turtle.up()
  turtle.goto(x,y-radius)
  turtle.down()
  turtle.seth(0)
  turtle.circle(radius, steps=360)

def two_circles(x,y,radius,orientation):
  turtle.pensize(radius/50)
  if orientation==0:
    circle(x-radius/2,y,radius)
    circle(x+radius/2,y,radius)
  else:
    circle(x,y-radius/2,radius)
    circle(x,y+radius/2,radius)

def gardi_fractal(x,y,radius,orientation,n):
  if n==0: return
  two_circles(x,y,radius,orientation)
  gardi_fractal(x,y,(4-7**0.5)/3*radius,1-orientation,n-1)
  
gardi_fractal(0,0,300,0,6)
screen.update()

Star Fractal with Python and Turtle (Tutorial and Source Code)

Draw the following fractal made up with stars. You may need to use recursion and trigonometry to do this project.

Star Fractal (Recursion Depth 4)

The following figures show star fractal with different recursion depths (from depth 0 to depth 4)

Recursion Depth 0
Recursion Depth 1
Recursion Depth 2
Recursion Depth 3

Solution

It is very helpful to make a function that draws star at any given center and size. The following code is the function that does the work. It also can draw filled stars given pen color and fill color.

def star(x,y,length,penc,fillc):
  turtle.up()
  turtle.goto(x,y)
  turtle.seth(90)
  turtle.fd(length)
  turtle.seth(180+36/2)
  L = length*math.sin(36*math.pi/180)/math.sin(54*math.pi/180)
  turtle.seth(180+72)
  turtle.down()
  turtle.fillcolor(fillc)
  turtle.pencolor(penc)
  turtle.begin_fill()
  for _ in range(5):
    turtle.fd(L)
    turtle.right(72)
    turtle.fd(L)
    turtle.left(144)
  turtle.end_fill()

The next step is to define a recursive function that draws the star fractal. One way to stop the recursion function is to set the depth limit. In each recursive call decrement the depth limit by 1. The base condition of the recursive call is when the depth limit is 0. In this case, just draw a star by calling the function we defined above. It requires some trigonometry to figure out the centers and the size of 5 star fractals relative to the current center and size. The following code is the recursive function:

def star_fractal(x,y,length,penc,fillc,n):
  if n==0:
    star(x,y,length,penc,fillc)
    return
  length2 = length/(1+(math.sin(18*math.pi/180)+1)/math.sin(54*math.pi/180))
  L = length-length2-length2*math.sin(18*math.pi/180)/math.sin(54*math.pi/180)
  for i in range(5):
    star_fractal(x+math.cos((90+i*72)*math.pi/180)*(length-length2),
                 y+math.sin((90+i*72)*math.pi/180)*(length-length2),
                 length2,penc,fillc,n-1)

The following is the complete code:

import turtle
import math

screen = turtle.Screen()
screen.title('Star Fractal - PythonTurtle.Academy')
screen.setup(1000,1000)
screen.tracer(0,0)
turtle.hideturtle()
turtle.speed(0)

def star(x,y,length,penc,fillc):
  turtle.up()
  turtle.goto(x,y)
  turtle.seth(90)
  turtle.fd(length)
  turtle.seth(180+36/2)
  L = length*math.sin(36*math.pi/180)/math.sin(54*math.pi/180)
  turtle.seth(180+72)
  turtle.down()
  turtle.fillcolor(fillc)
  turtle.pencolor(penc)
  turtle.begin_fill()
  for _ in range(5):
    turtle.fd(L)
    turtle.right(72)
    turtle.fd(L)
    turtle.left(144)
  turtle.end_fill()

def star_fractal(x,y,length,penc,fillc,n):
  if n==0:
    star(x,y,length,penc,fillc)
    return
  length2 = length/(1+(math.sin(18*math.pi/180)+1)/math.sin(54*math.pi/180))
  L = length-length2-length2*math.sin(18*math.pi/180)/math.sin(54*math.pi/180)
  for i in range(5):
    star_fractal(x+math.cos((90+i*72)*math.pi/180)*(length-length2),
                 y+math.sin((90+i*72)*math.pi/180)*(length-length2),
                 length2,penc,fillc,n-1)
    
star_fractal(0,0,400,'blue','blue',3)
screen.update()

Related Projects:

Blue Star
Colorful Star Fractal 1
Colorful Star Fractal 2