Achieving some fractals using code, the beauty of recursion!

Rahul Roy
5 min readAug 28, 2020

--

sergio medina

NOTE:- Use laptop as a viewing screen or naturally landscape-aligned screens for better pictures.

If there is one most beautiful piece of code in computer science then it is artistically applied recursion. DFS, transversal, memoization, regenerative approaches are all under its belt. It's something very much similar to the concept of infinity in mathematics, cut short by a base case. And if you are able to optimize tail calls then you have a highly memory-optimized approach. Avoid the tail calls don’t build the stack, don’t build stack!! Recursive depth exceeded!!. There you have killed the beauty.

Adding to the cherry are fractals, recursive structures found in nature, snowflakes, clouds, flower petals, arteries, etc. Mathematicians have always been fascinated by them. The Mandelbrot's set needs a mention here. This amazing pattern is generated by complex numbers escaping the boundary or recursively falling back on hitting the wall.(Random thought reminds me of the control system in electrical engineering, plots to verify the stability of a system)(Wikipedia) (Numperhile).

Mandelbrot fractal(credit)

Fractals have been used to generate random numbers, used extensively in computer graphics to generate images/graphics. To study growth patterns of bacteria. Stock market trading. I do not know all the applications they have been put to but, they have seemingly numerous applications, like other things in technology this is also inspired by nature.

Here I have listed some fractals which I have written, thanks to the amazing course(MOOC) by Gregor Kiczales (cs professor at UBC) which imparted to me some understanding of these amazing patterns. The code is in python ad Racket which makes it quite readable and self-explanatory enjoy!

Sierpinski Triangle
(define (stri s)
(if (<= s 4)
(triangle s “outline” “red”)
(overlay (triangle s “outline” “red”)
(local [(define sub (stri (/ s 2)))]
(above sub
(beside sub sub ))))))

The overlay keyword is to draw over past image, local to assign a local variable (local scope), assigns the result of past recursion to “sub” variable which is further placed in fashion. These triangles are of half the size(height, width) than the earlier ones and are placed over the first one. The big triangle gets drawn as you enter the recursion. Base or cutoff is the if condition which keeps size(height, width) greater than 4.

Left Sierpinski carpet, Right an extension of Sierpinski carpet zoom in to get better picture.
(define (carpet s)
(if (<= s 2)
(square s "outline" "black")
(overlay (square s "outline" "black")
(local [(define sub (carpet (/ s 3)))
(define ctr (square (/ s 3) "solid" "white"))]
(above (beside sub sub sub)
(beside sub ctr sub)
(beside sub sub sub))))))

The left one is achieved through the above code, where inside an outer square nine length/3 squares are placed. The center square is solid white, the rest being black. The right one uses the same code with all squares being in outline mode and colored interchangeably as red and black.

Circular fractal, similar to flowering patters
(define (circle-fractal n)
(local [(define top-leaf (draw-leaf (* n STEP)))
(define center (circle n "solid" "blue"))]
(above top-leaf
(beside (rotate 90 top-leaf) center (rotate -90 top-leaf))
(rotate 180 top-leaf))))
; <template as gen-rec subroutine>
(define (draw-leaf n)
(if (<= n TRIVIAL-SIZE)
(circle n "solid" "blue")
(local [(define center (circle n "solid" "blue"))
(define leaf (draw-leaf (* n STEP)))]
(above leaf
(beside (rotate 90 leaf) center (rotate -90 leaf))))))

There are two functions circle-fractal, the main function, and draw-leaf a subroutine that gets called to draw leaves around the center circle. “TRIVIAL-SIZE” is set to 5. The result of the subroutine is placed on four corners, that are rotated by 0, 90, -90, and 180. The subroutine is the one that does the main work or heavy lifting by generating the recursive pattern of petals. Recursively generating and placing them on top(“above”) and on both sides (“beside”. Which is used by the main function.

The job done by subroutine
Tree fractals played around with color change in each call.
color_r_value = 0
color_b_value = 244

def changeColorR():
global color_r_value
if color_r_value<244:
color_r_value = color_r_value+1
color_r_value = 0
return color_r_value
def changeColorB():
global color_b_value
if color_b_value>1:
color_b_value=color_b_value-1
color_b_value = 244
return color_b_value

def drawTree(x1, y1, angle, depth):
fork_angle = 20
base_len = 10.0
if depth > 0:
x2 = x1 + int(math.cos(math.radians(angle))*depth*base_len)
y2 = y1 + int(math.sin(math.radians(angle))*depth*base_len)
r = changeColorR()
b = changeColorB()
pygame.draw.line(screen, (r,255,255), (x1, y1), (x2, y2), 2)
drawTree(x2, y2, angle - fork_angle, depth -1 )
drawTree(x2, y2, angle + fork_angle, depth -1 )

This generates the green fractal, adding a switching if clause to select from “r” or “b” as the color would generate a color combination similar to shown below. Notice the two different lines drawn recursively from the same point at different angles which helps us achieve the above effect. The left one uses black color as seed. Code credits.

single-sided tree with modified angles.

These have been obtained by playing around with the angles and recursive calls in the tree fractal above. We decrease the class from two to one, recursive call changes the depth of recursion and length of the line.

Mentions for inspiration, do check out these resources.

--

--