diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib.rs | 112 | ||||
-rw-r--r-- | src/main.rs | 8 |
2 files changed, 60 insertions, 60 deletions
@@ -17,7 +17,7 @@ use std::vec; use clap::Parser; -pub struct Gif { +pub struct Image { pub height: u16, pub width: u16, pub frames: u16, @@ -69,9 +69,9 @@ impl Args { } } -impl Gif { +impl Image { pub fn create_from_args(args: &Args) -> Self { - Gif { + Image { height: args.height, width: args.width, frames: args.frames, @@ -83,27 +83,64 @@ impl Gif { }; args.height as usize * args.width as usize ], - cross_distance: distance( - &Point { x: 0, y: 0 }, - &Point { - x: args.width - 1, - y: args.height - 1, - }, - ), + cross_distance: Point { x: 0, y: 0 }.distance(&Point { + x: args.width - 1, + y: args.height - 1, + }), points: generate_points(args.width, args.height, args.num_cells), } } + + pub fn fill_canvas(&mut self) { + self.generate_noise(); + } + + fn generate_noise(&mut self) { + let mut max_dist = 0.0; + + // Get distance and nearest point for each point on the canvas + for y in 0..self.height { + for x in 0..self.width { + let index = y as usize * self.width as usize + x as usize; + self.point_data[index] = PointData::get_point_data(self, Point { x, y }); + max_dist = f64::max(max_dist, self.point_data[index].min_dist); + } + } + + // normalize distances to [0,1] + for y in 0..self.height { + for x in 0..self.width { + let index = y as usize * self.width as usize + x as usize; + self.point_data[index].min_dist /= max_dist; + } + } + + // write pixels + for y in 0..self.height { + for x in 0..self.width { + let index = y as usize * self.width as usize + x as usize; + let val = 0xFF - (0xFF as f64 * self.point_data[index].min_dist) as u8; + self.set_pixel(val, val, val, Point { x, y }); + } + } + } + + fn set_pixel(&mut self, r: u8, g: u8, b: u8, p: Point) { + self.pixels[3 * (self.width as usize * p.y as usize + p.x as usize)] = r; + self.pixels[3 * (self.width as usize * p.y as usize + p.x as usize) + 1] = g; + self.pixels[3 * (self.width as usize * p.y as usize + p.x as usize) + 2] = b; + } } impl PointData { - fn get_point_data(gif: &Gif, p: Point) -> Self { + fn get_point_data(image: &Image, p: Point) -> Self { let mut pd = PointData { - min_dist: gif.cross_distance, + min_dist: image.cross_distance, closest_point: Point { x: 0, y: 0 }, }; - for point in &gif.points { - let d = distance(&p, point); + for point in &image.points { + let d = p.distance(point); if d < pd.min_dist { pd.min_dist = d; pd.closest_point = point.clone(); @@ -114,42 +151,12 @@ impl PointData { } } -pub fn fill_canvas(gif: &mut Gif) { - generate_noise(gif); -} - -fn set_pixel(gif: &mut Gif, r: u8, g: u8, b: u8, x: u16, y: u16) { - gif.pixels[3 * (gif.width as usize * y as usize + x as usize)] = r; - gif.pixels[3 * (gif.width as usize * y as usize + x as usize) + 1] = g; - gif.pixels[3 * (gif.width as usize * y as usize + x as usize) + 2] = b; -} - -fn generate_noise(gif: &mut Gif) { - let mut max_dist = 0.0; - - // Get distance and nearest point for each point on the canvas - for y in 0..gif.height { - for x in 0..gif.width { - let index = y as usize * gif.width as usize + x as usize; - gif.point_data[index] = PointData::get_point_data(gif, Point { x, y }); - max_dist = f64::max(max_dist, gif.point_data[index].min_dist); - } - } +impl Point { + fn distance(&self, other: &Point) -> f64 { + let x_dist: f64 = other.x as f64 - self.x as f64; + let y_dist: f64 = other.y as f64 - self.y as f64; - // normalize distances to [0,1] - for y in 0..gif.height { - for x in 0..gif.width { - let index = y as usize * gif.width as usize + x as usize; - gif.point_data[index].min_dist /= max_dist; - } - } - - for y in 0..gif.height { - for x in 0..gif.width { - let index = y as usize * gif.width as usize + x as usize; - let val = 0xFF - (0xFF as f64 * gif.point_data[index].min_dist) as u8; - set_pixel(gif, val, val, val, x, y) - } + (x_dist * x_dist + y_dist * y_dist).sqrt() } } @@ -163,10 +170,3 @@ fn generate_points(width: u16, height: u16, num_cells: usize) -> Vec<Point> { points } - -fn distance(p1: &Point, p2: &Point) -> f64 { - let x_dist: f64 = p2.x as f64 - p1.x as f64; - let y_dist: f64 = p2.y as f64 - p1.y as f64; - - (x_dist * x_dist + y_dist * y_dist).sqrt() -} diff --git a/src/main.rs b/src/main.rs index 59a14c6..3622bb5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,13 +16,13 @@ use std::fs::File; use std::process; use bubbles::Args; -use bubbles::Gif; +use bubbles::Image; fn main() { let args = Args::read(); // create Gif data - let mut gif = Gif::create_from_args(&args); + let mut data = Image::create_from_args(&args); // Create encoder let mut image = File::create(args.out).unwrap(); @@ -34,8 +34,8 @@ fn main() { } // Create pixel array - bubbles::fill_canvas(&mut gif); - let frame = gif::Frame::from_rgb(gif.width, gif.height, &mut gif.pixels); + data.fill_canvas(); + let frame = gif::Frame::from_rgb(data.width, data.height, &mut data.pixels); // Write frame to file encoder.write_frame(&frame).unwrap(); |