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

This is a modification of code posted at http://code.activestate.com/recipes/577715/ (r3)

The original code produces a png image using the PIL module. It generates a Random 2D Slice of a 4D Mandelbrot Fractal.

This extends the program into 3D with Visual Python 5.4, running under Python 2.7.1

Changing vp_flag from 0 to 1 will restore program to original functionality. The program is interactive with keys q,w,e,r and x used to control visual points object.

Python, 188 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
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
## {{{ http://code.activestate.com/recipes/577715/ (r3)
# Random 2D Slice Of 4D Mandelbrot Fractal
# FB - 201105231
"""Random 2D Slice Of 4D Mandelbrot Fractal.
                          Modified by Symion 2011
    Now works with Visual Python v5.40.
    Produce 2D slice of 4D Mandelbrot Fractal and Map it in 3D!

Visual Python Controls:
    Click Left Mouse Key = Navigate
    Press Right Mouse Key = Spin
    Press Both Keys = Zoom
    q = Point size - 1
    w = Point size + 1
    e = Point shape + 1
    r = Scene Alignment
"""
vp_flag = 0

if vp_flag == 0:
    from visual import *
else:
    import random
    from math import *
    from PIL import Image
imgx = 512
imgy = 512
forge = 0
pcc = 0
pii = 0
psize = 3
pshape = 0

if vp_flag == 0:
    scene.width=imgx
    scene.height=imgy
    image = [points(size=psize, shape="square")]
    forward = vector(scene.forward)
    print "Number of Points objects: {0}".format(len(image))
else:
    image = Image.new("RGB", (imgx, imgy))
#
print __doc__
# drawing area (xa < xb & ya < yb)
xa = -2.0
xb = 2.0
ya = -2.0
yb = 2.0
maxIt = 32 # max number of iterations allowed
maxit = maxIt / 2.0
if True:
    # random rotation angles to convert 2d plane to 4d plane
    xy = random.random() * 2.0 * pi
    xz = random.random() * 2.0 * pi
    xw = random.random() * 2.0 * pi
    yz = random.random() * 2.0 * pi
    yw = random.random() * 2.0 * pi
    zw = random.random() * 2.0 * pi

else:
    # default rotation angles
    xy=1.3536589728
    xz=2.30808965705
    xw=3.50029464114
    yz=3.37449518258
    yw=4.23401560176
    zw=2.44695022478

sxy = sin(xy)
cxy = cos(xy)
sxz = sin(xz)
cxz = cos(xz)
sxw = sin(xw)
cxw = cos(xw)
syz = sin(yz)
cyz = cos(yz)
syw = sin(yw)
cyw = cos(yw)
szw = sin(zw)
czw = cos(zw)

origx = (xa + xb) / 2.0
origy = (ya + yb) / 2.0

for ky in range(imgy):
    b = ky * (yb - ya) / (imgy - 1)  + ya
    for kx in range(imgx):
        a = kx * (xb - xa) / (imgx - 1)  + xa
        x = a
        y = b
        z = 0 # c = 0
        w = 0 # d = 0
        # 4d rotation around center of the plane
        x = x - origx
        y = y - origy
        x0 = x * cxy - y * sxy
        y = x * sxy + y * cxy
        x = x0 # xy-plane rotation
        x0 = x * cxz - z * sxz
        z = x * sxz + z * cxz
        x = x0 # xz-plane rotation 
        x0 = x * cxw - z * sxw
        w = x * sxw + z * cxw
        x = x0 # xw-plane rotation
        y0 = y * cyz - z * syz
        z = y * syz + z * cyz
        y = y0 # yz-plane rotation
        y0 = y * cyw - w * syw
        w = y * syw + w * cyw
        y = y0 # yw-plane rotation
        z0 = z * czw - w * szw
        w = z * szw + w * czw
        z = z0 # zw-plane rotation
        x = x + origx
        y = y + origy
        if forge:
            for i in range(maxIt):
                # iteration using quaternion numbers
                x0 = x * x - y * y - z * z - w * w + a
                y = 2.0 * x * y + b
                z = 2.0 * x * z
                w = 2.0 * x * w
                x = x0
                s = x * x + y * y + z * z + w * w # 4d absolute value squared
                if s > 4.0:
                    break
        else:
            for i in range(maxIt):
                # iteration using hyper-complex numbers
                x0 = x * x - y * y - z * z - w * w + a
                y0 = 2.0 * x * y - 2.0 * z * w + b
                z0 = 2.0 * x * z - 2.0 * y * w
                w = 2.0 * x * w + 2.0 * z * y
                x = x0
                y = y0
                z = z0
                s = x * x + y * y + z * z + w * w # 4d absolute value squared
                if s > 4.0:
                    break
        pcc += i
        pii += 1
        if (i%maxIt) != 0:
            if vp_flag == 0:
                if len(image[-1].pos) > 9999:
                    image.append(points(size=psize, shape="square"))
                    print "Number of Points objects: {0}".format(len(image))
                c = (i/maxit, i/maxit, i/maxit)
                image[-1].append((kx-256, ky-256, i/maxit))
                image[-1].color[-1] = c
            else:
                image.putpixel((kx, ky), (i % 4 * 64, i % 8 * 32, i % 16 * 16))
if vp_flag == 0:
    scene.autoscale=False
    scene.range=mag(scene.mouse.camera)/sqrt(3)
    scene.visible = True
else:
    image.save("4D_Mandelbrot_Fractal.png", "PNG")
print "Finished!"
print "{0} / {1} = {2}".format(pcc, pii, pcc / pii)
mess = "Base Set:\nxy={0}, xz={1}, xw={2}, yz={3}, yw={4}, zw={5}"
print mess.format(xy, xz, xw, yz, yw, zw)
if vp_flag == 0:
    while 1:
        if scene.mouse.events>0:
            mk = scene.mouse.getevent()
            if mk.release == "left":
                scene.center = mk.pos
        elif scene.kb.keys:
            km = scene.kb.getkey()
            if km in ["x", "X"]:
                break
            elif km in ["w"]:
                psize = psize%50
                psize += 1
                for a in image:
                    a.size = psize
            elif km in ["q"]:
                psize -= 1
                if psize<1:
                    psize = 50
                for a in image:
                    a.size = psize
            elif km in ["e"]:
                pshape = (pshape+1)%2
                for a in image:
                    a.shape = ["square","round"][pshape]
            elif km in ["r"]:
                scene.forward = forward

Mapping fractals into 3D with visual python points object produces interesting topologies.