def accumulate_subpixels(offset_x, offset_y): nonlocal result x = np.arange(width, dtype='float64') + offset_x y = np.arange(height, dtype='float64') + offset_y x, y = np.meshgrid(x, y) x = (2 * x - width) * z y = (2 * y - height) * z x, y = x*c + y*s, y*c - x*s x += center_x y += center_y x_buf = ffi.cast("double*", x.ctypes.data) y_buf = ffi.cast("double*", y.ctypes.data) lib.mandelbrot_generic(x_buf, y_buf, width*height, numerator, denominator, max_iter, inside_cutoff, outside_offset, clip_outside, np.real(julia_c), np.imag(julia_c), julia) inside = x outside = y subpixel_image = color_map(inside, outside, inside_cutoff) lock.acquire() result += subpixel_image lock.release()
def basic_eval(q, a, b, c, max_iter, shape=None): if shape is None: for z in (q, a, b, c): if hasattr(z, 'shape'): if shape is None: shape = z.shape if shape == (): shape = z.shape # Upshape and make unique z = np.zeros(shape) q = q + z a = a + z b = b + z c = c + z result = z q_buf = ffi.cast("double*", q.ctypes.data) a_buf = ffi.cast("double*", a.ctypes.data) b_buf = ffi.cast("double*", b.ctypes.data) c_buf = ffi.cast("double*", c.ctypes.data) result_buf = ffi.cast("double*", result.ctypes.data) lib.smooth_julia(q_buf, a_buf, b_buf, c_buf, result_buf, max_iter, result.size) return result
def pow_quaternion_inplace(x, y, z, exponent): x_buf = ffi.cast("double*", x.ctypes.data) y_buf = ffi.cast("double*", y.ctypes.data) z_buf = ffi.cast("double*", z.ctypes.data) lib.pow_quaternion( x_buf, y_buf, z_buf, exponent, x.size ) return x, y, z
def buddhabulb_exposure(width, height, depth, center_x, center_y, center_z, zoom, rotation_theta, rotation_phi, rotation_gamma, exponent_theta, exponent_phi, exponent_r, num_samples, min_iter, max_iter, generator, num_threads=16, bailout=16, chunk_size=8192, julia=None): num_color_channels = 3 result = np.zeros((depth, height, width), dtype="uint64") result_buf = ffi.cast("unsigned long long*", result.ctypes.data) num_samples = int(round(num_samples / num_threads)) ct, st = np.cos(rotation_theta), np.sin(rotation_theta) cp, sp = np.cos(rotation_phi), np.sin(rotation_phi) cg, sg = np.cos(rotation_gamma), np.sin(rotation_gamma) dx = np.identity(3, dtype="double") dx = np.matmul(dx, [[ct, 0, st], [0, 1, 0], [-st, 0, ct]]) dx = np.matmul(dx, [[cp, sp, 0], [-sp, cp, 0], [0, 0, 1]]) dx = np.matmul(dx, [[1, 0, 0], [0, cg, sg], [0, -sg, cg]]) dx[0] *= 2**zoom * height dx[1] *= 2**zoom * height dx[2] *= 2**zoom * depth dx_buf = ffi.cast("double*", dx.ctypes.data) offset = np.matmul(dx, [center_x, center_y, center_z]) x0 = width*0.5 - offset[0] y0 = height*0.5 - offset[1] z0 = depth*0.5 - offset[2] def accumulate_samples(): remaining = num_samples while remaining: chunk = min(remaining, chunk_size) x_samples, y_samples, z_samples = generator(chunk) x_samples_buf = ffi.cast("double*", x_samples.ctypes.data) y_samples_buf = ffi.cast("double*", y_samples.ctypes.data) z_samples_buf = ffi.cast("double*", z_samples.ctypes.data) if julia is not None: cx_samples = 0*x_samples + julia[0] cy_samples = 0*y_samples + julia[1] cz_samples = 0*z_samples + julia[2] else: cx_samples = x_samples cy_samples = y_samples cz_samples = z_samples cx_samples_buf = ffi.cast("double*", cx_samples.ctypes.data) cy_samples_buf = ffi.cast("double*", cy_samples.ctypes.data) cz_samples_buf = ffi.cast("double*", cz_samples.ctypes.data) lib.buddhabulb(x_samples_buf, y_samples_buf, z_samples_buf, cx_samples_buf, cy_samples_buf, cz_samples_buf, chunk, result_buf, width, height, depth, x0, y0, z0, dx_buf, exponent_theta, exponent_phi, exponent_r, max_iter, min_iter, bailout) remaining -= chunk ts = [] for _ in range(num_threads): ts.append(Thread(target=accumulate_samples)) ts[-1].start() for t in ts: t.join() return result
def accumulate_subpixels(offset_x, offset_y): nonlocal result inside_arr = np.empty(height * width, dtype='int64') outside_arr = np.empty(height * width, dtype='float64') inside_buf = ffi.cast("long long*", inside_arr.ctypes.data) outside_buf = ffi.cast("double*", outside_arr.ctypes.data) lib.mandelbrot(inside_buf, outside_buf, width, height, offset_x, offset_y, x, y, zoom, int(exponent - 0.5), max_iter, inside_cutoff, clip_outside) subpixel_image = color_map(inside_arr.reshape(height, width), outside_arr.reshape(height, width), inside_cutoff) lock.acquire() result += subpixel_image lock.release()
def accumulate_samples(): remaining = num_samples while remaining: chunk = min(remaining, chunk_size) samples = generator(chunk) samples_buf = ffi.cast("double*", samples.ctypes.data) if julia: cs = samples*0j + julia_c else: cs = samples cs_buf = ffi.cast("double*", cs.ctypes.data) seed = np.random.randint(0, 1<<32); lib.buddhabrot(samples_buf, cs_buf, chunk, result_buf, width, height, x0, y0, dx00, dx01, dx10, dx11, numerator, denominator, max_iter, min_iter, bailout, seed) remaining -= chunk
def biaxial_julia(x, y, z, c0x, c0y, c1y, c1z, exponent0, exponent1, max_iter, shape=None): refs, bufs = bufferize(x, y, z, c0x, c0y, c1y, c1z) result = np.zeros(refs[0].shape) result_buf = ffi.cast("double*", result.ctypes.data) args = bufs + [result_buf, exponent0, exponent1, max_iter, result.size] lib.biaxial_julia(*args) return result
def mandelbulb(x, y, z, cx, cy, cz, exponent_theta, exponent_phi, exponent_r, max_iter, shape=None): if shape is None: for w in (x, y, z, cx, cy, cz): if hasattr(w, 'shape'): if shape is None: shape = w.shape if shape == (): shape = w.shape # Upshape and make unique w = np.zeros(shape) x = x + w y = y + w z = z + w cx = cx + w cy = cy + w cz = cz + w result = w x_buf = ffi.cast("double*", x.ctypes.data) y_buf = ffi.cast("double*", y.ctypes.data) z_buf = ffi.cast("double*", z.ctypes.data) cx_buf = ffi.cast("double*", cx.ctypes.data) cy_buf = ffi.cast("double*", cy.ctypes.data) cz_buf = ffi.cast("double*", cz.ctypes.data) result_buf = ffi.cast("double*", result.ctypes.data) lib.smooth_mandelbulb( x_buf, y_buf, z_buf, cx_buf, cy_buf, cz_buf, result_buf, exponent_theta, exponent_phi, exponent_r, max_iter, result.size ) return result
def accumulate_subpixels(offset_x, offset_y): nonlocal result x = np.arange(width, dtype='float64') + offset_x y = np.arange(height, dtype='float64') + offset_y x = x_scale * (2 * x - width) * zoom / height y = (2 * y - height) * zoom / height x, y = np.meshgrid(x, y) qw = center.w + x * cos(theta) + u_max * sin(theta) qx = center.x + u_max * cos(theta) - x * sin(theta) qy = center.y + y * cos(phi) + v_max * sin(phi) qz = center.z + v_max * cos(phi) - y * sin(phi) uw = sin(theta) * u_delta ux = cos(theta) * u_delta uy = 0 uz = 0 vw = 0 vx = 0 vy = sin(phi) * v_delta vz = cos(phi) * v_delta area = qw + 0 red = qx + 0 green = qy + 0 blue = qz + 0 qw_buf = ffi.cast("double*", area.ctypes.data) qx_buf = ffi.cast("double*", red.ctypes.data) qy_buf = ffi.cast("double*", green.ctypes.data) qz_buf = ffi.cast("double*", blue.ctypes.data) lib.julia(qw_buf, qx_buf, qy_buf, qz_buf, width * height, uw, ux, uy, uz, u_samples, vw, vx, vy, vz, v_samples, a.w, a.x, a.y, a.z, b.w, b.x, b.y, b.z, c.w, c.x, c.y, c.z, max_iter, pseudo_mandelbrot, coloring, bg_luminance, attenuation) subpixel_image = color_map(area, red, green, blue) lock.acquire() result += subpixel_image lock.release()
def pow3d(x, y, z, exponent_theta, exponent_phi, exponent_r, shape=None): if shape is None: for w in (x, y, z): if hasattr(w, 'shape'): if shape is None: shape = w.shape if shape == (): shape = w.shape # Upshape and make unique w = np.zeros(shape) x = x + w y = y + w z = z + w x_buf = ffi.cast("double*", x.ctypes.data) y_buf = ffi.cast("double*", y.ctypes.data) z_buf = ffi.cast("double*", z.ctypes.data) lib.pow3d( x_buf, y_buf, z_buf, exponent_theta, exponent_phi, exponent_r, x.size ) return x, y, z
def bufferize(*args, shape=None): if shape is None: for w in args: if hasattr(w, 'shape'): if shape is None: shape = w.shape if shape == (): shape = w.shape # Upshape and make unique w = np.zeros(shape) refs = [] results = [] for z in args: z = z + w z_buffer = ffi.cast("double*", z.ctypes.data) refs.append(z) results.append(z_buffer) return refs, results
def buddhabrot_exposure(width, height, center_x, center_y, zoom, rotation, numerator, denominator, num_samples, min_iter, max_iter, generator, num_threads=16, bailout=16, chunk_size=8192, julia_c=1j, julia=False): num_color_channels = 3 result = np.zeros((height, width), dtype="uint64") result_buf = ffi.cast("unsigned long long*", result.ctypes.data) num_samples = int(round(num_samples / num_threads)) c, s = np.cos(rotation), np.sin(rotation) z = 2**zoom * height dx00 = z*c dx11 = z*c dx01 = z*s dx10 = -z*s x0 = width*0.5 - dx00 * center_x - dx01 * center_y y0 = height*0.5 - dx10 * center_x - dx11 * center_y def accumulate_samples(): remaining = num_samples while remaining: chunk = min(remaining, chunk_size) samples = generator(chunk) samples_buf = ffi.cast("double*", samples.ctypes.data) if julia: cs = samples*0j + julia_c else: cs = samples cs_buf = ffi.cast("double*", cs.ctypes.data) seed = np.random.randint(0, 1<<32); lib.buddhabrot(samples_buf, cs_buf, chunk, result_buf, width, height, x0, y0, dx00, dx01, dx10, dx11, numerator, denominator, max_iter, min_iter, bailout, seed) remaining -= chunk ts = [] for _ in range(num_threads): ts.append(Thread(target=accumulate_samples)) ts[-1].start() for t in ts: t.join() return result
def accumulate_samples(): remaining = num_samples while remaining: chunk = min(remaining, chunk_size) x_samples, y_samples, z_samples = generator(chunk) x_samples_buf = ffi.cast("double*", x_samples.ctypes.data) y_samples_buf = ffi.cast("double*", y_samples.ctypes.data) z_samples_buf = ffi.cast("double*", z_samples.ctypes.data) if julia is not None: cx_samples = 0*x_samples + julia[0] cy_samples = 0*y_samples + julia[1] cz_samples = 0*z_samples + julia[2] else: cx_samples = x_samples cy_samples = y_samples cz_samples = z_samples cx_samples_buf = ffi.cast("double*", cx_samples.ctypes.data) cy_samples_buf = ffi.cast("double*", cy_samples.ctypes.data) cz_samples_buf = ffi.cast("double*", cz_samples.ctypes.data) lib.buddhabulb(x_samples_buf, y_samples_buf, z_samples_buf, cx_samples_buf, cy_samples_buf, cz_samples_buf, chunk, result_buf, width, height, depth, x0, y0, z0, dx_buf, exponent_theta, exponent_phi, exponent_r, max_iter, min_iter, bailout) remaining -= chunk