Visualizations are hard, and take time, so here is a thread to highlight the visualizations that we have found/created.

Please feel free to post your visualisations!

  • CameronDevOPM
    link
    fedilink
    arrow-up
    2
    ·
    6 days ago

    For anyone else doing rust, this might be useful:

    It basically generates an asciicinema/asciicast file, which is then can be used to render a video.

    use std::fs::File;
    use std::io::Write;
    use std::process::Command;
    
    pub struct Recorder {
        filename: String,
        output: File,
        width: usize,
        height: usize,
        position: f32,
        frametime: f32,
        do_render: bool,
    }
    
    // Generate: https://docs.asciinema.org/manual/asciicast/v2/
    impl Recorder {
        pub fn new(filename: &str, w: usize, h: usize, framerate: u32, do_render: bool) -> Recorder {
            let mut r = Recorder {
                filename: String::from(filename),
                output: File::create(format!("{filename}.cast")).unwrap(),
                width: w,
                height: h,
                position: 0f32,
                frametime: 1f32 / framerate as f32,
                do_render,
            };
            r.init();
            r
        }
    
        fn init(&mut self) {
            self.output
                .write_all(
                    format!(
                        "{{\"version\": 2, \"width\": {}, \"height\": {}}}\n",
                        self.width, self.height
                    )
                    .as_bytes(),
                )
                .unwrap();
        }
    
        pub fn println(&mut self, s: &str) {
            let line = format!("{s}\n");
    
            self.print(&line);
        }
    
        pub fn print(&mut self, s: &str) {
            let escaped = serde_json::to_string(&(self.position, "o", s)).unwrap();
    
            self.output
                .write_all(format!("{escaped}\n").as_bytes())
                .unwrap();
        }
    
        const RESET: &'static str = "\u{001b}[H\u{001b}[2J\u{001b}[3J";
    
        pub fn sleep(&mut self, d: f32) {
            self.frametime += d;
        }
    
        pub fn new_frame(&mut self) {
            self.position += self.frametime;
    
            self.print(Self::RESET);
        }
    }
    
    impl Drop for Recorder {
        fn drop(&mut self) {
            if self.do_render {
                let castname = format!("{}.cast", self.filename);
                let gifname = format!("{}.gif", self.filename);
                let mp4name = format!("{}.mp4", self.filename);
    
                self.output.flush().unwrap();
                let mut command = Command::new("agg");
                command.arg(castname);
                command.arg(gifname.as_str());
                let mut proc = command.spawn().unwrap();
                proc.wait().unwrap();
    
                let _ = std::fs::remove_file(mp4name.as_str());
                let mut command = Command::new("ffmpeg");
                command.arg("-i");
                command.arg(gifname.as_str());
                command.arg(mp4name.as_str());
                let mut proc = command.spawn().unwrap();
                proc.wait().unwrap();
            }
        }
    }