Skip to content

Instantly share code, notes, and snippets.

@hugozap
Created July 27, 2022 15:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hugozap/07d25c364a7b6340332cbe4522e80552 to your computer and use it in GitHub Desktop.
Save hugozap/07d25c364a7b6340332cbe4522e80552 to your computer and use it in GitHub Desktop.
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