[−][src]Crate julia_set
Julia set boundary computation and rendering.
Theory
Informally, the Julia set for a complex-valued function f
(in Rust terms,
fn(Complex32) -> Complex32
) is a set of complex points for which an infinitely small
perturbation can lead to drastic changes in the sequence of iterated function applications
(that is, f(z)
, f(f(z))
, f(f(f(z)))
and so on).
For many functions f
, the iterated sequence may tend to infinity. Hence, the
commonly used computational way to render the Julia set boundary is as follows:
- For each complex value
z
within a rectangular area, perform steps 2-3. - Compute the minimum iteration
0 < i <= MAX_I
such that|f(f(f(...(z)))| > R
. Here,f
is appliedi
times;R
is a positive real-valued constant (the infinity distance);MAX_I
is a positive integer constant (maximum iteration count). - Associate
z
with a color depending oni
. For example,i == 1
may be rendered as black,i == MAX_I
as white, and values between it may get the corresponding shades of gray. - Render the rectangular area as a (two-dimensional) image, with each pixel corresponding
to a separate value of
z
.
This is exactly the way Julia set rendering is implemented in this crate.
Backends
The crate supports several computational Backend
s.
Backend | Crate feature | Hardware | Crate dep(s) |
---|---|---|---|
OpenCl | opencl_backend | GPU, CPU | ocl |
Vulkan | vulkan_backend | GPU | vulkano , shaderc |
Cpu | cpu_backend | CPU | rayon |
Cpu | dyn_cpu_backend | CPU | rayon |
None of the backends are on by default. A backend can be enabled by switching
on the corresponding crate feature. dyn_cpu_backend
requires cpu_backend
internally.
All backends except for cpu_backend
require parsing the complex-valued Function
from
a string presentation, e.g., "z * z - 0.4i"
. The arithmetic-parser
crate is used for this
purpose. For cpu_backend
, the function is defined directly in Rust.
For efficiency and modularity, a Backend
creates a program for each function.
(In case of OpenCL, a program is a kernel, and in Vulkan a program is a compute shader.)
The program can then be Render
ed with various Params
.
Backends targeting GPUs (i.e., OpenCl
and Vulkan
) should be much faster than CPU-based
backends. Indeed, the rendering task is embarrassingly parallel (could be performed
independently for each point).
Examples
Using Rust function definition with cpu_backend
:
use julia_set::{Backend, Cpu, Params, Render}; use num_complex::Complex32; let program = Cpu.create_program(|z: Complex32| z * z + Complex32::new(-0.4, 0.5))?; let render_params = Params::new([50, 50], 4.0).with_infinity_distance(5.0); let image = program.render(&render_params)?; // Do something with the image...
Using interpreted function definition with dyn_cpu_backend
:
use julia_set::{Backend, Cpu, Function, Params, Render}; use num_complex::Complex32; let function: Function = "z * z - 0.4 + 0.5i".parse()?; let program = Cpu.create_program(&function)?; let render_params = Params::new([50, 50], 4.0).with_infinity_distance(5.0); let image = program.render(&render_params)?; // Do something with the image...
Modules
transform | Post-processing transforms on Julia set images. |
Structs
Cpu | cpu_backend Backend that uses CPU for computations. |
CpuProgram | cpu_backend Programs output by the |
FnError | dyn_cpu_backend or opencl_backend or vulkan_backend Error associated with creating a |
Function | dyn_cpu_backend or opencl_backend or vulkan_backend Parsed complex-valued function of a single variable. |
OpenCl | opencl_backend Backend based on OpenCL. |
OpenClProgram | opencl_backend Program produced by the |
Params | Julia set rendering parameters. |
Vulkan | vulkan_backend Backend based on Vulkan. |
VulkanProgram | vulkan_backend Program produced by the |
Traits
Backend | Backend capable of converting an input (the type parameter) into a program. The program
then can be used to |
ComputePoint | cpu_backend Complex-valued function of a single variable. |
Render | Program for a specific |
Type Definitions
ImageBuffer | Image buffer output by a |