summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md5
-rw-r--r--Cargo.toml2
-rw-r--r--source/benoit/benoit/application/colour.rs13
-rw-r--r--source/benoit/benoit/application/draw.rs9
-rw-r--r--source/benoit/benoit/application/render_row.rs68
5 files changed, 61 insertions, 36 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 514d715..36ad036 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+# 20
+
+* Optimise renderer
+* Update commenting
+
# 1↋
* Make configuration support more precise numbers (must be parsed as strings now)
diff --git a/Cargo.toml b/Cargo.toml
index b5b7473..e3039fb 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "benoit"
-version = "0.23.0"
+version = "0.24.0"
authors = ["Gabriel Bjørnager Jensen"]
edition = "2021"
description = "Mandelbrot renderer."
diff --git a/source/benoit/benoit/application/colour.rs b/source/benoit/benoit/application/colour.rs
index db7e467..c9cf507 100644
--- a/source/benoit/benoit/application/colour.rs
+++ b/source/benoit/benoit/application/colour.rs
@@ -26,7 +26,6 @@ use crate::benoit::application::Application;
impl Application {
pub fn colour(&self, buffer: &mut [u8], data: &[u32]) {
let canvas_size = self.canvas_height * self.canvas_width;
-
for pixel in 0x0..canvas_size {
let iteration_count = data[pixel as usize];
@@ -40,15 +39,19 @@ impl Application {
}) * 2.0
};
- let colour: u8 = if iteration_count != self.maximum_iteration_count {
+ let value: u8 = if iteration_count != self.maximum_iteration_count {
(factor * 255.0).round() as u8
} else {
0x0
};
- buffer[pixel as usize * 0x3] = colour;
- buffer[pixel as usize * 0x3 + 0x1] = colour;
- buffer[pixel as usize * 0x3 + 0x2] = colour;
+ let red = value;
+ let green = value;
+ let blue = value;
+
+ buffer[pixel as usize * 0x3] = red;
+ buffer[pixel as usize * 0x3 + 0x1] = green;
+ buffer[pixel as usize * 0x3 + 0x2] = blue;
}
}
}
diff --git a/source/benoit/benoit/application/draw.rs b/source/benoit/benoit/application/draw.rs
index 1bc22c3..715b3da 100644
--- a/source/benoit/benoit/application/draw.rs
+++ b/source/benoit/benoit/application/draw.rs
@@ -39,9 +39,14 @@ impl Application {
let y = pixel as u32 / self.canvas_width;
let x = pixel as u32 - y * self.canvas_width;
- let value = image[pixel as usize * 0x3];
+ let colour = {
+ let red = image[pixel as usize * 0x3];
+ let green = image[pixel as usize * 0x3 + 0x1];
+ let blue = image[pixel as usize * 0x3 + 0x2];
+
+ Color::RGB(red, green, blue)
+ };
- let colour = Color::RGB(value, value, value);
self.video.as_mut().unwrap().canvas.set_draw_color(colour);
let rectangle = Rect::new(
diff --git a/source/benoit/benoit/application/render_row.rs b/source/benoit/benoit/application/render_row.rs
index f47f166..757e4d3 100644
--- a/source/benoit/benoit/application/render_row.rs
+++ b/source/benoit/benoit/application/render_row.rs
@@ -27,72 +27,84 @@ use crate::benoit::application::Application;
extern crate rug;
use rug::Float;
-use std::ops::{AddAssign, DivAssign, MulAssign};
impl Application {
pub fn render_row(data: &mut [u32], y: u32, canvas_width: u32, canvas_height: u32, center_real: Float, center_imaginary: Float, zoom: Float, maximum_iteration_count: u32) {
- let two = Float::with_val(PRECISION, 2.0);
-
for x in 0x0..canvas_width {
let canvas_width = Float::with_val(PRECISION, canvas_width);
let canvas_height = Float::with_val(PRECISION, canvas_height);
- //let ca = Float::with_val(PRECISION, (&x - &canvas_width / 2.0) / &canvas_width * 4.0 / &zoom + &center_real);
- //let cb = Float::with_val(PRECISION, (&y - &canvas_height / 2.0) / &canvas_height * 4.0 / &zoom + &center_imaginary);
-
let x_float = Float::with_val(PRECISION, x);
let y_float = Float::with_val(PRECISION, y);
// Re(c) = (x-canvas_width/2)/canvas_width*4/zoom+Re(z)
-
let ca = {
let tmp0 = Float::with_val(PRECISION, &canvas_width / 2.0);
let mut ca = Float::with_val(PRECISION, &x_float - &tmp0);
- ca.div_assign(&canvas_width);
- ca.mul_assign(4.0);
- ca.div_assign(&zoom);
- ca.add_assign(&center_real);
+ ca /= &canvas_width;
+ ca *= 4.0;
+ ca /= &zoom;
+ ca += &center_real;
ca
};
// Im(c) = (x-canvas_height/2)/canvas_height*4/zoom+Im(z)
-
let cb = {
let tmp0 = Float::with_val(PRECISION, &canvas_height / 2.0);
let mut cb = Float::with_val(PRECISION, &y_float - &tmp0);
- cb.div_assign(&canvas_height);
- cb.mul_assign(4.0);
- cb.div_assign(&zoom);
- cb.add_assign(&center_imaginary);
+ cb /= &canvas_height;
+ cb *= 4.0;
+ cb /= &zoom;
+ cb += &center_imaginary;
cb
};
+ // Formaly, the initial condition that
+ //
+ // z = 0
+ //
+ // may be skipped as the first two iterations will
+ // always be
+ //
+ // z0 = 0
+ // z1 = z0^2+c = 0^2+c = 0+c = c
+ //
+ // That is, the result of the second iteration will
+ // always be the value of (c).
let mut za = Float::with_val(PRECISION, &ca);
let mut zb = Float::with_val(PRECISION, &cb);
let mut iteration_count: u32 = 0x0;
- while iteration_count < maximum_iteration_count {
+ while {
let square_distance = Float::with_val(PRECISION, &za * &za + &zb * &zb);
- if square_distance > 4.0 { break }
-
+ square_distance <= 4.0 && iteration_count < maximum_iteration_count
+ } {
{
- // z = z^2 + c
-
- // Complex square:
- // a = a^2 - b^2
- // b = 2abi
+ // The Mandelbrot Set (M) is defined as the set of values in the complex plane where the iterating function
+ //
+ // z = z^2+c
+ //
+ // stays bounded: I.e. the absolute value of (z) stays bounded:
+ //
+ // abs(z) = sqrt(Re(z)^2+Im(z)^2) <= 2^2 = 4
let za_temporary = Float::with_val(PRECISION, &za);
- za = Float::with_val(PRECISION, &za * &za - &zb * &zb);
- za = Float::with_val(PRECISION, &za + &ca);
+ // We can calculate the square of a complex number (z) as:
+ //
+ // z^2 = (a+ib)^2 = (a+ib)(a+ib) = a^2+iab+iab-b^2 = a^2-b^2+2iab
+
+ za = za.square();
+ za -= &zb * &zb;
+ za += &ca;
- zb = Float::with_val(PRECISION, &za_temporary * &zb);
- zb = Float::with_val(PRECISION, &zb * &two + &cb);
+ zb *= &za_temporary;
+ zb *= 2.0;
+ zb += &cb;
}
iteration_count += 0x1;