2 patterns-animation-Recursive-Pattern
Balazs Horvath edited this page 2026-04-18 11:13:08 +02:00

Recursive Pattern

Mathematical recursion creating self-similar patterns through depth-controlled iteration.

Mathematical Formula


P_0(x, y) = \sin(x) + \cos(y)

P_{n+1}(x, y) = \sin(P_n(x, y) + x) + \cos(P_n(x, y) + y)

Where:

  • P_0 is base pattern
  • P_n is nth recursion
  • More iterations = more complex: d = 0 returns 0
  • Each level adds higher-frequency components

How It Works

Recursive patterns demonstrate mathematical recursion. Each level of recursion adds detail at a smaller scale, creating self-similar patterns where the structure repeats at different scales.

Implementation

import numpy as np

def recursive_pattern(x, y, t, depth=5):
    if depth == 0:
        return 0
    
    # Base pattern
    pattern = np.sin(x * depth + t/5) * np.cos(y * depth + t/5)
    
    # Recursive addition
    pattern += recursive_pattern(x/2, y/2, t, depth-1)
    
    return pattern

width, height = 512, 512
frames = []

for t in range(30):
    x = np.linspace(0, 4*np.pi, width)
    y = np.linspace(0, 4*np.pi, height)
    X, Y = np.meshgrid(x, y)
    
    # Generate recursive pattern
    pattern = np.zeros_like(X)
    for i in range(X.shape[0]):
        for j in range(X.shape[1]):
            pattern[i, j] = recursive_pattern(X[i, j], Y[i, j], t)
    
    # Normalize and colorize
    pattern = (pattern + 5) / 10
    rgb = np.zeros((height, width, 3), dtype=np.uint8)
    rgb[..., 0] = (pattern * 255).astype(np.uint8)
    rgb[..., 1] = ((1 - pattern) * 255).astype(np.uint8)
    rgb[..., 2] = (np.sin(pattern * np.pi) * 255).astype(np.uint8)
    frames.append(rgb)

output_image = torch.stack([torch.from_numpy(f).float() / 255 for f in frames], dim=0)

Line-by-Line Explanation

def recursive_pattern(x, y, t, depth=5):

Recursive function with depth parameter.

if depth == 0:
    return 0

Base case: stop recursion at depth 0.

pattern = np.sin(x * depth + t/5) * np.cos(y * depth + t/5)

Base pattern at current depth. Higher depth = higher frequency.

pattern += recursive_pattern(x/2, y/2, t, depth-1)

Recursive call with halved coordinates and reduced depth.

for i in range(X.shape[0]):
    for j in range(X.shape[1]):
        pattern[i, j] = recursive_pattern(X[i, j], Y[i, j], t)

Per-pixel recursion (slow but clear). For performance, consider vectorization.

Customization

More Depth

recursive_pattern(x, y, t, depth=8)  # More detail

Less Depth

recursive_pattern(x, y, t, depth=3)  # Faster, less detail

Different Base Pattern

pattern = np.sin(x * depth) + np.cos(y * depth)

Performance Notes

  • Per-pixel recursion in Python loops is very slow
  • Consider using memoization or vectorization
  • Reduce depth or resolution for real-time

Mathematical Insight

Self-Similarity

Each recursive level adds detail at half the scale:

  • Level 5: frequency 5
  • Level 4: frequency 2.5
  • Level 3: frequency 1.25
  • Level 2: frequency 0.625
  • Level 1: frequency 0.3125

This creates patterns that look similar at different zoom levels.

Recursion Depth

Depth controls the number of recursive calls:

  • Too shallow: insufficient detail
  • Too deep: exponential computational cost
  • Depth 5 is a good balance for most cases

Vectorized Version (Faster)

def recursive_vectorized(X, Y, t, depth=5):
    if depth == 0:
        return np.zeros_like(X)
    
    pattern = np.sin(X * depth + t/5) * np.cos(Y * depth + t/5)
    pattern += recursive_vectorized(X/2, Y/2, t, depth-1)
    
    return pattern

# Use this instead of per-pixel loop
pattern = recursive_vectorized(X, Y, t)