diff --git a/src/main.rs b/src/main.rs index ebc46f4..354220f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,6 +9,8 @@ extern crate image; use image::io::Reader as ImageReader; use image::{ DynamicImage }; +use std::collections::{HashMap, HashSet}; + use std::cell::RefCell; use std::rc::Rc; @@ -21,26 +23,61 @@ struct Node { pub y: f32, pub name: String, - pub edges: Vec, + pub edges: HashSet, } #[derive(Serialize, Deserialize, Debug)] struct Board { - nodes: Vec, + nodes: HashMap, } impl Board { pub fn new() -> Self { - let nodes = Vec::new(); + let nodes = HashMap::new(); Board { nodes } } pub fn add_node(&mut self, x: f32, y: f32) { - self.nodes.push(Node { + self.nodes.insert(self.next_id(), Node { x, y, name: "Canada".to_string(), - edges: vec![], + edges: HashSet::new(), }); } + + pub fn remove_node(&mut self, id: usize) { + self.nodes.remove(&id); + for (_, node) in &mut self.nodes { + node.edges.remove(&id); + } + } + + pub fn nearest_node(&self, x: f32, y: f32) -> Option { + let f = |n: &Node| dist_sq((n.x, n.y), (x, y)); + let mut iter = self.nodes.iter(); + if let Some((id, node)) = iter.next() { + let mut min = *id; + let mut min_val = f(node); + for (id, node) in iter { + let val = f(node); + if val < min_val { + min = *id; + min_val = val; + } + } + Some(min) + } else { + None + } + } + + fn next_id(&self) -> usize { + for i in 0 .. { + if !self.nodes.contains_key(&i) { + return i; + } + } + unreachable!(); + } } struct AppState { @@ -84,6 +121,10 @@ fn inv_lerp(v0: f32, v1: f32, a: f32) -> f32 { (a - v0) / (v1 - v0) } +fn dist_sq((x0, y0): (f32, f32), (x1, y1): (f32, f32)) -> f32 { + (x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0) +} + trait CoordTransformer { fn to_coords(&self, x: i32, y: i32) -> (f32, f32); fn from_coords(&self, x: f32, y: f32) -> (i32, i32); @@ -200,7 +241,7 @@ fn main() { image.draw(f.x(), f.y(), f.w(), f.h()); } let board = &state.board; - for node in &board.nodes { + for (_, node) in &board.nodes { let (x, y) = f.from_coords(node.x, node.y); draw_text(&node.name, x, y); } @@ -211,7 +252,14 @@ fn main() { Event::Push => { let mut state = state_clone.borrow_mut(); let (pos_x, pos_y) = f.to_coords(app::event_x(), app::event_y()); - state.board.add_node(pos_x, pos_y); + if app::event_button() == 1 { + state.board.add_node(pos_x, pos_y); + } else if app::event_button() == 3 { + let id = state.board.nearest_node(pos_x, pos_y); + if let Some(id) = id { + state.board.remove_node(id); + } + } app::redraw(); true }