use super::layout::{edge_notch, footprint, signed_area};
use crate::gerber::layers::{PcbComponentElm, PcbPoint};
#[derive(Debug, Clone, PartialEq)]
pub(super) struct EdgeContact {
pub edge: usize,
pub normal: [f64; 2],
pub span: [[f64; 2]; 2],
}
pub(super) fn edge_normal(a: PcbPoint, b: PcbPoint, winding: f64) -> Option<(f64, f64)> {
let len = (b.x - a.x).hypot(b.y - a.y);
(len > 0.0).then(|| ((b.y - a.y) / len * winding, -(b.x - a.x) / len * winding))
}
pub(super) fn edge_contacts(component: &PcbComponentElm, outline: &[PcbPoint]) -> Vec<EdgeContact> {
let Some(corners) = footprint(component) else {
return Vec::new();
};
let winding = signed_area(outline).signum();
(0..outline.len())
.filter_map(|edge| {
let (a, b) = (outline[edge], outline[(edge + 1) % outline.len()]);
let notch = edge_notch(&corners, a, b, winding, 1.0)?;
let (nx, ny) = edge_normal(a, b, winding)?;
Some(EdgeContact {
edge,
normal: [nx, ny],
span: [notch.points[0], notch.points[1]],
})
})
.collect()
}