Created
July 27, 2022 15:45
-
-
Save hugozap/07d25c364a7b6340332cbe4522e80552 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use colorsys::{Hsl, Rgb}; | |
use core::ops::Add; | |
use core::ops::Div; | |
use core::ops::Mul; | |
use core::ops::Sub; | |
use image; | |
use noise::{NoiseFn, Perlin}; | |
use num::Complex; | |
use std::cmp; | |
use std::str::FromStr; | |
fn escape_time(c: Complex<f64>, limit: usize) -> Option<usize> { | |
let mut z = Complex { re: 0.0, im: 0.0 }; | |
for i in 0..limit { | |
if z.norm_sqr() > 4.0 { | |
return Some(i); | |
} | |
z = z * z + c; | |
} | |
None | |
} | |
fn pixel_to_point( | |
bounds: (usize, usize), | |
pixel: (usize, usize), | |
upper_left: Complex<f64>, | |
lower_right: Complex<f64>, | |
) -> Complex<f64> { | |
let (width, height) = ( | |
lower_right.re - upper_left.re, | |
upper_left.im - lower_right.im, | |
); | |
Complex { | |
re: upper_left.re + pixel.0 as f64 * width / bounds.0 as f64, | |
im: upper_left.im - pixel.1 as f64 * height / bounds.1 as f64, | |
} | |
} | |
#[test] | |
fn test_pixel_to_point() { | |
assert_eq!( | |
pixel_to_point( | |
(100, 200), | |
(25, 175), | |
Complex { re: -1.0, im: 1.0 }, | |
Complex { re: 1.0, im: -1.0 } | |
), | |
Complex { | |
re: -0.5, | |
im: -0.75 | |
} | |
); | |
} | |
#[test] | |
fn test_escape_time() { | |
let mut c = Complex { re: 0.0, im: 0.0 }; | |
assert_eq!(escape_time(c, 10), None); | |
c.re = 5.0; | |
assert_eq!(escape_time(c, 5), Some(1)); | |
} | |
fn render( | |
pixels: &mut [u8], | |
bounds: (usize, usize), | |
upper_left: Complex<f64>, | |
bottom_right: Complex<f64>, | |
) { | |
let width = bounds.0; | |
let height = bounds.1; | |
for row in 0..bounds.1 { | |
for col in 0..bounds.0 { | |
let point = pixel_to_point(bounds, (row, col), upper_left, bottom_right); | |
//ya tenemos el numero complejo que representa el pixel | |
let distance = escape_time(point, 255); | |
let ix = row * width + col; | |
pixels[ix] = match distance { | |
Some(i) => i as u8, | |
_ => 0 as u8, | |
} | |
} | |
} | |
} | |
#[test] | |
fn test_render() { | |
let mut pixels: [u8; 4] = [0, 0, 0, 0]; | |
render( | |
&mut pixels, | |
(2, 2), | |
Complex { im: -0.5, re: -1.0 }, | |
Complex { im: 0.5, re: 1.0 }, | |
); | |
assert_eq!(pixels[0], 0); | |
assert_eq!(pixels[1], 0); | |
} | |
//Write pixels to image | |
fn write_image(file: &str, width: usize, height: usize, pixels: &[u8]) { | |
image::save_buffer( | |
file, | |
pixels, | |
width as u32, | |
height as u32, | |
image::ColorType::Rgb8, | |
) | |
.unwrap() | |
} | |
fn main() { | |
println!("Hello, world!"); | |
let width = 4000; | |
let height = 4000; | |
let mut pixels = vec![0; width * height]; | |
render( | |
&mut pixels, | |
(width, height), | |
Complex { im: 0.1, re: 0.1 }, | |
Complex { im: 0.6, re: 0.6 }, | |
); | |
let mut rgbpixels = vec![0; width * height * 3]; | |
createColoredImage((width, height), &mut rgbpixels, &pixels); | |
write_image(&String::from("image.png"), width, height, &rgbpixels); | |
} | |
fn createColoredImage(size: (usize, usize), rgbpixels: &mut [u8], pixels: &[u8]) { | |
let mut ix = 0; | |
let mut row = 0; | |
let mut col = 0; | |
for (pix, p) in pixels.iter().enumerate() { | |
let width = size.0; | |
let height = size.1; | |
row = (pix / width) as u8; | |
col = (pix % width) as u8; | |
let val = 50.0 + 255.0 - *p as f32; | |
//let perlin = Perlin::new(); | |
//let n = perlin.get([row as f64 / height as f64, col as f64 / width as f64]); | |
let n = 0.0; | |
println!("row {} col {} noise {:?}", row, col, n); | |
let hue: f32 = 360.0 * (*p as f32) / 255.0; // *p as f32; | |
let light: f32 = 500.0 * (*p as f32) / 200.0; | |
let hslc: Hsl = Hsl::from(&(hue + (n as f32) as f32, 45.0 + val as f32, light)); | |
let rgbc: Rgb = Rgb::from(&hslc); | |
rgbpixels[ix] = rgbc.red() as u8; | |
rgbpixels[ix + 1] = rgbc.green() as u8; | |
rgbpixels[ix + 2] = rgbc.blue() as u8; | |
ix += 3; | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment