INTRODUCTION

Fractals are fascinating mathematical objects characterized by self-similarity – their fragments look similar to the whole, regardless of scale. Discovered and popularized by Benoît Mandelbrot, fractals have found applications in many fields, from computer graphics to financial market analysis.

Fractals in Nature

Although fractals are abstract mathematical constructs, their patterns often appear in nature:

  • Snowflakes: Each snowflake has a unique but self-similar shape.
  • Romanesco broccoli: This type of broccoli is characterized by a spiral structure, where each smaller floret is similar to the whole.
  • Coastlines: The length of a coastline depends on the scale of measurement – the more accurate the measurement, the longer the line, which results from its fractal nature.
  • Ferns: The structure of a fern is self-similar – each branch resembles the shape of the entire fern.

Here is an image that matches the content:

Interactive Exploration: Sierpinski Triangle

One of the classic examples of a fractal is the Sierpinski triangle. It can be generated as follows:

  1. Start with an equilateral triangle.
  2. Divide it into four smaller, identical triangles.
  3. Remove the middle triangle.
  4. Repeat steps 2 and 3 for the remaining three triangles.
  5. Continue the process indefinitely.

PYTHON CODE

import matplotlib.pyplot as plt

def sierpinski(points, depth):
    if depth == 0:
        return
    p1, p2, p3 = points
    m1 = ((p1[0] + p2[0]) / 2, (p1[1] + p2[1]) / 2)
    m2 = ((p2[0] + p3[0]) / 2, (p2[1] + p3[1]) / 2)
    m3 = ((p3[0] + p1[0]) / 2, (p3[1] + p1[1]) / 2)
    plt.plot([p1[0], p2[0], p3[0], p1[0]], [p1[1], p2[1], p3[1], p1[1]], 'k-')
    sierpinski([p1, m1, m3], depth - 1)
    sierpinski([m1, p2, m2], depth - 1)
    sierpinski([m3, m2, p3], depth - 1)
points = [(0, 0), (1, 0), (0.5, 0.866)]
depth = 5
plt.figure(figsize=(8, 8))
plt.axis('off')
sierpinski(points, depth)
plt.show()

⬆️⬆️⬆️ See in Google Colaboratory


HOW THE CODE WORKS?

The core of the code relies on a recursive algorithm that repeatedly subdivides a triangle into smaller triangles, creating the fractal pattern. Here’s a breakdown of the process:

  1. Initialization: The code starts by defining the initial triangle (points) and the recursion depth (depth).
  2. Base Case: Inside the sierpinski function, there’s a base case: if depth == 0: return. This stops the recursion when the desired level of detail is reached.
  3. Subdivision: If the base case isn’t met, the function proceeds to subdivide the current triangle. It calculates the midpoints (m1m2m3) of each side of the triangle using the midpoint formula.
  4. Plotting the Outer Triangle: The code then uses plt.plot to draw the outer triangle connecting the original vertices (p1p2p3). This forms the largest triangle in the pattern.
  5. Recursive Calls: Here comes the crucial recursive step: the function calls itself three times (sierpinski), each time with a new set of points representing a smaller triangle:
    • sierpinski([p1, m1, m3], depth - 1): Forms a triangle using the original vertex p1 and the midpoints m1 and m3.
    • sierpinski([m1, p2, m2], depth - 1): Forms a triangle using the original vertex p2 and the midpoints m1 and m2.
    • sierpinski([m3, m2, p3], depth - 1): Forms a triangle using the original vertex p3 and the midpoints m2 and m3. Notice that the depth is reduced by 1 in each call, moving us closer to the base case.
  6. Repeating the Process: Each recursive call repeats steps 3 to 5, further subdividing the smaller triangles. This continues until the depth reaches 0, at which point the recursion stops.