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
        1
        ·
        4 days ago

        You clearly have more patience than me! I assumed that at 16x, it would be way to easy to blink and miss it.

    • CameronDevOPM
      link
      fedilink
      arrow-up
      2
      ·
      5 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();
              }
          }
      }