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}