kind of works

This commit is contained in:
Nilstrieb 2021-03-02 21:59:13 +01:00
parent be61bdeaa5
commit f4b33c7c03
3 changed files with 87 additions and 38 deletions

View file

@ -2,13 +2,18 @@ use std::error::Error;
use std::time::SystemTime;
use std::ops::{Add, Mul};
pub fn main(config: Config) -> Result<String, Box<dyn Error>> {
let start_time = SystemTime::now().elapsed()?;
pub fn run(config: Config) -> Result<String, Box<dyn Error>> {
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<Vec<CNumber>> {
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<CNumber>> =
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<Vec<CNumber>> {
coords
}
fn check_mandelbrot(number: &CNumber, iter: i32, threshold: f64) -> i32 {
static HIGH: &str = "#";
static LOW: &str = " ";
fn check_whole_mandelbrot(nums: &Vec<Vec<CNumber>>, iter: i32, threshold: f64) -> Vec<Vec<&str>> {
let height = nums.len();
let width = nums[0].len();
let mut result: Vec<Vec<&str>> = 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<Vec<&str>>) -> String {
@ -57,12 +80,13 @@ fn draw(values: Vec<Vec<&str>>) -> 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) = (acbd) + (ad+bc)i
let real = self.real * b.real - self.imag * b.imag; //acbd
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
")
}
}