aboutsummaryrefslogtreecommitdiffstats
path: root/src/state.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/state.rs')
-rw-r--r--src/state.rs139
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)");
}
}