gasket.rs
1.7 kB · rust · 63 lines
1use crate::design::Graph;2use std::collections::{BTreeSet, HashMap};34pub type Corner = (i64, i64);56pub fn edges(level: u32) -> BTreeSet<(Corner, Corner)> {7 let mut out = BTreeSet::new();8 let side = 1i64 << level;9 split(&mut out, (0, 0), (side, 0), (0, side), level);10 out11}1213fn split(out: &mut BTreeSet<(Corner, Corner)>, a: Corner, b: Corner, c: Corner, level: u32) {14 if level == 0 {15 for (one, two) in [(a, b), (b, c), (a, c)] {16 out.insert(if one < two { (one, two) } else { (two, one) });17 }18 return;19 }20 let ab = ((a.0 + b.0) / 2, (a.1 + b.1) / 2);21 let bc = ((b.0 + c.0) / 2, (b.1 + c.1) / 2);22 let ac = ((a.0 + c.0) / 2, (a.1 + c.1) / 2);23 split(out, a, ab, ac, level - 1);24 split(out, ab, b, bc, level - 1);25 split(out, ac, bc, c, level - 1);26}2728pub struct Gasket {29 pub points: Vec<Corner>,30 pub graph: Graph,31}3233pub fn build(level: u32) -> Gasket {34 let edges = edges(level);35 let points: Vec<Corner> = edges36 .iter()37 .flat_map(|edge| [edge.0, edge.1])38 .collect::<BTreeSet<_>>()39 .into_iter()40 .collect();41 let seat: HashMap<Corner, u32> = points42 .iter()43 .enumerate()44 .map(|(index, point)| (*point, index as u32))45 .collect();46 let mut adjacency: Vec<Vec<u32>> = vec![Vec::new(); points.len()];47 for edge in &edges {48 let (here, there) = (seat[&edge.0], seat[&edge.1]);49 adjacency[here as usize].push(there);50 adjacency[there as usize].push(here);51 }52 for row in adjacency.iter_mut() {53 row.sort_unstable();54 }55 Gasket {56 points,57 graph: Graph {58 shape: Vec::new(),59 cells: Vec::new(),60 adjacency,61 },62 }63}