Skip to content

Instantly share code, notes, and snippets.

@wolfiestyle
Created September 15, 2015 04:42
Show Gist options
  • Save wolfiestyle/4dcc67e3737b94ce3c8c to your computer and use it in GitHub Desktop.
Save wolfiestyle/4dcc67e3737b94ce3c8c to your computer and use it in GitHub Desktop.
mandelbrot renderer in Rust
extern crate num;
use num::complex::Complex64;
use num::traits::{Zero, One};
use std::env;
use std::io::{self, Write};
use std::fs::File;
fn viewport(width: usize, height: usize, size: f64, center: Complex64) -> (f64, f64, f64, f64)
{
let (w, h, s) = (width as f64, height as f64, size * 0.5);
let dist = if w > h { Complex64::new(s, s * h / w) } else { Complex64::new(s * w / h, s) };
let (p0, p1) = (center - dist, center + dist);
let dp = p1 - p0;
(p0.re, p1.im, dp.re / (w - 1.), dp.im / (1. - h))
}
fn render<F>(width: usize, height: usize, size: f64, center: Complex64, f: F) -> Vec<u8>
where F: Fn(Complex64) -> u8
{
let mut buf = Vec::with_capacity(width * height);
let (x0, y0, ix, iy) = viewport(width, height, size, center);
let mut y = y0;
for _ in 0..height
{
let mut x = x0;
for _ in 0..width
{
buf.push(f(Complex64::new(x, y)));
x += ix;
}
y += iy;
}
buf
}
fn mandel_dist(c: Complex64, max_it: u32) -> Option<f64>
{
let mut z = Complex64::zero();
let mut dz = Complex64::one();
for _ in 0..max_it
{
dz = (z * dz).scale(2.) + Complex64::one();
z = z * z + c;
let zsq = z.norm_sqr();
if zsq > 1024.
{
return Some((zsq / dz.norm_sqr()).sqrt() * zsq.ln() * 0.5)
}
}
None
}
fn save_ppm<W: Write>(file: &mut W, img: &[u8], w: usize, h: usize) -> io::Result<()>
{
try!(write!(file, "P5\n{} {}\n{}\n", w, h, std::u8::MAX));
file.write_all(&img)
}
fn main()
{
let mut file: Box<Write> = match env::args().nth(1) {
Some(name) => Box::new(File::create(name).unwrap()),
None => Box::new(io::stdout()),
};
let (w, h, size) = (640, 480, 3.5);
let img = render(w, h, size, Complex64::new(-0.7, 0.), |c| {
mandel_dist(c, 255).map(|dist| {
let val = 1. - (dist * 8. / size).max(0.).min(1.).powf(0.125);
(val * 255.) as u8
}).unwrap_or(255)
});
save_ppm(&mut file, &img, w, h).unwrap();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment