diff --git a/src/main.rs b/src/main.rs index 2d102e0..92cdff9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,9 +4,9 @@ use anyhow::Result; use clap::{app_from_crate, crate_authors, crate_description, crate_name, crate_version, Arg}; use io::Write; use lasy::{ - euler_graph_to_euler_circuit, interpolate_euler_circuit, point_graph_to_euler_graph, - points_to_segments, segments_to_point_graph, Blanked, InterpolationConfig, IsBlank, Lerp, - Position, Weight, + blank_segment_points, euler_graph_to_euler_circuit, interpolate_euler_circuit, + point_graph_to_euler_graph, points_to_segments, segments_to_point_graph, Blanked, + InterpolationConfig, IsBlank, Lerp, Position, Weight, }; type InputArrayEntry = (f32, f32, u32); @@ -50,14 +50,14 @@ impl Position for Point { impl IsBlank for Point { fn is_blank(&self) -> bool { - self.color == 0xffffff + self.color == 0 } } impl Blanked for Point { fn blanked(&self) -> Self { Self { - color: 0xffffff, + color: 0, ..*self } } @@ -99,7 +99,11 @@ impl Lerp for Point { } } -fn optimize_line(default_weight: u32, line: &str) -> Result> { +fn optimize_line( + default_weight: u32, + line: &str, + config: &InterpolationConfig, +) -> Result> { let frame: Vec = serde_json::from_str(line)?; let input_points: Vec = frame @@ -116,13 +120,8 @@ fn optimize_line(default_weight: u32, line: &str) -> Result let pg = segments_to_point_graph(&input_points, segs); let eg = point_graph_to_euler_graph(&pg); let ec = euler_graph_to_euler_circuit(&input_points, &eg); - let output_points: Vec = interpolate_euler_circuit( - &input_points, - &ec, - &eg, - input_points.len() as u32, - &InterpolationConfig::default(), - ); + let output_points: Vec = + interpolate_euler_circuit(&input_points, &ec, &eg, input_points.len() as u32, config); let output_frame: Vec<_> = output_points.iter().map(|p| (p.x, p.y, p.color)).collect(); @@ -131,20 +130,97 @@ fn optimize_line(default_weight: u32, line: &str) -> Result fn main() -> Result<()> { let matches = app_from_crate!() - .args(&[Arg::with_name("default-weight") - .short("w") - .takes_value(true) - .multiple(false) - .default_value("0")]) + .args(&[ + Arg::with_name("default-weight") + .short("w") + .takes_value(true) + .multiple(false) + .default_value("0"), + Arg::with_name("distance-per-point") + .short("d") + .takes_value(true) + .multiple(false), + Arg::with_name("blank-delay-points") + .short("b") + .takes_value(true) + .multiple(false), + Arg::with_name("radians-per-point") + .short("r") + .takes_value(true) + .multiple(false), + ]) .get_matches(); let default_weight = matches.value_of("default-weight").unwrap().parse().unwrap(); + let mut config = InterpolationConfig::default(); + + if let Some(distance_per_point) = matches.value_of("distance-per-point") { + config.distance_per_point = distance_per_point + .parse() + .expect("distance-per-point must be a float") + } + + if let Some(blank_delay_points) = matches.value_of("blank-delay-points") { + config.blank_delay_points = blank_delay_points + .parse() + .expect("blank-delay-points must be an unsigned integer") + } + + if let Some(radians_per_point) = matches.value_of("radians-per-point") { + config.radians_per_point = radians_per_point + .parse() + .expect("radians-per-point must be a float") + } + + let mut last_frames = vec![]; loop { let mut line = String::new(); io::stdin().read_line(&mut line)?; - serde_json::to_writer(io::stdout(), &optimize_line(default_weight, &line)?)?; + last_frames.push(optimize_line(default_weight, &line, &config)?); + + if last_frames.len() == 2 { + let a: Vec = last_frames + .first() + .unwrap() + .iter() + .map(|(x, y, color)| Point { + x: *x, + y: *y, + color: *color, + weight: default_weight, + }) + .collect(); + + let b: Vec = last_frames + .last() + .unwrap() + .iter() + .map(|(x, y, color)| Point { + x: *x, + y: *y, + color: *color, + weight: default_weight, + }) + .collect(); + + let c: Vec = a + .into_iter() + .zip(b.into_iter()) + .map(|(a, b)| blank_segment_points(a, b, config.blank_delay_points)) + .flatten() + .map(|p| (p.x, p.y, p.color)) + .collect(); + + serde_json::to_writer(io::stdout(), &c)?; + io::stdout().write(b"\n")?; + io::stdout().flush()?; + + last_frames.remove(0); + } + + serde_json::to_writer(io::stdout(), &last_frames.last())?; io::stdout().write(b"\n")?; io::stdout().flush()?; } @@ -152,5 +228,5 @@ fn main() -> Result<()> { #[test] fn optimize_line_test() { - optimize_line(0, "[[100.0, 100.0, 65280], [100.0, 500.0, 65280], [500.0, 500.0, 65280], [500.0, 100.0, 65280], [100.0, 100.0, 65280]]").unwrap(); + optimize_line(0, "[[100.0, 100.0, 65280], [100.0, 500.0, 65280], [500.0, 500.0, 65280], [500.0, 100.0, 65280], [100.0, 100.0, 65280]]", &InterpolationConfig::default()).unwrap(); }