Skip to content

Commit b0e9d6b

Browse files
authored
Merge pull request #7 from jackyarndley/testing
Reorganised repository and deleted unused files
2 parents 9f161a2 + a8ae8cc commit b0e9d6b

18 files changed

+213
-949
lines changed

Cargo.lock

Lines changed: 0 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ pbr = "1.0.2"
1212
rayon = "1.3.0"
1313
packed_simd = "0.3.3"
1414
rug = "1.7.0"
15-
float-extended = { path = "../rust-float-extended/" }
1615

1716
#Additional commands that can improve performance (maybe by around 5-10%)
1817
#[profile.release]

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
![image](output.png)
1+
![image](output2.png)
22

33
# rust-fractal
44
A mandelbrot fractal image generator featuring perturbation theory. A high precision reference point is iterated at arbitrary precision and the differences from this are calculated in machine precision. This allows for a large speedup in image generation specifically at high zoom levels. This generator features:

output.png

-82.5 KB
Loading

output2.png

-4.65 MB
Binary file not shown.

render.png

5.61 MB
Loading

src/bin/main.rs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
use std::time::Instant;
2-
use rust_fractal::renderer2::FractalRenderer;
2+
use rust_fractal::renderer::FractalRenderer;
33

44
fn main() {
55
println!("Mandelbrot Renderer");
6-
// let center = (
7-
// "-1.99996619445037030418434688506350579675531241540724851511761922944801584242342684381376129778868913812287046406560949864353810575744772166485672496092803920095332",
8-
// "+0.00000000000000000000000000000000030013824367909383240724973039775924987346831190773335270174257280120474975614823581185647299288414075519224186504978181625478529");
9-
// let zoom = 2.3620330788506154104770818136626E157;
6+
let center = (
7+
"-1.99996619445037030418434688506350579675531241540724851511761922944801584242342684381376129778868913812287046406560949864353810575744772166485672496092803920095332",
8+
"+0.00000000000000000000000000000000030013824367909383240724973039775924987346831190773335270174257280120474975614823581185647299288414075519224186504978181625478529");
9+
let zoom = 2.3620330788506154104770818136626E157;
1010

1111
// let center = (
1212
// "0.0",
@@ -48,10 +48,10 @@ fn main() {
4848
// "-0.000000000000000000000000000000000300138243679093832407249730397759249873468311907733352701742572801204749756148235811856472992884140755192241865049781816254785289455481579902975133989545509287024987599289178526901586954397865");
4949
// let zoom = 8.80307862787E167;
5050

51-
let center = (
52-
"-1.479796270901760024425279934770411525645551054432599517909807632824286254403907594526888466099962805022975196472549771681831234491695559852583955204986197762293872769474806903995564259040667568599770094383157857518790853771783314763231302599999999999999999999999998",
53-
"-0.001199443952813447746281973233374468444560314114132538362037569205657422216739564521471119107626453330996365067987088146663639996715939831819152248618042255824652268918299630897525386638029428706473919823922522752497780934312003352081931299999999999999999999999998");
54-
let zoom = 3.27799999998E235;
51+
// let center = (
52+
// "-1.479796270901760024425279934770411525645551054432599517909807632824286254403907594526888466099962805022975196472549771681831234491695559852583955204986197762293872769474806903995564259040667568599770094383157857518790853771783314763231302599999999999999999999999998",
53+
// "-0.001199443952813447746281973233374468444560314114132538362037569205657422216739564521471119107626453330996365067987088146663639996715939831819152248618042255824652268918299630897525386638029428706473919823922522752497780934312003352081931299999999999999999999999998");
54+
// let zoom = 3.27799999998E235;
5555

5656
// let center = (
5757
// "-0.74962449737876168207862620426836138684529527812364025754481571424558286479672801698750203976779135608148687747196595174858125388297577788573082753210469806739721377901297451172624762450940529814713048377873612297220313016947039287469999999999999999",
@@ -63,10 +63,9 @@ fn main() {
6363
1000,
6464
1000,
6565
zoom,
66-
150000,
66+
100000,
6767
center.0,
6868
center.1,
69-
1000,
7069
0.001,
7170
false,
7271
64

src/colouring.rs

Lines changed: 80 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ use crate::util::PixelData;
33

44
pub enum ColourMethod {
55
Iteration,
6-
// IterationSquareRoot,
7-
// Histogram
6+
IterationSquareRoot,
7+
Histogram,
8+
Distance
89
}
910

1011
impl ColourMethod {
11-
pub fn run(&self, pixels: &Vec<PixelData>, image: &mut Image, maximum_iterations: usize) {
12+
pub fn run(&self, pixel_data: &Vec<PixelData>, image: &mut Image, maximum_iteration: usize, delta_pixel: f64) {
1213
// Palette is temporarily here
1314
let mut colours = Vec::new();
1415

@@ -56,10 +57,12 @@ impl ColourMethod {
5657

5758
match self {
5859
ColourMethod::Iteration => {
59-
for pixel in pixels {
60-
let (red, green, blue) = if pixel.glitched && image.display_glitches {
60+
// No smooth colouring at the moment
61+
62+
for pixel in pixel_data {
63+
let (r, g, b) = if pixel.glitched && image.display_glitches {
6164
(255, 0, 0)
62-
} else if pixel.iteration >= maximum_iterations {
65+
} else if pixel.iteration >= maximum_iteration {
6366
(0, 0, 0)
6467
} else {
6568
// 0.1656
@@ -70,87 +73,79 @@ impl ColourMethod {
7073
(colour.0 as u8, colour.1 as u8, colour.2 as u8)
7174
};
7275

73-
image.plot(pixel.image_x, pixel.image_y, red, green, blue);
76+
image.plot(pixel.image_x, pixel.image_y, r, g, b);
7477
}
7578
},
76-
// ColourMethod::IterationSquareRoot => {
77-
// for point in points {
78-
// let index = point.index;
79-
//
80-
// if point.glitched && display_glitches {
81-
// image[3 * index] = 255u8;
82-
// image[3 * index + 1] = 0u8;
83-
// image[3 * index + 2] = 0u8;
84-
// } else if point.iterations >= maximum_iterations {
85-
// image[3 * index] = 0u8;
86-
// image[3 * index + 1] = 0u8;
87-
// image[3 * index + 2] = 0u8;
88-
// } else {
89-
// let hue = 1600.0 * (point.iterations as f32 + point.smooth).sqrt() % 8192.0;
90-
//
91-
// let colour = colours[(hue.floor() as usize) % 8192];
92-
// let colour2 = colours[(hue.floor() as usize + 1) % 8192];
93-
//
94-
// let red = (colour.0 + ((colour2.0 - colour.0) * hue.fract())) as u8;
95-
// let green = (colour.1 + ((colour2.1 - colour.1) * hue.fract())) as u8;
96-
// let blue = (colour.2 + ((colour2.2 - colour.2) * hue.fract())) as u8;
97-
//
98-
// image[3 * index] = red;
99-
// image[3 * index + 1] = green;
100-
// image[3 * index + 2] = blue;
101-
// }
102-
// }
103-
// },
104-
// ColourMethod::Histogram => {
105-
// let mut iteration_counts = vec![0usize; maximum_iterations + 1];
106-
//
107-
// for point in points {
108-
// iteration_counts[point.iterations as usize] += 1
109-
// }
110-
//
111-
// for i in 1..iteration_counts.len() {
112-
// iteration_counts[i] += iteration_counts[i - 1];
113-
// }
114-
//
115-
// let total = iteration_counts[maximum_iterations - 1];
116-
//
117-
// for point in points {
118-
// let index = point.index;
119-
//
120-
// if point.glitched && display_glitches {
121-
// image[3 * index] = 255u8;
122-
// image[3 * index + 1] = 0u8;
123-
// image[3 * index + 2] = 0u8;
124-
// } else if point.iterations >= maximum_iterations {
125-
// image[3 * index] = 0u8;
126-
// image[3 * index + 1] = 0u8;
127-
// image[3 * index + 2] = 0u8;
128-
// } else {
129-
// let factor = if point.smooth == std::f32::NAN || point.iterations as f32 + point.smooth < 0.0 {
130-
// point.iterations as f32
131-
// } else {
132-
// point.iterations as f32 + point.smooth
133-
// };
134-
//
135-
// let v1 = iteration_counts[factor as usize] as f32 / total as f32;
136-
// let v2 = iteration_counts[factor as usize + 1] as f32 / total as f32;
137-
//
138-
// // the hue is used to smooth the histogram bins. The hue is in the range 0.0-1.0
139-
// let hue = (v1 + (v2 - v1) * factor.fract()) * 8192.0;
140-
//
141-
// let colour = colours[hue.floor() as usize % 8192];
142-
// let colour2 = colours[(hue.floor() as usize + 1) % 8192];
143-
//
144-
// let red = (colour.0 + ((colour2.0 - colour.0) * factor.fract())) as u8;
145-
// let green = (colour.1 + ((colour2.1 - colour.1) * factor.fract())) as u8;
146-
// let blue = (colour.2 + ((colour2.2 - colour.2) * factor.fract())) as u8;
147-
//
148-
// image[3 * index] = red;
149-
// image[3 * index + 1] = green;
150-
// image[3 * index + 2] = blue;
151-
// }
152-
// }
153-
// }
79+
ColourMethod::IterationSquareRoot => {
80+
for pixel in pixel_data {
81+
let (r, g, b) = if pixel.glitched && image.display_glitches {
82+
(255, 0, 0)
83+
} else if pixel.iteration >= maximum_iteration {
84+
(0, 0, 0)
85+
} else {
86+
// 0.1656
87+
let hue = (0.1656 * pixel.iteration as f64).sqrt() as usize % 8192;
88+
89+
let colour = colours[hue];
90+
91+
(colour.0 as u8, colour.1 as u8, colour.2 as u8)
92+
};
93+
94+
image.plot(pixel.image_x, pixel.image_y, r, g, b);
95+
}
96+
},
97+
ColourMethod::Histogram => {
98+
let mut iteration_counts = vec![0usize; maximum_iteration + 2];
99+
100+
for pixel in pixel_data {
101+
iteration_counts[pixel.iteration as usize] += 1
102+
}
103+
104+
for i in 1..iteration_counts.len() {
105+
iteration_counts[i] += iteration_counts[i - 1];
106+
}
107+
108+
// Don't count the pixels that are inside the set
109+
let total = iteration_counts[maximum_iteration - 1];
110+
111+
112+
for pixel in pixel_data {
113+
let (r, g, b) = if pixel.glitched && image.display_glitches {
114+
(255, 0, 0)
115+
} else if pixel.iteration >= maximum_iteration {
116+
(0, 0, 0)
117+
} else {
118+
let v1 = iteration_counts[pixel.iteration] as f32 / total as f32;
119+
120+
// the hue is used to smooth the histogram bins. The hue is in the range 0.0-1.0
121+
let hue = (v1 * 8192.0) as usize;
122+
123+
let colour = colours[hue % 8192];
124+
125+
(colour.0 as u8, colour.1 as u8, colour.2 as u8)
126+
};
127+
128+
image.plot(pixel.image_x, pixel.image_y, r, g, b);
129+
}
130+
},
131+
ColourMethod::Distance => {
132+
// At the moment distance has a white-black gradient
133+
for pixel in pixel_data {
134+
let (r, g, b) = if pixel.glitched && image.display_glitches {
135+
(255, 0, 0)
136+
} else {
137+
if pixel.escaped {
138+
let de = 2.0 * pixel.delta_current.norm() * pixel.delta_current.norm().ln() / pixel.derivative_current.norm();
139+
let out = (255.0 * (de / delta_pixel).tanh()) as u8;
140+
(out, out, out)
141+
} else {
142+
(0, 0, 0)
143+
}
144+
};
145+
146+
image.plot(pixel.image_x, pixel.image_y, r, g, b);
147+
}
148+
}
154149
}
155150
}
156151
}

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// pub mod renderer;
2-
pub mod renderer2;
2+
pub mod renderer;
33
pub mod util;
44
pub mod colouring;
55
pub mod math;

src/math/perturbation.rs

Lines changed: 2 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,12 @@
11
use crate::math::reference::Reference;
2-
use crate::util::{ComplexFixed, PixelData};
3-
use crate::util::complex_vector::ComplexVector;
2+
use crate::util::PixelData;
43

54
use rayon::prelude::*;
6-
use pbr::{ProgressBar, MultiBar};
7-
use std::sync::Arc;
85

9-
pub struct Perturbation {
10-
}
6+
pub struct Perturbation {}
117

128
impl Perturbation {
139
pub fn iterate(pixel_data: &mut Vec<PixelData>, reference: &Reference, maximum_iteration: usize) {
14-
// let mut packets = Vec::new();
15-
16-
// TODO non 4x image
17-
// for i in (0..self.image_x.len()).step_by(4) {
18-
// packets.push(
19-
// PerturbationData {
20-
// iteration: u64x4::splat(self.iteration[0] as u64),
21-
// delta_reference: ComplexVector::new2(&[self.delta_reference[i], self.delta_reference[i + 1], self.delta_reference[i + 2], self.delta_reference[i + 3]]),
22-
// delta_current: ComplexVector::new2(&[self.delta_current[i], self.delta_current[i + 1], self.delta_current[i + 2], self.delta_current[i + 3]]),
23-
// derivative_current: ComplexVector::new2(&[self.derivative_current[i], self.derivative_current[i + 1], self.derivative_current[i + 2], self.derivative_current[i + 3]]),
24-
// glitched: m64x4::splat(false),
25-
// escaped: m64x4::splat(false)
26-
// }
27-
// );
28-
// }
29-
//
30-
// packets.par_chunks_mut(1)
31-
// .for_each(|packet| {
32-
// // temporary - the number of iterations should be the same in all cases after the series approximation
33-
// for iteration in self.iteration[0]..maximum_iteration {
34-
// let z = packet[0].delta_current + ComplexVector::<f64x4>::splat(reference.z_reference[(iteration - reference.start_iteration)]);
35-
// let z_norm = z.norm_sqr();
36-
//
37-
// packet[0].escaped = packet[0].escaped.select(m64x4::splat(true), z_norm.ge(f64x4::splat(65536.0)));
38-
// packet[0].glitched = packet[0].glitched.select(m64x4::splat(true), z_norm.le(f64x4::splat(reference.z_tolerance[(iteration - reference.start_iteration)])));
39-
//
40-
// packet[0].escaped |= packet[0].glitched;
41-
//
42-
// if packet[0].escaped.all() {
43-
// break;
44-
// }
45-
//
46-
// packet[0].derivative_current = z * packet[0].derivative_current * f64x4::splat(2.0) + ComplexVector::<f64x4>::splat(ComplexFixed::new(1.0, 0.0));
47-
// packet[0].delta_current = ComplexVector::<f64x4>::splat(2.0 * reference.z_reference[(iteration - reference.start_iteration)]) * packet[0].delta_current + packet[0].delta_current * packet[0].delta_current + packet[0].delta_reference;
48-
// packet[0].iteration += packet[0].escaped.select(u64x4::splat(0), u64x4::splat(1));
49-
// }
50-
// });
51-
//
52-
// for i in (0..self.image_x.len()).step_by(4) {
53-
// for j in 0..4 {
54-
// self.iteration[i + j] = packets[i / 4].iteration.extract(j) as usize;
55-
// self.escaped[i + j] = packets[i / 4].escaped.extract(j);
56-
// self.glitched[i + j] = packets[i / 4].glitched.extract(j);
57-
// self.derivative_current[i + j] = ComplexFixed::new(packets[i / 4].derivative_current.re.extract(j), packets[i / 4].derivative_current.im.extract(j));
58-
// self.delta_current[i + j] = ComplexFixed::new(packets[i / 4].delta_current.re.extract(j), packets[i / 4].delta_current.im.extract(j));
59-
// }
60-
// }
61-
6210
pixel_data.par_chunks_mut(1)
6311
.for_each(|pixel_data| {
6412
for packet in pixel_data {

0 commit comments

Comments
 (0)