Skip to content

Instantly share code, notes, and snippets.

@aisamanra
Last active February 23, 2018 08:20
Show Gist options
  • Select an option

  • Save aisamanra/601e95da34065671b7cf4b4cfdf4e9ae to your computer and use it in GitHub Desktop.

Select an option

Save aisamanra/601e95da34065671b7cf4b4cfdf4e9ae to your computer and use it in GitHub Desktop.
extern crate rand;
use rand::Rng;
use std::io::Write;
use std::ops::{Index,IndexMut};
use std::fs;
struct Config {
inner_size: usize,
outer_size: usize,
incr_amt: f32,
decr_amt: f32,
steps: usize,
img_size: usize,
}
fn clamp(low: f32, high: f32, num: f32) -> f32 {
if num < low {
low
} else if num > high {
high
} else {
num
}
}
struct Image {
sz: usize,
px: Vec<f32>,
}
impl Image {
fn new(sz: usize) -> Image {
let mut v = Vec::new();
for _ in 0..(sz*sz) {
v.push(0.0);
}
Image { sz: sz, px: v }
}
fn new_rand(sz: usize) -> Image {
let mut rng = rand::thread_rng();
let mut v = Vec::new();
for _ in 0..(sz*sz) {
v.push(rng.gen());
}
Image { sz: sz, px: v }
}
fn dim(&self) -> usize {
self.sz
}
fn print(&self, mut f: fs::File) {
writeln!(f, "P2\n{} {}\n128", self.dim(), self.dim());
for x in 0..self.dim() {
for y in 0..self.dim() {
writeln!(f, "{} ", (self[(x,y)] * 128.0).floor());
}
writeln!(f, "");
}
}
}
impl Index<(usize, usize)> for Image {
type Output = f32;
fn index<'a>(&'a self, (x, y): (usize, usize)) -> &'a f32 {
&self.px[x * self.sz + y]
}
}
impl IndexMut<(usize, usize)> for Image {
fn index_mut<'a>(&'a mut self, (x, y): (usize, usize)) -> &'a mut f32 {
&mut self.px[x * self.sz + y]
}
}
fn run_step(old: &Image, new: &mut Image, conf: &Config) {
for x in 0..conf.img_size {
for y in 0..conf.img_size {
if gather_neighbors(old, (x, y), conf.inner_size) >
gather_neighbors(old, (x, y), conf.outer_size) {
new[(x,y)] = clamp(0.0, 1.0, old[(x,y)] + conf.incr_amt)
} else {
new[(x,y)] = clamp(0.0, 1.0, old[(x,y)] - conf.decr_amt)
}
}
}
}
fn gather_neighbors(img: &Image, (x, y): (usize, usize), n: usize) -> f32 {
let mut amt = 0.0;
let mut tot = 0.0;
let ns = n as isize;
for i in -ns..ns {
for j in -ns..ns {
let xn = (i + x as isize) as usize;
let yn = (j + y as isize) as usize;
if xn > 0 && xn < img.dim() && yn > 0 && yn < img.dim() {
amt += img[(xn,yn)];
tot += 1.0;
}
}
}
amt / tot
}
fn main() {
for isize in 2..10 {
for osize in (isize+2)..12 {
let conf = Config {
inner_size: isize*2,
outer_size: osize*2,
incr_amt: 0.05,
decr_amt: 0.05,
steps: 100,
img_size: 256,
};
let filename = format!("output/morph-m-{}-{}.pbm", isize*2, osize*2);
println!("Printing to {:?}", filename);
let mut old = Image::new_rand(conf.img_size);
let mut new = Image::new(conf.img_size);
for _ in 0..conf.steps {
run_step(&old, &mut new, &conf);
std::mem::swap(&mut new, &mut old);
}
let mut f = match fs::File::create(filename) {
Ok(f) => f,
_ => panic!("Unable to open file"),
};
new.print(f);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment