Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Chris M. Thomasson 7/29/2016
- # N-Ary Reverse Julia Set Renderer
- import math;
- import random;
- import copy; # for non-mutable aspects of classes
- #import os;
- from PIL import Image;
- # Complex Absolute Value
- def cabs(z):
- return math.sqrt(z.real**2 + z.imag**2);
- # Complex Argument
- def carg(z):
- return math.atan2(z.imag, z.real);
- # Complex Argument Range [0...PI2]
- def cargr(z):
- a = math.atan2(z.imag, z.real);
- if (a < 0): a += math.pi * 2;
- return a;
- # Complex Roots
- def croots(z, p):
- l = cabs(z);
- s = l**(1.0 / p);
- a = carg(z) / p;
- n = int(math.ceil(math.fabs(p)));
- astep = (math.pi * 2.0) / p;
- result = [];
- for i in range(n):
- r = complex(math.cos(a + astep * i) * s,
- math.sin(a + astep * i) * s);
- result.append(r);
- return result;
- # 2d Axes
- class ct_axes_2d:
- def __init__(self, xmin, xmax, ymin, ymax):
- self.xmin = xmin;
- self.xmax = xmax;
- self.ymin = ymin;
- self.ymax = ymax;
- def __repr__(self):
- return "(%s, %s, %s, %s)" % (self.xmin, self.xmax, self.ymin, self.ymax)
- def __str__(self): return self.__repr__();
- def width(self): return self.xmax - self.xmin;
- def height(self): return self.ymax - self.ymin;
- # 2d Plane
- class ct_plane_2d:
- def __init__(self, width, height, axes):
- self.axes = copy.copy(axes);
- self.width = width;
- self.height = height;
- self.xstep = self.axes.width() / width;
- self.ystep = self.axes.height() / height;
- self.aratio = height / width;
- def __repr__(self):
- return "(%s, %s, %s, %s, %s, %s)" % (self.axes,
- self.width, self.height,
- self.xstep, self.ystep,
- self.aratio);
- def __str__(self): return self.__repr__();
- def project_to(self, p):
- x = math.floor((p.real - self.axes.xmin) / self.xstep * self.aratio);
- y = math.floor((self.axes.ymax - p.imag) / self.ystep);
- return complex(x, y);
- # Secret Key
- class ct_skey:
- def __init__(self, c, p):
- self.c = c;
- self.p = p;
- def __repr__(self):
- return "(%s, %s)" % (self.c, self.p);
- def __str__(self): return self.__repr__();
- # Reverse Julia Fractal
- class ct_rjulia:
- def __init__(self, plane):
- self.plane = copy.copy(plane);
- self.image = Image.new("RGB", (plane.width, plane.height));
- self.pixels = self.image.load();
- def __repr__(self):
- return "(%s)" % (self.plane);
- def __str__(self): return self.__repr__();
- def save(self, fname):
- self.image.save(fname, "BMP");
- def set_pixel(self, p, c):
- if (p.real < 0 or p.real >= self.plane.width or
- p.imag < 0 or p.imag >= self.plane.height):
- return False;
- self.pixels[p.real, p.imag] = c;
- return True;
- def set_point(self, p, c):
- pp = self.plane.project_to(p);
- return self.set_pixel(pp, c);
- def plot(self, skey, z, n):
- for i in range(n):
- r = croots(z - skey.c, skey.p);
- for p in r: self.set_point(p, (255, 255, 255));
- print("ct_rjulia::plot(%s of %s)\r" % (i, n), end="");
- z = r[random.randint(0, len(r) - 1)];
- print("");
- # Main Program
- rfrac = ct_rjulia(ct_plane_2d(640, 640, ct_axes_2d(-2, 2, -2, 2)));
- skey = ct_skey((-.75+.09j), 2.0);
- print("rfrac:%s" % (rfrac));
- print("skey:%s" % (skey));
- rfrac.plot(skey, (0+0j), 12048);
- rfrac.save("output.bmp");
- #os.system("mspaint output.bmp");
Add Comment
Please, Sign In to add comment