josecelano / mandelbrot-orbits-rust Goto Github PK
View Code? Open in Web Editor NEWPlotting Mandelbrot Set periods using Rust language.
License: MIT License
Plotting Mandelbrot Set periods using Rust language.
License: MIT License
The escape_time
function calculates some interactions (255 right now):
fn escape_time(c: Complex<f64>, limit: usize) -> Option<usize> {
let mut z = Complex { re: 0.0, im: 0.0 };
for i in 0..limit {
if z.norm_sqr() > 4.0 {
return Some(i);
}
z = z * z + c;
}
None
}
But the is_period_p
starts again from z = 0.
fn is_period_p(z: Complex<f64>,c: Complex<f64>, n: usize) -> bool {
let max_period = 40;
let mut result = z.clone();
for _iter in 0..max_period {
let lambda = lambda(result, c, n);
let lambda_abs = lambda.abs();
if lambda_abs >= 1. {
return false;
}
result = phi(result, c);
}
true
}
as you can see in the render
function:
fn render(pixels: &mut [u8],
bounds: (usize, usize),
upper_left: Complex<f64>,
lower_right: Complex<f64>)
{
assert!(pixels.len() == bounds.0 * bounds.1);
for row in 0..bounds.1 {
for column in 0..bounds.0 {
// ...
pixels[row * bounds.0 + column] =
match escape_time(point, iteration_limit) {
None => {
// Mandelbrot Set point
// Calculate period
let z0 = Complex { re: 0.0, im: 0.0 };
let period = calculate_period(z0, point);
// ...
color
},
// Not a Mandelbrot Set point. Grayscale depending on the escape time
Some(count) => iteration_limit as u8 - count as u8,
};
}
}
}
Consider returning zn
from escape_time instead of starting from z0
.
It seems Newton's method can be used to calculate the value we need for the lambda function. What I call "Za". It seems to be much faster.
https://math.stackexchange.com/a/4503144/1082376
I think that value is a root of the nth composition that is the computation of n iteration of z²+c.
This could be an alternative implementation. We could keep both for the record or just remove the old one if this is better.
Publish a crate on https://crates.io/
I was looking for a way to show the test coverage and found the nextest crate.
Add test coverage: https://nexte.st/book/test-coverage.html
This is how it looks: https://github.com/nextest-rs/nextest/runs/7537588703?check_suite_focus=true#step:7:1
We are using ColorType::L8
. We could use RBG to apply other colours, but that would increase the size needed in memory to 3 bytes. And that would lower the maximum image size you can render with your computer because the full image is in memory before writing it into a file. In case you want a bigger image, you could always split it into parts.
In the book I'm following, there is an improvement by using threads:
https://github.com/ProgrammingRust/mandelbrot/tree/bands
There are different alternatives.
I would implement this once the image is generated correctly, or at least we merge this PR.
I want to generate an image like this:
Where the colour of the pixel depends on the point period.
@jeremy-rifkin has already implemented it in C++, so I can try to port his code to Rust.
The image
dependency has a transitive dependency with a vulnerability:
Cargo.lock (cargo)
==================
Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 1)
┌─────────────────┬────────────────┬──────────┬───────────────────┬───────────────┬──────────────────────────────────────────────────────────────┐
│ Library │ Vulnerability │ Severity │ Installed Version │ Fixed Version │ Title │
├─────────────────┼────────────────┼──────────┼───────────────────┼───────────────┼──────────────────────────────────────────────────────────────┤
│ crossbeam-deque │ CVE-2021-32810 │ CRITICAL │ 0.8.0 │ 0.7.4, 0.8.1 │ rust-crossbeam-deque: race condition may lead to double free │
│ │ │ │ │ │ https://avd.aquasec.com/nvd/cve-2021-32810 │
└─────────────────┴────────────────┴──────────┴───────────────────┴───────────────┴──────────────────────────────────────────────────────────────┘
├── image v0.24.3
│ ├── bytemuck v1.11.0
│ ├── byteorder v1.4.3
│ ├── color_quant v1.1.0
│ ├── exr v1.4.2
│ │ ├── bit_field v0.10.1
│ │ ├── deflate v1.0.0
│ │ │ └── adler32 v1.2.0
│ │ ├── flume v0.10.14
│ │ │ ├── futures-core v0.3.21
│ │ │ ├── futures-sink v0.3.21
│ │ │ ├── nanorand v0.7.0
│ │ │ │ └── getrandom v0.2.7
│ │ │ │ ├── cfg-if v1.0.0
│ │ │ │ └── libc v0.2.126
│ │ │ ├── pin-project v1.0.11
│ │ │ │ └── pin-project-internal v1.0.11 (proc-macro)
│ │ │ │ ├── proc-macro2 v1.0.42
│ │ │ │ │ └── unicode-ident v1.0.2
│ │ │ │ ├── quote v1.0.20
│ │ │ │ │ └── proc-macro2 v1.0.42 (*)
│ │ │ │ └── syn v1.0.98
│ │ │ │ ├── proc-macro2 v1.0.42 (*)
│ │ │ │ ├── quote v1.0.20 (*)
│ │ │ │ └── unicode-ident v1.0.2
│ │ │ └── spin v0.9.4
│ │ │ └── lock_api v0.4.6
│ │ │ └── scopeguard v1.1.0
│ │ ├── half v1.8.2
│ │ ├── inflate v0.4.5
│ │ │ └── adler32 v1.2.0
│ │ ├── lebe v0.5.1
│ │ ├── smallvec v1.9.0
│ │ └── threadpool v1.8.1
│ │ └── num_cpus v1.13.0
│ │ └── libc v0.2.126
│ ├── gif v0.11.4
│ │ ├── color_quant v1.1.0
│ │ └── weezl v0.1.7
│ ├── jpeg-decoder v0.2.6
│ │ └── rayon v1.5.1
│ │ ├── crossbeam-deque v0.8.0
│ │ │ ├── cfg-if v1.0.0
│ │ │ ├── crossbeam-epoch v0.9.5
│ │ │ │ ├── cfg-if v1.0.0
│ │ │ │ ├── crossbeam-utils v0.8.5
│ │ │ │ │ ├── cfg-if v1.0.0
│ │ │ │ │ └── lazy_static v1.4.0
│ │ │ │ ├── lazy_static v1.4.0
│ │ │ │ ├── memoffset v0.6.4
│ │ │ │ │ [build-dependencies]
│ │ │ │ │ └── autocfg v1.0.1
│ │ │ │ └── scopeguard v1.1.0
│ │ │ └── crossbeam-utils v0.8.5 (*)
│ │ ├── either v1.6.1
│ │ └── rayon-core v1.9.1
│ │ ├── crossbeam-channel v0.5.1
│ │ │ ├── cfg-if v1.0.0
│ │ │ └── crossbeam-utils v0.8.5 (*)
│ │ ├── crossbeam-deque v0.8.0 (*)
│ │ ├── crossbeam-utils v0.8.5 (*)
│ │ ├── lazy_static v1.4.0
│ │ └── num_cpus v1.13.0 (*)
│ │ [build-dependencies]
│ │ └── autocfg v1.0.1
I've opened an issue.
At the edge, some pixels are darker than they should. That's because the period is not calculated well, probably because the interactions are insufficient.
If we want to improve the artistic result without increasing the number of iterations. We can apply the direct formulas to detect periods 1 and 2 and adjust the colour.
We can add a new workflow to generate a sample image. The workflow could:
Convert this image in the README
into LaTeX formatted within Markdown.
Maybe it can be done once we have a good full and clear explanation.
Add file: .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "cargo" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "weekly
We could add more tests for these functions:
Using known values.
If we do not know any value, we can run @jeremy-rifkin 's implementation to generate some values.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.