Welcome, guest | Sign In | My Account | Store | Cart

This based on another of my posted codes, titled "Spiral IFS Fractals".

Python, 42 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# Random Spiral Fractals
# FB36 - 20130929
import math
import random
from collections import deque
from PIL import Image
imgx = 512; imgy = 512
image = Image.new("RGB", (imgx, imgy))
pixels = image.load()
xa = -1.5; xb = 1.5; ya = -1.5; yb = 1.5 # view
n = random.randint(2, 9) # of spiral arms
a = 2.0 * math.pi / n # angle between arms
t = 2.0 * math.pi * random.random() # rotation angle of central copy
r1 = 0.1 * random.random() + 0.1 # scale factor of outmost copies of the spiral arms
r0 = 1.0 - r1 # scale factor of central copy
ts = math.sin(t) * r0; tc = math.cos(t) * r0
maxIt = 64 # max number of iterations allowed
for ky in range(imgy):
    print str(100 * ky / (imgy - 1)).zfill(3) + "%"
    for kx in range(imgx):
        x = float(kx) / (imgx - 1) * (xb - xa) + xa
        y = float(ky) / (imgy - 1) * (yb - ya) + ya
        queue = deque([])
        queue.append((x, y, 0))
        while len(queue) > 0: # iterate points until none left
            (x, y, i) = queue.popleft()
            # apply all (inverse) IFS transformations
            for k in range(n + 1): # n outmost copies + central copy
                if k == n: # central copy
                    # inverse rotation and scaling
                    xnew = (y + x * tc / ts) / (ts + tc * tc / ts)
                    ynew = (y - x / tc * ts) / (tc + ts / tc * ts)
                else: # outmost copies on the spiral arms
                    c = k * a # angle
                    # inverse scaling and translation
                    xnew = (x - math.cos(c)) / r1
                    ynew = (y - math.sin(c)) / r1
                if xnew >= xa and xnew <= xb and ynew >= ya and ynew <= yb:
                    if i + 1 == maxIt: break
                    queue.append((xnew, ynew, i + 1))
        pixels[kx, ky] = (i % 16 * 16 , i % 8 * 32, i % 4 * 64)
image.save("RandomSpiralFractal_" + str(n) + ".png", "PNG")

1 comment

FB36 (author) 8 years, 2 months ago  # | flag

Another version using IFS method:

# Random Spiral IFS Fractals
# FB - 20130928
import math
import random
from PIL import Image
imgx = 512; imgy = 512
image = Image.new("RGB", (imgx, imgy))
pixels = image.load()
maxIt = imgx * imgy
n = random.randint(2, 9)
a = 2.0 * math.pi / n
t = 2.0 * math.pi * random.random() # rotation angle of central copy
ts = math.sin(t); tc = math.cos(t)
r1 = 0.2 * random.random() + 0.1 # scale factor of outmost copies on the spiral arms
r0 = 1.0 - r1 # scale factor of central copy
p0 = r0 ** 2.0 / (n * r1 ** 2.0 + r0 ** 2.0) # probability of central copy
x = 0.0; y = 0.0
for i in range(maxIt):
    if random.random() < p0: # central copy
        x *= r0; y *= r0 # scaling
        # rotation
        h = x * tc - y * ts
        y = x * ts + y * tc
        x = h
    else: # outmost copies on the spiral arms
        k = random.randint(0, n - 1) # select an arm
        c = k * a # angle
        # scaling and translation
        x = x * r1 + math.cos(c)
        y = y * r1 + math.sin(c)
    kx = int((x + 2.0) / 4.0 * (imgx - 1))            
    ky = int((y + 2.0) / 4.0 * (imgy - 1))            
    pixels[kx, ky] = (255, 255, 255)
image.save("RandomSpiralIFSFractal.png", "PNG")
Created by FB36 on Sat, 14 Sep 2013 (MIT)
Python recipes (4591)
FB36's recipes (148)

Required Modules

Other Information and Tasks