proof_engine/ecology/
migration.rs1#[derive(Debug, Clone)]
5pub struct MigrationRoute {
6 pub species_id: u32,
7 pub waypoints: Vec<(f32, f32)>,
8 pub season_start: f32, pub season_end: f32,
10 pub fraction: f64, }
12
13pub fn route_position(route: &MigrationRoute, time_of_year: f32) -> Option<(f32, f32)> {
15 if route.waypoints.len() < 2 { return None; }
16 let t = time_of_year;
17 if t < route.season_start || t > route.season_end { return None; }
18
19 let progress = (t - route.season_start) / (route.season_end - route.season_start);
20 let segment_f = progress * (route.waypoints.len() - 1) as f32;
21 let seg = (segment_f as usize).min(route.waypoints.len() - 2);
22 let local_t = segment_f - seg as f32;
23
24 let (x0, y0) = route.waypoints[seg];
25 let (x1, y1) = route.waypoints[seg + 1];
26 Some((x0 + (x1 - x0) * local_t, y0 + (y1 - y0) * local_t))
27}
28
29#[cfg(test)]
30mod tests {
31 use super::*;
32
33 #[test]
34 fn test_migration_position() {
35 let route = MigrationRoute {
36 species_id: 0,
37 waypoints: vec![(0.0, 0.0), (10.0, 0.0), (10.0, 10.0)],
38 season_start: 0.2,
39 season_end: 0.8,
40 fraction: 0.5,
41 };
42 let pos = route_position(&route, 0.5).unwrap();
43 assert!(pos.0 > 0.0, "should have moved");
44 }
45}