diff options
| -rw-r--r-- | src/state.rs | 139 |
1 files changed, 97 insertions, 42 deletions
diff --git a/src/state.rs b/src/state.rs index 1793388..4c1f0d4 100644 --- a/src/state.rs +++ b/src/state.rs @@ -126,58 +126,113 @@ impl State { } pub fn find_poly(&self) -> Vec<&Point> { - let p1 = Point::new(0.0, 0.0); - let p2 = Point::new(1.0, 0.0); - let mut last_line = Line::new(&p1, &p2); - let mut xxx = 100; - let mut res = vec![&self.points[0]]; - loop { - let last = res.last().expect("something in res"); - let mut min_theta = TAU; - let mut min_p = &self.points[0]; - for p in &self.points { - if !last.equal_pos(p) { - let l2 = Line::new(last, p); - let theta = last_line.angle_between(&l2); - if theta < min_theta { - min_theta = theta; - min_p = p; - } - } - } - last_line = Line::new(res.last().expect("something in res"), min_p); - res.push(min_p); + find_poly_helper(&self.points) + } + + fn bounce_points(&mut self) -> bool { + bounce_points_helper(&mut self.points) + } + + fn move_points(&mut self) { + move_points_helper(&mut self.points); + } +} - xxx -= 1; - if xxx == 0 || res[0].equal_pos(res.last().expect("something in res")) { - break; +fn bounce_points_helper(points: &mut Vec<Point>) -> bool { + let mut did_bounce = false; + for p in points { + let x = p.x + p.speed_x(); + let y = p.y + p.speed_y(); + + if x < 0.0 || x >= 1.0 { + p.heading = PI - p.heading; + did_bounce = true; + } else if y < 0.0 || y >= 1.0 { + p.heading = -p.heading; + did_bounce = true; + } + } + did_bounce +} + +fn move_points_helper(points: &mut Vec<Point>) { + for p in points { + p.x += p.speed_x(); + p.y += p.speed_y(); + } +} + +fn find_poly_helper(points: &Vec<Point>) -> Vec<&Point> { + let p1 = Point::new(0.0, 0.0); + let p2 = Point::new(1.0, 0.0); + let mut last_line = Line::new(&p1, &p2); + let mut xxx = 100; + let mut res = vec![&points[0]]; + loop { + let last = res.last().expect("something in res"); + let mut min_theta = TAU; + let mut min_p = &points[0]; + for p in points { + if !last.equal_pos(p) { + let l2 = Line::new(last, p); + let theta = last_line.angle_between(&l2); + if theta < min_theta { + min_theta = theta; + min_p = p; + } } } + last_line = Line::new(res.last().expect("something in res"), min_p); + res.push(min_p); - res + xxx -= 1; + if xxx == 0 || res[0].equal_pos(res.last().expect("something in res")) { + break; + } } - fn bounce_points(&mut self) -> bool { - let mut did_bounce = false; - for p in &mut self.points { - let x = p.x + p.speed_x(); - let y = p.y + p.speed_y(); + res +} + +#[cfg(test)] +mod test { + use super::*; + + use std::hint::black_box; + use std::time::Instant; - if x < 0.0 || x >= 1.0 { - p.heading = PI - p.heading; - did_bounce = true; - } else if y < 0.0 || y >= 1.0 { - p.heading = -p.heading; - did_bounce = true; + fn update(points: &mut Vec<Point>) { + black_box(bounce_points_helper(points)); + black_box(move_points_helper(points)); + points.sort_by(|a, b| { + if a.y > b.y { + std::cmp::Ordering::Greater + } else if a.y == b.y { + std::cmp::Ordering::Equal + } else { + std::cmp::Ordering::Less } - } - did_bounce + }); + black_box(find_poly_helper(points)); } - fn move_points(&mut self) { - for p in &mut self.points { - p.x += p.speed_x(); - p.y += p.speed_y(); + #[test] + fn bench_update() { + println!("in bench_update(), you remembered cargo test -- --nocapture."); + let point_count = 40; + let iters = 10_000; + + let mut points: Vec<Point> = (0..point_count) + .map(|_| Point::new(fastrand::f64(), fastrand::f64())) + .collect(); + + let start = Instant::now(); + for _ in 0..iters { + black_box(update(&mut points)); } + let delta = start.elapsed(); + let smaller: f64 = u32::try_from(delta.as_millis()).unwrap().into(); + let iters_per_ms = Into::<f64>::into(iters) / smaller; + println!("{iters} iters in {smaller} ms ({iters_per_ms:0.2} iters per ms)"); } } |
