use nalgebra::{Point2, Vector2};
use std::collections::{HashMap, HashSet};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Admit {
Accept,
Reject,
}
#[derive(Clone, Copy, Debug)]
pub struct LabelledNeighbour {
pub idx: usize,
pub at: (i32, i32),
pub position: Point2<f32>,
}
pub trait SquareAttachPolicy {
fn is_eligible(&self, idx: usize) -> bool;
fn required_label_at(&self, i: i32, j: i32) -> Option<u8>;
fn label_of(&self, idx: usize) -> Option<u8>;
fn accept_candidate(
&self,
idx: usize,
at: (i32, i32),
prediction: Point2<f32>,
neighbours: &[LabelledNeighbour],
) -> Admit;
fn edge_ok(
&self,
_candidate_idx: usize,
_neighbour_idx: usize,
_at_candidate: (i32, i32),
_at_neighbour: (i32, i32),
) -> bool {
true
}
fn eligible_for_fill(&self, idx: usize) -> bool {
self.is_eligible(idx)
}
fn fill_edge_ok(&self, ctx: FillEdgeCtx<'_>) -> bool {
self.edge_ok(
ctx.candidate_idx,
ctx.neighbour_idx,
ctx.at_candidate,
ctx.at_neighbour,
)
}
}
#[non_exhaustive]
#[derive(Clone, Copy)]
pub struct FillEdgeCtx<'a> {
pub candidate_idx: usize,
pub neighbour_idx: usize,
pub at_candidate: (i32, i32),
pub at_neighbour: (i32, i32),
pub labelled: &'a HashMap<(i32, i32), usize>,
pub positions: &'a [Point2<f32>],
pub cell_size: f32,
}
#[non_exhaustive]
#[derive(Clone, Copy, Debug)]
pub struct GrowParams {
pub attach_search_rel: f32,
pub attach_ambiguity_factor: f32,
pub boundary_search_factor: f32,
}
impl Default for GrowParams {
fn default() -> Self {
Self {
attach_search_rel: 0.35,
attach_ambiguity_factor: 1.5,
boundary_search_factor: 2.0,
}
}
}
impl GrowParams {
pub fn new(attach_search_rel: f32, attach_ambiguity_factor: f32) -> Self {
Self {
attach_search_rel,
attach_ambiguity_factor,
..Self::default()
}
}
}
#[derive(Debug, Default)]
pub struct GrowResult {
pub labelled: HashMap<(i32, i32), usize>,
pub by_corner: HashMap<usize, (i32, i32)>,
pub ambiguous: HashSet<(i32, i32)>,
pub holes: HashSet<(i32, i32)>,
pub axis_i: Vector2<f32>,
pub axis_j: Vector2<f32>,
pub rebase_i_mod2: i32,
pub rebase_j_mod2: i32,
}