From f4b33c7c034f7e5bd754398e3dd9df3906a21d78 Mon Sep 17 00:00:00 2001 From: Nilstrieb Date: Tue, 2 Mar 2021 21:59:13 +0100 Subject: [PATCH] kind of works --- src/MandelbrotSet.java | 12 ++--- src/lib.rs | 109 +++++++++++++++++++++++++++++------------ src/main.rs | 4 +- 3 files changed, 87 insertions(+), 38 deletions(-) diff --git a/src/MandelbrotSet.java b/src/MandelbrotSet.java index fb1069a..9d34cbb 100644 --- a/src/MandelbrotSet.java +++ b/src/MandelbrotSet.java @@ -18,7 +18,7 @@ public class MandelbrotSet { // important settings------------------------------------------------------------- int pointNumber = 1; - int quality = 2; // 0 = very low, 1 = low, 2 = medium, 3 = high, 4 = ultra, any number bigger than 5 = custom + int quality = 2; // 0 = very low, 1 = low, 2 = medium, 3 = HIGH, 4 = ultra, any number bigger than 5 = custom double zoomSpeed = 1.1; // >1 int frames = 100; int width = 1920; @@ -36,7 +36,7 @@ public class MandelbrotSet { int iterations; double threshold = 100; char low = ' '; - char high = '#'; + char HIGH = '#'; if (quality == 0) { iterations = 20; @@ -101,7 +101,7 @@ public class MandelbrotSet { } else { // draw - draw(low, high, width, height, values); + draw(low, HIGH, width, height, values); } System.out.println("------------------------Frame " + frameCounter + " finished------------------------"); @@ -117,9 +117,9 @@ public class MandelbrotSet { } - static void draw(char low, char high, int width, int height, double[][] values) { + static void draw(char low, char HIGH, int width, int height, double[][] values) { // a method to draw a filled rectangle of size width * height - // each cell can be low or high, and it will show the corresponding char in each cell + // each cell can be low or HIGH, and it will show the corresponding char in each cell String line; for (int i = 0; i < height; i++) { @@ -129,7 +129,7 @@ public class MandelbrotSet { // for every char: double value = values[j][i]; if (value >= 1) { - line += high; + line += HIGH; } else { line += low; } diff --git a/src/lib.rs b/src/lib.rs index 28fdb80..22e2589 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,13 +2,18 @@ use std::error::Error; use std::time::SystemTime; use std::ops::{Add, Mul}; -pub fn main(config: Config) -> Result> { - let start_time = SystemTime::now().elapsed()?; +pub fn run(config: Config) -> Result> { + check_mandelbrot(&CNumber::new(-2.17068377, -1.13646737), 100, 100.0); + + let start_time = SystemTime::now(); + //let start_time = start_time.as_millis(); let coords = calculate_sample_points(&config); + let result = check_whole_mandelbrot(&coords, config.iterations, config.threshold); + let draw = draw(result); + println!("{}", draw); - let end_time = SystemTime::now().elapsed()?; - println!("Time: {}", end_time.as_micros() - start_time.as_micros()); + println!("Time: {}ms", start_time.elapsed()?.as_millis()); Ok(String::from("hi")) } @@ -17,7 +22,7 @@ fn calculate_sample_points(config: &Config) -> Vec> { let step_size_y = 2.0 / config.height; let offset_x = config.center.real - config.width / 2.0 * step_size_x; - let offset_y = -(config.center.imag - config.height / 2.0 * step_size_y); + let offset_y = -(config.center.imag - config.height / 2.0 * step_size_y) - 2.0; let mut coords: Vec> = vec![vec![CNumber::new(0.0, 0.0); config.width as usize]; config.height as usize]; @@ -33,7 +38,25 @@ fn calculate_sample_points(config: &Config) -> Vec> { coords } -fn check_mandelbrot(number: &CNumber, iter: i32, threshold: f64) -> i32 { +static HIGH: &str = "#"; +static LOW: &str = " "; + +fn check_whole_mandelbrot(nums: &Vec>, iter: i32, threshold: f64) -> Vec> { + let height = nums.len(); + let width = nums[0].len(); + + let mut result: Vec> = vec![vec![""; nums[0].len()]; nums.len()]; + + for i in 0..height { + for j in 0..width { + result[i][j] = check_mandelbrot(&nums[i][j], iter, threshold); + } + } + + result +} + +fn check_mandelbrot(number: &CNumber, iter: i32, threshold: f64) -> &str { let mut n = CNumber::new(0.0, 0.0); let c = number; @@ -41,13 +64,13 @@ fn check_mandelbrot(number: &CNumber, iter: i32, threshold: f64) -> i32 { for _ in 0..iter { n = n * n + *c; + + if n.imag > threshold || n.real > threshold { + return LOW; + } } - if n.real < threshold && n.imag < threshold { - 1 - } else { - 0 - } + HIGH } fn draw(values: Vec>) -> String { @@ -57,12 +80,13 @@ fn draw(values: Vec>) -> String { for char in line { out += char; } + out += "\n"; } out } -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, PartialEq)] struct CNumber { real: f64, imag: f64, @@ -89,8 +113,9 @@ impl Mul for CNumber { type Output = CNumber; fn mul(self, b: Self) -> Self::Output { - let real = self.real * self.real - b.imag * b.imag; - let imag = self.real * b.imag + b.real * self.imag; + //(a+bi)(c+di) = (ac−bd) + (ad+bc)i + let real = self.real * b.real - self.imag * b.imag; //ac−bd + let imag = self.real * b.imag + self.imag * b.real; //ad+bc CNumber { real, imag } } @@ -98,7 +123,6 @@ impl Mul for CNumber { pub struct Config { - quality: i32, width: f64, threshold: f64, //-- calculated @@ -115,15 +139,14 @@ impl Config { let center = interesting_points[point_number]; let iterations = match quality { 0 => 20, - 1 => 50, - 2 => 100, - 3 => 500, - 4 => 1000, + 1 => 500, + 2 => 1000, + 3 => 5000, + 4 => 20000, _ => quality }; Config { - quality, width: width as f64, height: height as f64, center, @@ -135,7 +158,29 @@ impl Config { //#[cfg(tests)] mod tests { - use crate::{Config, calculate_sample_points, check_mandelbrot, CNumber, draw}; + use crate::{CNumber, calculate_sample_points, check_mandelbrot, draw, HIGH, LOW, Config}; + + #[test] + fn cnumber_add_test() { + let a = CNumber::new(1.0, 1.0); + let b = CNumber::new(1.0, 1.0); + assert_eq!(a + b, CNumber::new(2.0, 2.0)); + + let a = CNumber::new(0.0, 0.0); + let b = CNumber::new(0.0, -1.0); + assert_eq!(a + b, CNumber::new(0.0, -1.0)); + + let a = CNumber::new(5.0, -13.0); + let b = CNumber::new(10.0, 5.0); + assert_eq!(a + b, CNumber::new(15.0, -8.0)) + } + + #[test] + fn cnumber_mul_test() { + let a = CNumber::new(1.0, 2.0); + let b = CNumber::new(3.0, 4.0); + assert_eq!(a * b, CNumber::new(-5.0, 10.0)); + } #[test] fn correct_size_points() { @@ -152,12 +197,16 @@ mod tests { let iter = 1000; let thr = 100.0; - assert_eq!(check_mandelbrot(&CNumber::new(1.0, 1.0), iter, thr), 0); - assert_eq!(check_mandelbrot(&CNumber::new(2.0, 0.0), iter, thr), 0); - assert_eq!(check_mandelbrot(&CNumber::new(0.0, 0.0), iter, thr), 1); - assert_eq!(check_mandelbrot(&CNumber::new(0.0, 3.0), iter, thr), 0); - assert_eq!(check_mandelbrot(&CNumber::new(0.8, 0.0), iter, thr), 0); - assert_eq!(check_mandelbrot(&CNumber::new(0.7, 0.0), iter, thr), 0); + assert_eq!(check_mandelbrot(&CNumber::new(1.0, 1.0), iter, thr), LOW); + assert_eq!(check_mandelbrot(&CNumber::new(2.0, 0.0), iter, thr), LOW); + assert_eq!(check_mandelbrot(&CNumber::new(0.0, 0.0), iter, thr), HIGH); + assert_eq!(check_mandelbrot(&CNumber::new(0.0, 3.0), iter, thr), LOW); + assert_eq!(check_mandelbrot(&CNumber::new(0.8, 0.0), iter, thr), LOW); + assert_eq!(check_mandelbrot(&CNumber::new(0.7, 0.0), iter, thr), LOW); + assert_eq!(check_mandelbrot(&CNumber::new(0.7, 0.0), iter, thr), LOW); + assert_eq!(check_mandelbrot(&CNumber::new(0.1, 0.1), iter, thr), HIGH); + assert_eq!(check_mandelbrot(&CNumber::new(0.1, 0.1), iter, thr), HIGH); + assert_eq!(check_mandelbrot(&CNumber::new(-2.17068377, -1.13646737), iter, thr), LOW); //CNumber { real: -2.17068377, imag: -1.13646737 } } #[test] @@ -165,8 +214,8 @@ mod tests { let vector = vec![vec!["a", "b", "c", "d", "e"]; 2]; let out = draw(vector); println!("{}", out); - assert_eq!(out, "\ - abcde\ - abcde") + assert_eq!(out, "abcde +abcde +") } } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 1f9251e..7b3f186 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,9 @@ use mandelbrot_set::Config; fn main() { - let config = Config::new(1, 3, 100, 100.0); + let config = Config::new(1, 4, 200, 100.0); - match mandelbrot_set::main(config) { + match mandelbrot_set::run(config) { Ok(s) => println!("{}", s), Err(e) => println!("Error: {}", e) }