mirror of
https://github.com/Noratrieb/mandelbrot-rust.git
synced 2026-01-16 16:25:06 +01:00
kind of works
This commit is contained in:
parent
be61bdeaa5
commit
f4b33c7c03
3 changed files with 87 additions and 38 deletions
|
|
@ -18,7 +18,7 @@ public class MandelbrotSet {
|
||||||
|
|
||||||
// important settings-------------------------------------------------------------
|
// important settings-------------------------------------------------------------
|
||||||
int pointNumber = 1;
|
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
|
double zoomSpeed = 1.1; // >1
|
||||||
int frames = 100;
|
int frames = 100;
|
||||||
int width = 1920;
|
int width = 1920;
|
||||||
|
|
@ -36,7 +36,7 @@ public class MandelbrotSet {
|
||||||
int iterations;
|
int iterations;
|
||||||
double threshold = 100;
|
double threshold = 100;
|
||||||
char low = ' ';
|
char low = ' ';
|
||||||
char high = '#';
|
char HIGH = '#';
|
||||||
|
|
||||||
if (quality == 0) {
|
if (quality == 0) {
|
||||||
iterations = 20;
|
iterations = 20;
|
||||||
|
|
@ -101,7 +101,7 @@ public class MandelbrotSet {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// draw
|
// draw
|
||||||
draw(low, high, width, height, values);
|
draw(low, HIGH, width, height, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("------------------------Frame " + frameCounter + " finished------------------------");
|
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
|
// 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;
|
String line;
|
||||||
|
|
||||||
for (int i = 0; i < height; i++) {
|
for (int i = 0; i < height; i++) {
|
||||||
|
|
@ -129,7 +129,7 @@ public class MandelbrotSet {
|
||||||
// for every char:
|
// for every char:
|
||||||
double value = values[j][i];
|
double value = values[j][i];
|
||||||
if (value >= 1) {
|
if (value >= 1) {
|
||||||
line += high;
|
line += HIGH;
|
||||||
} else {
|
} else {
|
||||||
line += low;
|
line += low;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
109
src/lib.rs
109
src/lib.rs
|
|
@ -2,13 +2,18 @@ use std::error::Error;
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
use std::ops::{Add, Mul};
|
use std::ops::{Add, Mul};
|
||||||
|
|
||||||
pub fn main(config: Config) -> Result<String, Box<dyn Error>> {
|
pub fn run(config: Config) -> Result<String, Box<dyn Error>> {
|
||||||
let start_time = SystemTime::now().elapsed()?;
|
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 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: {}ms", start_time.elapsed()?.as_millis());
|
||||||
println!("Time: {}", end_time.as_micros() - start_time.as_micros());
|
|
||||||
Ok(String::from("hi"))
|
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 step_size_y = 2.0 / config.height;
|
||||||
|
|
||||||
let offset_x = config.center.real - config.width / 2.0 * step_size_x;
|
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>> =
|
let mut coords: Vec<Vec<CNumber>> =
|
||||||
vec![vec![CNumber::new(0.0, 0.0); config.width as usize]; config.height as usize];
|
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
|
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 mut n = CNumber::new(0.0, 0.0);
|
||||||
let c = number;
|
let c = number;
|
||||||
|
|
||||||
|
|
@ -41,13 +64,13 @@ fn check_mandelbrot(number: &CNumber, iter: i32, threshold: f64) -> i32 {
|
||||||
|
|
||||||
for _ in 0..iter {
|
for _ in 0..iter {
|
||||||
n = n * n + *c;
|
n = n * n + *c;
|
||||||
|
|
||||||
|
if n.imag > threshold || n.real > threshold {
|
||||||
|
return LOW;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.real < threshold && n.imag < threshold {
|
HIGH
|
||||||
1
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw(values: Vec<Vec<&str>>) -> String {
|
fn draw(values: Vec<Vec<&str>>) -> String {
|
||||||
|
|
@ -57,12 +80,13 @@ fn draw(values: Vec<Vec<&str>>) -> String {
|
||||||
for char in line {
|
for char in line {
|
||||||
out += char;
|
out += char;
|
||||||
}
|
}
|
||||||
|
out += "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
struct CNumber {
|
struct CNumber {
|
||||||
real: f64,
|
real: f64,
|
||||||
imag: f64,
|
imag: f64,
|
||||||
|
|
@ -89,8 +113,9 @@ impl Mul for CNumber {
|
||||||
type Output = CNumber;
|
type Output = CNumber;
|
||||||
|
|
||||||
fn mul(self, b: Self) -> Self::Output {
|
fn mul(self, b: Self) -> Self::Output {
|
||||||
let real = self.real * self.real - b.imag * b.imag;
|
//(a+bi)(c+di) = (ac−bd) + (ad+bc)i
|
||||||
let imag = self.real * b.imag + b.real * self.imag;
|
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 }
|
CNumber { real, imag }
|
||||||
}
|
}
|
||||||
|
|
@ -98,7 +123,6 @@ impl Mul for CNumber {
|
||||||
|
|
||||||
|
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
quality: i32,
|
|
||||||
width: f64,
|
width: f64,
|
||||||
threshold: f64,
|
threshold: f64,
|
||||||
//-- calculated
|
//-- calculated
|
||||||
|
|
@ -115,15 +139,14 @@ impl Config {
|
||||||
let center = interesting_points[point_number];
|
let center = interesting_points[point_number];
|
||||||
let iterations = match quality {
|
let iterations = match quality {
|
||||||
0 => 20,
|
0 => 20,
|
||||||
1 => 50,
|
1 => 500,
|
||||||
2 => 100,
|
2 => 1000,
|
||||||
3 => 500,
|
3 => 5000,
|
||||||
4 => 1000,
|
4 => 20000,
|
||||||
_ => quality
|
_ => quality
|
||||||
};
|
};
|
||||||
|
|
||||||
Config {
|
Config {
|
||||||
quality,
|
|
||||||
width: width as f64,
|
width: width as f64,
|
||||||
height: height as f64,
|
height: height as f64,
|
||||||
center,
|
center,
|
||||||
|
|
@ -135,7 +158,29 @@ impl Config {
|
||||||
|
|
||||||
//#[cfg(tests)]
|
//#[cfg(tests)]
|
||||||
mod 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]
|
#[test]
|
||||||
fn correct_size_points() {
|
fn correct_size_points() {
|
||||||
|
|
@ -152,12 +197,16 @@ mod tests {
|
||||||
let iter = 1000;
|
let iter = 1000;
|
||||||
let thr = 100.0;
|
let thr = 100.0;
|
||||||
|
|
||||||
assert_eq!(check_mandelbrot(&CNumber::new(1.0, 1.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), 0);
|
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), 1);
|
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), 0);
|
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), 0);
|
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), 0);
|
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]
|
#[test]
|
||||||
|
|
@ -165,8 +214,8 @@ mod tests {
|
||||||
let vector = vec![vec!["a", "b", "c", "d", "e"]; 2];
|
let vector = vec![vec!["a", "b", "c", "d", "e"]; 2];
|
||||||
let out = draw(vector);
|
let out = draw(vector);
|
||||||
println!("{}", out);
|
println!("{}", out);
|
||||||
assert_eq!(out, "\
|
assert_eq!(out, "abcde
|
||||||
abcde\
|
abcde
|
||||||
abcde")
|
")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
use mandelbrot_set::Config;
|
use mandelbrot_set::Config;
|
||||||
|
|
||||||
fn main() {
|
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),
|
Ok(s) => println!("{}", s),
|
||||||
Err(e) => println!("Error: {}", e)
|
Err(e) => println!("Error: {}", e)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue