~jpl8/text-to-piet

c9016ebc23d6db7a06b1b0d15448ce3ce8f45701 — jpl 1 year, 7 months ago 48f85f9
Add spiral struct and iterator for image output
4 files changed, 103 insertions(+), 41 deletions(-)

A spiral.png
M src/main.rs
A src/spiral.rs
M test.png
A spiral.png => spiral.png +0 -0
M src/main.rs => src/main.rs +15 -41
@@ 8,6 8,8 @@ use crate::colors::Color;
use clap::Parser;

mod colors;
mod spiral;
use spiral::*;

/// A text to piet encoder
#[derive(Parser, Debug)]


@@ 161,24 163,6 @@ fn gen_num_with_prev(prev: i64, n: i64) -> Vec<Instructions> {
    instructions
}

enum Direction {
    Up,
    Down,
    Left,
    Right,
}

impl Direction {
    fn clockwise(&self) -> Self {
        match self {
            Direction::Up => Direction::Right,
            Direction::Down => Direction::Left,
            Direction::Left => Direction::Up,
            Direction::Right => Direction::Down,
        }
    }
}

fn update_x_y_spiral(x: u32, y: u32, step: u32, dir: &Direction) -> (u32, u32) {
    match dir {
        Direction::Up => (x, y - step),


@@ 294,28 278,18 @@ fn instructions_to_blocks(instructions: &Vec<Instructions>, img_size: u32) -> Ve

fn colors_to_img(colors: Vec<Color>, img_size: u32, img_name: String) {
    let mut img = RgbImage::new(img_size, img_size);
    let mut direction = Direction::Right;

    let mut space_in_row: u32 = img_size;
    let mut remaining_space: u32 = space_in_row - 1;
    let mut final_pos = (0, 0);
    let mut final_dir = Direction::Right;

    let mut x = 0;
    let mut y = 0;
    let sp = Spiral2D::new(0, 0, Direction::Right, img_size, colors.len() as u32);

    for color in colors.iter() {
    for ((x, y, dir), color) in sp.zip(colors.iter()) {
        img.put_pixel(x, y, Rgb(color.to_bytes()));
        (x, y) = update_x_y_spiral(x, y, 1, &direction);
        remaining_space -= 1;

        if remaining_space == 0 {
            direction = direction.clockwise();
            match direction {
                Direction::Down | Direction::Up => space_in_row -= 2,
                _ => (),
            }
            remaining_space = space_in_row;
        }
        final_pos = (x, y);
        final_dir = dir;
    }
    let (mut x, mut y) = final_pos;

    // SAFE: There is always the starting color in colors
    let color = colors.last().unwrap();


@@ 324,21 298,21 @@ fn colors_to_img(colors: Vec<Color>, img_size: u32, img_name: String) {
    img.put_pixel(x, y, Rgb(color.to_bytes()));

    let color = colors::instruction_to_block(PUSH(1), *color).0;
    (x, y) = update_x_y_spiral(x, y, 1, &direction.clockwise());
    (x, y) = update_x_y_spiral(x, y, 1, &final_dir.clockwise());
    img.put_pixel(x, y, Rgb(color.to_bytes()));

    let color = colors::instruction_to_block(PUSH(1), color).0;
    (x, y) = update_x_y_spiral(x, y, 1, &direction.clockwise());
    (x, y) = update_x_y_spiral(x, y, 1, &final_dir.clockwise());
    img.put_pixel(x, y, Rgb(color.to_bytes()));

    (x, y) = update_x_y_spiral(x, y, 1, &direction);
    (x, y) = update_x_y_spiral(x, y, 1, &final_dir);
    img.put_pixel(x, y, Rgb(color.to_bytes()));

    (x, y) = update_x_y_spiral(x, y, 2, &direction.clockwise().clockwise());
    (x, y) = update_x_y_spiral(x, y, 2, &final_dir.clockwise().clockwise());
    img.put_pixel(x, y, Rgb(color.to_bytes()));

    (x, y) = update_x_y_spiral(x, y, 1, &direction);
    (x, y) = update_x_y_spiral(x, y, 1, &direction.clockwise());
    (x, y) = update_x_y_spiral(x, y, 1, &final_dir);
    (x, y) = update_x_y_spiral(x, y, 1, &final_dir.clockwise());
    img.put_pixel(x, y, Rgb(color.to_bytes()));

    img.save(img_name).expect("Failed to save image");

A src/spiral.rs => src/spiral.rs +88 -0
@@ 0,0 1,88 @@
#[derive(Debug, Clone, Copy)]
pub enum Direction {
    Up,
    Down,
    Left,
    Right,
}

impl Direction {
    pub fn clockwise(&self) -> Self {
        match self {
            Direction::Up => Direction::Right,
            Direction::Down => Direction::Left,
            Direction::Left => Direction::Up,
            Direction::Right => Direction::Down,
        }
    }
}

#[derive(Debug, Clone, Copy)]
pub struct Spiral2D {
    pub x: u32,
    pub y: u32,

    pub dir: Direction,

    side: u32,
    length: u32,

    remaining_space: u32,
    remaining_length: u32,
    curr_side: u32,

    spiral_tightness: u32,
}

impl Spiral2D {
    pub fn new(x: u32, y: u32, dir: Direction, side: u32, length: u32) -> Self {
        Self {
            x,
            y,
            side,
            length,
            dir,
            remaining_space: side,
            remaining_length: length,
            curr_side: side,
            spiral_tightness: 2,
        }
    }
}

impl Iterator for Spiral2D {
    type Item = (u32, u32, Direction);

    fn next(&mut self) -> Option<Self::Item> {
        if self.remaining_length == 0 || self.curr_side == 0 {
            None
        } else {
            let prev = (self.x, self.y, self.dir);

            self.remaining_space -= 1;
            self.remaining_length -= 1;

            if self.remaining_space == 0 {
                self.dir = self.dir.clockwise();
                // TODO: Check if the remaining_space should
                // be decremented on Down and Up
                // or if it should be a function of the original
                // direction
                match self.dir {
                    Direction::Down | Direction::Up => self.curr_side -= self.spiral_tightness,
                    _ => (),
                }
                self.remaining_space = self.curr_side;
            }

            (self.x, self.y) = match self.dir {
                Direction::Up => (self.x, self.y - 1),
                Direction::Down => (self.x, self.y + 1),
                Direction::Left => (self.x - 1, self.y),
                Direction::Right => (self.x + 1, self.y),
            };

            Some(prev)
        }
    }
}

M test.png => test.png +0 -0