summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md8
-rw-r--r--Cargo.toml5
-rw-r--r--source/benoit/benoit.rs2
-rw-r--r--source/benoit/benoit/application/colour.rs44
-rw-r--r--source/benoit/benoit/application/draw.rs15
-rw-r--r--source/benoit/benoit/application/handle_keys.rs4
-rw-r--r--source/benoit/benoit/application/render_row_julia.rs13
-rw-r--r--source/benoit/benoit/application/render_row_normal.rs21
-rw-r--r--source/benoit/benoit/application/run.rs6
-rw-r--r--source/benoit/benoit/iteration/iterate_mandelbrot.rs2
-rw-r--r--source/benoit/benoit/video/initialise.rs9
11 files changed, 100 insertions, 29 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 34a8383..74c4f6e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,11 @@
+# 2↋
+
+* Optimise and refactor code
+* Update colouring
+* Log version and copyright
+* Fix complex-to-cartesian conversions (and controls)
+* Update translation feedback
+
# 2↊
* Fix Julia toggle messages
diff --git a/Cargo.toml b/Cargo.toml
index 9b90787..4db24db 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "benoit"
-version = "0.34.0"
+version = "0.35.0"
authors = ["Gabriel Bjørnager Jensen"]
edition = "2021"
description = "Mandelbrot renderer."
@@ -12,7 +12,8 @@ name = "benoit"
path = "source/benoit/main.rs"
[profile.release]
-lto = true
+codegen-units = 1
+lto = "fat"
[dependencies]
rayon = "1.7.0"
diff --git a/source/benoit/benoit.rs b/source/benoit/benoit.rs
index b301f36..2812e52 100644
--- a/source/benoit/benoit.rs
+++ b/source/benoit/benoit.rs
@@ -28,4 +28,6 @@ pub mod iteration;
pub mod render_data;
pub mod video;
+pub const VERSION: u32 = 0x23;
+
pub const PRECISION: u32 = 0x80;
diff --git a/source/benoit/benoit/application/colour.rs b/source/benoit/benoit/application/colour.rs
index c243f71..a4587c6 100644
--- a/source/benoit/benoit/application/colour.rs
+++ b/source/benoit/benoit/application/colour.rs
@@ -23,6 +23,33 @@
use crate::benoit::application::Application;
+fn hsv_to_rgb(hue: f32, saturation: f32, value: f32) -> (f32, f32, f32) {
+ return if saturation <= 0.0 {
+ let value = value.min(1.0);
+
+ (value, value, value)
+ } else {
+ let h = hue % 1.0 * 6.0;
+ let s = saturation.min(1.0);
+ let v = value.min(1.0);
+
+ let f = h % 1.0;
+ let p = v * (1.0 - s);
+ let q = v * (1.0 - s * f);
+ let t = v * (1.0 - s * (1.0 - f));
+
+ match h.trunc() as u8 {
+ 0x0 => (v, t, p),
+ 0x1 => (q, v, p),
+ 0x2 => (p, v, t),
+ 0x3 => (p, q, v),
+ 0x4 => (t, p, v),
+ 0x5 => (v, p, q),
+ value => unreachable!(),
+ }
+ };
+}
+
impl Application {
pub fn colour(&self, buffer: &mut [u8], iter_count_buffer: &[u32], square_dist_buffer: &[f32]) {
let canvas_size = self.canvas_width * self.canvas_width;
@@ -30,20 +57,13 @@ impl Application {
for pixel in 0x0..canvas_size {
let iter_count = iter_count_buffer[pixel as usize];
- let (red, green, blue) = if iter_count != self.max_iter_count {
- let distance = square_dist_buffer[pixel as usize].sqrt();
-
- let factor_range = 16.0_f32.min(self.max_iter_count as f32);
+ let distance = square_dist_buffer[pixel as usize].sqrt();
- let mut factor = (iter_count as f32 + 1.0 - distance.log2().log2()) / factor_range % 1.0;
+ let factor_range = 16.0_f32.min(self.max_iter_count as f32);
+ let factor = (iter_count as f32 + 1.0 - distance.log2().log2()) / factor_range % 1.0;
- factor = (if factor >= 1.0 / 2.0 {
- 1.0 - factor
- } else {
- factor
- }) * 2.0;
-
- (factor * factor, factor * factor, factor)
+ let (red, green, blue) = if iter_count != self.max_iter_count {
+ hsv_to_rgb(factor, 7.0 / 8.0, 7.0 / 8.0)
} else {
(0.0, 0.0, 0.0)
};
diff --git a/source/benoit/benoit/application/draw.rs b/source/benoit/benoit/application/draw.rs
index 7c62c98..31ba470 100644
--- a/source/benoit/benoit/application/draw.rs
+++ b/source/benoit/benoit/application/draw.rs
@@ -59,8 +59,6 @@ impl Application {
}
if !self.julia {
- let viewport_colour = Color::RGB(0xFF, 0x0, 0x0);
-
let canvas_width = {
let mut canvas_width = Float::with_val(PRECISION, self.canvas_width);
canvas_width *= self.scale;
@@ -74,11 +72,15 @@ impl Application {
let mut width = Float::with_val(PRECISION, 1.0 / &zoom_ratio);
+ // Remember that cartesian coordinates have an
+ // inverted vertical axis compared to those of
+ // SDL's coordinate system.
+
let mut offset_x = self.centre_real.clone();
- let mut offset_y = self.centre_imag.clone();
+ let mut offset_y = Float::with_val(PRECISION, -&self.centre_imag);
offset_x -= &previous_position.centre_real;
- offset_y -= &previous_position.centre_imag;
+ offset_y += &previous_position.centre_imag;
offset_x /= 4.0;
offset_y /= 4.0;
@@ -107,7 +109,10 @@ impl Application {
)
};
- self.video.as_mut().unwrap().canvas.set_draw_color(viewport_colour);
+ self.video.as_mut().unwrap().canvas.set_draw_color(Color::RGBA(0x0, 0x0, 0x0, 0x3F));
+ self.video.as_mut().unwrap().canvas.fill_rects(&[viewport]).unwrap();
+
+ self.video.as_mut().unwrap().canvas.set_draw_color(Color::RGB(0xFF, 0xFF, 0xFF));
self.video.as_mut().unwrap().canvas.draw_rects(&[viewport]).unwrap();
}
diff --git a/source/benoit/benoit/application/handle_keys.rs b/source/benoit/benoit/application/handle_keys.rs
index 0a1b281..1991c36 100644
--- a/source/benoit/benoit/application/handle_keys.rs
+++ b/source/benoit/benoit/application/handle_keys.rs
@@ -92,8 +92,8 @@ impl Application {
};
match scan_code {
- Scancode::S => self.centre_imag += &translate_ammount,
- Scancode::W => self.centre_imag -= &translate_ammount,
+ Scancode::S => self.centre_imag -= &translate_ammount,
+ Scancode::W => self.centre_imag += &translate_ammount,
_ => {},
};
diff --git a/source/benoit/benoit/application/render_row_julia.rs b/source/benoit/benoit/application/render_row_julia.rs
index 7bfa6be..3f4bb0c 100644
--- a/source/benoit/benoit/application/render_row_julia.rs
+++ b/source/benoit/benoit/application/render_row_julia.rs
@@ -28,7 +28,8 @@ use crate::benoit::render_data::RenderData;
extern crate rug;
-use rug::Float;
+use rug::{Assign, Float};
+use rug::float::Special;
use std::sync::Arc;
impl Application {
@@ -71,12 +72,22 @@ impl Application {
zb
};
+ let mut za_prev = Float::with_val(PRECISION, Special::Nan);
+ let mut zb_prev = Float::with_val(PRECISION, Special::Nan);
+
let mut iter_count: u32 = 0x0;
let mut square_dist;
while {
square_dist = Float::with_val(PRECISION, &za * &za + &zb * &zb).to_f32();
+
+ let periodic = za == za_prev && zb == zb_prev;
+
+ if periodic { iter_count = data.max_iter_count }
square_dist <= 256.0 && iter_count < data.max_iter_count
} {
+ za_prev.assign(&za);
+ zb_prev.assign(&zb);
+
iterator(&mut za, &mut zb, ca, cb);
iter_count += 0x1;
diff --git a/source/benoit/benoit/application/render_row_normal.rs b/source/benoit/benoit/application/render_row_normal.rs
index b3d3835..157c767 100644
--- a/source/benoit/benoit/application/render_row_normal.rs
+++ b/source/benoit/benoit/application/render_row_normal.rs
@@ -28,7 +28,8 @@ use crate::benoit::render_data::RenderData;
extern crate rug;
-use rug::Float;
+use rug::{Assign, Float};
+use rug::float::Special;
use std::sync::Arc;
impl Application {
@@ -60,13 +61,16 @@ impl Application {
cb *= 4.0;
cb /= &canvas_width;
cb /= &data.zoom;
- cb += &data.centre_imag;
+ cb -= &data.centre_imag;
cb
};
- let mut za = Float::with_val(PRECISION, &ca);
- let mut zb = Float::with_val(PRECISION, &cb);
+ let mut za = ca.clone();
+ let mut zb = cb.clone();
+
+ let mut za_prev = Float::with_val(PRECISION, Special::Nan);
+ let mut zb_prev = Float::with_val(PRECISION, Special::Nan);
let mut iter_count: u32 = 0x0;
let mut square_dist;
@@ -74,8 +78,17 @@ impl Application {
square_dist = Float::with_val(PRECISION, &za * &za + &zb * &zb).to_f32();
// Having a larger escape radius gives better
// results with regard to smoothing.
+
+ // Check if the value is periodic, i.e. its
+ // sequence repeats.
+ let periodic = za == za_prev && zb == zb_prev;
+
+ if periodic { iter_count = data.max_iter_count }
square_dist <= 256.0 && iter_count < data.max_iter_count
} {
+ za_prev.assign(&za);
+ zb_prev.assign(&zb);
+
iterator(&mut za, &mut zb, &ca, &cb);
iter_count += 0x1;
diff --git a/source/benoit/benoit/application/run.rs b/source/benoit/benoit/application/run.rs
index e8ee4e3..b9aa50b 100644
--- a/source/benoit/benoit/application/run.rs
+++ b/source/benoit/benoit/application/run.rs
@@ -21,12 +21,18 @@
If not, see <https://www.gnu.org/licenses/>.
*/
+use crate::benoit::VERSION;
use crate::benoit::application::Application;
extern crate sdl2;
impl Application {
pub fn run(&mut self) -> i32 {
+ println!();
+ println!("Benoit {VERSION:X}");
+ println!("Copyright 2021, 2023 Gabriel Bjørnager Jensen.");
+ println!();
+
eprintln!("rendering the {}", self.fractal.get_name());
return match self.interactive {
diff --git a/source/benoit/benoit/iteration/iterate_mandelbrot.rs b/source/benoit/benoit/iteration/iterate_mandelbrot.rs
index 34a3c79..6be612c 100644
--- a/source/benoit/benoit/iteration/iterate_mandelbrot.rs
+++ b/source/benoit/benoit/iteration/iterate_mandelbrot.rs
@@ -41,7 +41,7 @@ pub fn iterate_mandelbrot(za: &mut Float, zb: &mut Float, ca: &Float, cb: &Float
// We can calculate the square of a complex number
// as:
//
- // (a+ib)^2 = (a+ib)(a+ib) = a^2+iab+iab-b^2 = a^2-b^2+2iab
+ // (a+bi)^2 = (a+bi)(a+bi) = a^2+abi+abi-b^2 = a^2-b^2+2abi
za.square_mut();
*za -= &*zb * &*zb;
diff --git a/source/benoit/benoit/video/initialise.rs b/source/benoit/benoit/video/initialise.rs
index 15449fd..40bc68d 100644
--- a/source/benoit/benoit/video/initialise.rs
+++ b/source/benoit/benoit/video/initialise.rs
@@ -25,14 +25,19 @@ use crate::benoit::video::Video;
extern crate sdl2;
+use crate::benoit::VERSION;
+use sdl2::render::BlendMode;
+
impl Video {
pub fn initialise(canvas_width: u32, scale: u32) -> Video {
let sdl = sdl2::init().expect("unable to initialise sdl2");
let sdl_video = sdl.video().expect("unable to initialise video");
- let window = sdl_video.window("Benoit", canvas_width * scale, canvas_width * scale).position_centered().build().expect("unable to open window");
+ let window = sdl_video.window(format!("Benoit {VERSION:X}").as_str(), canvas_width * scale, canvas_width * scale).position_centered().build().expect("unable to open window");
+
+ let mut canvas = window.into_canvas().build().expect("unable to create canvas");
- let canvas = window.into_canvas().build().expect("unable to create canvas");
+ canvas.set_blend_mode(BlendMode::Blend);
return Video {
sdl: sdl,