| Crates.io | space-filling |
| lib.rs | space-filling |
| version | 0.4.0 |
| created_at | 2021-09-15 08:51:20.42315+00 |
| updated_at | 2023-06-14 20:43:10.386559+00 |
| description | Generalized 2D space filling |
| homepage | |
| repository | https://github.com/FredericaBernkastel/space-filling |
| max_upload_size | |
| id | 451707 |
| size | 112,665 |
Note: this is a subject of ongoing research, no stability guarantees are made.
You can read this paper for introduction:
Paul Bourke - Random space filling of the plane (2011).
However, the provided search algorithm for the next location is inefficient,
and offers very limited control over the distribution[1].
In this work, I present two solvers for the following equation:
sdfn are signed distance functions (primitives), by aggregate minima forming together a complex distance field - further denoted "SDF".
The goal of algorithm lies in finding a safe domain, guaranteed to not intersect with any shapes. A generic and parallel interface was implemented. Currently supported:
SDF is stored as a discrete bitmap, with memory layout reminiscent of z-order curve. Solver is guaranteed to always find global maxima, but increasing precision requires quadratic memory.
A paper "Adaptively Sampled Distance Fields" (doi:10.1145/344779.344899) offered an idea of reducing memory consumption, however it was very elaborate to not include any hints for a practical implementation. The only one being - using polynomial approximations for every node of the k-d tree; however, current work takes a different path - by storing function primitives themselves in each node (bucket). Redundant primitive elimination within a bucket was performed using interior-point method.
ADF itself implements SDF trait, allowing for complex fields composed of millions of primitives to be sampled efficiently — as opposed to computing it directly — with quadratic complexity in nature.
However, primitive elimination is not yet perfect. An elimination algorithm which is both precise and fast enough will be a subject of further theoretical research.
Once the representation is obtained, the role of optimizer takes place. For practical purposes, gradient descent with exponential convergence has been chosen — making GD-ADF a local maxima algorithm; as described by following equation:
Since by definition, first order derivative of distance field is constant, only direction of the gradient is considered — eliminating a number of issues with both GD/IPM; and as a bonus, rendering them to be no longer dependent on the field magnitude directly.
Unlike Argmax2D, GD-ADF offers 10-100x memory reduction, as well as continuous, exact field representation. Various speed tradeoffs are provided, including both single and double float precision.
You can run examples with following command:
cargo run --release --features "drawing" --example <example name>
You can add -- -C target-cpu=native at the command end to further improve the speed.
01_fractal_distribution
Each subsequent circle is inserted at the maxima of distance field.

02_random_distribution
Given (xy, magnitude) of the maxima, a new random circle is inserted within a domain of radius magnitude and center xy.

03_embedded
A distribution embedded in a distribution.

04_polymorphic
Showcasing:
05_image_dataset
Display over 100'000 images.
Run with cargo run --release --features "drawing" --example image_dataset -- "<image folder>" -C target-cpu=native

06_custom_primitive
A user-defined primitive.

In src/legacy you can find numeruos algorithms which are worth re-exploring, including quadtree and GPU implementations.
Once above are done, I will use this library for my next project "Gallery of Babel".
[1]: J. Shier, "A Million-Circle Fractal": https://www.d.umn.edu/~ddunham/circlepat.html
«...Run time was 14.7 hours.»