#[derive(Debug, Clone)] pub struct Domain { pub width: usize, pub height: usize, pub cells: Vec<(f64, f64)>, pub enabled: Vec, } impl Domain { pub fn empty(width: usize, height: usize) -> Self { let grid_size = (width+2)*(height*2); let cells = core::iter::repeat_n((0.0, 0.0), grid_size).collect(); let mut enabled: Vec = core::iter::repeat_n(1.0, grid_size).collect(); for x in 0..width+2 { *enabled.get_mut(x).unwrap() = 0.0; *enabled.get_mut((height+1)*width + x).unwrap() = 0.0; } for y in 0..height+2 { *enabled.get_mut(y*width + 0).unwrap() = 0.0; *enabled.get_mut(y*width + width-1).unwrap() = 0.0; } Domain { width, height, cells, enabled } } pub fn get_mut(&mut self, x: usize, y: usize) -> Option<&mut (f64, f64)> { self.cells.get_mut((y + 1)*self.width + x + 1) } } pub fn simulate(start: &mut Domain) { let dT: f64 = 1.0 / 30.0; for i in 0..25 { for y in 1..start.height-1 { for x in 1..start.width-1 { let own_cell_idx = y * start.width + x; let top_cell_idx = (y-1) * start.width + x; let right_cell_idx = y * start.width + x + 1; let own_cell = start.cells.get(own_cell_idx).copied().unwrap(); let top_cell = start.cells.get(top_cell_idx).copied().unwrap(); let right_cell = start.cells.get(right_cell_idx).copied().unwrap(); let d = right_cell.0 - own_cell.0 + top_cell.1 - own_cell.1; let s_right = start.enabled.get(y*start.width+x+1).copied().unwrap(); let s_left = start.enabled.get(y*start.width+x-1).copied().unwrap(); let s_top = start.enabled.get((y-1)*start.width+x).copied().unwrap(); let s_bot = start.enabled.get((y+1)*start.width+x).copied().unwrap(); let total = s_right + s_left + s_top + s_bot; start.cells.get_mut(own_cell_idx).unwrap().0 = own_cell.0 + d*(s_left/total); start.cells.get_mut(own_cell_idx).unwrap().1 = own_cell.1 + d*(s_top/total); start.cells.get_mut(right_cell_idx).unwrap().0 = right_cell.0 - d*(s_right/total); start.cells.get_mut(top_cell_idx).unwrap().1 = top_cell.1 - d*(s_bot/total); } } } // Advaction simulate_advaction(start, dT); } fn simulate_advaction(start: &mut Domain, dT: f64) { for y in 1..start.height-1 { for x in 1..start.width-1 { let own_cell_idx = y * start.width + x; let own_cell = start.cells.get(own_cell_idx).copied().unwrap(); let u = own_cell.0; let v = (own_cell.1 + start.cells.get(y * start.width + x - 1).copied().unwrap().1 + start.cells.get((y-1) * start.width + x).copied().unwrap().1 + start.cells.get((y-1) * start.width + x - 1).copied().unwrap().1) / 4.0; let prev_x = x as f64 + 0.5 - dT*u; let prev_y = y as f64 + 0.5 - dT*v; println!("[AD] ({}, {}) --({}, {})--> ({}, {})", x, y, u, v, prev_x, prev_y); let cell = (prev_x.round() as usize, prev_y.round() as usize); let cell_left = (cell.0 - 1, cell.1); let cell_left_top = (cell.0 - 1, cell.1 - 1); let cell_top = (cell.0, cell.1 - 1); println!("[AD] Right-B {:?} - Left-B {:?} - Right-T {:?} - Left-T {:?}", cell, cell_left, cell_top, cell_left_top); let w00 = 1.0 - (prev_x - (cell_left.0 as f64 + 0.5))/1.0; let w01 = (prev_x - (cell_left.0 as f64 + 0.5))/1.0; let w10 = 1.0 - (prev_y - (cell_left.1 as f64 + 0.5))/1.0; let w11 = (prev_y - (cell_left.1 as f64 + 0.5))/1.0; println!("W00 {} - W01 {} - W10 {} - W11 {}", w00, w01, w10, w11); } } } #[cfg(test)] mod tests { use super::*; #[test] fn advaction_x_only() { let input = Domain::empty(6, 6); let mut target = input.clone(); target.get_mut(2, 2).unwrap().0 = 1.0; println!("{:?}", target); simulate_advaction(&mut target, 0.1); println!("{:?}", target); assert!(false); } }