projective_grid/feature/
mod.rs1use nalgebra::Point2;
15
16use crate::lattice::Coord;
17
18#[derive(Clone, Copy, Debug, PartialEq)]
20#[non_exhaustive]
21pub struct PointFeature {
22 pub source_index: usize,
24 pub position: Point2<f32>,
26}
27
28impl PointFeature {
29 pub fn new(source_index: usize, position: Point2<f32>) -> Self {
31 Self {
32 source_index,
33 position,
34 }
35 }
36}
37
38#[derive(Clone, Copy, Debug, PartialEq)]
40#[non_exhaustive]
41pub struct LocalAxis {
42 pub angle_rad: f32,
44 pub sigma_rad: Option<f32>,
46}
47
48impl LocalAxis {
49 pub fn new(angle_rad: f32, sigma_rad: Option<f32>) -> Self {
51 Self {
52 angle_rad,
53 sigma_rad,
54 }
55 }
56}
57
58#[derive(Clone, Copy, Debug, PartialEq)]
60#[non_exhaustive]
61pub struct OrientedFeature<const N: usize> {
62 pub point: PointFeature,
64 pub axes: [LocalAxis; N],
66}
67
68impl<const N: usize> OrientedFeature<N> {
69 pub fn new(point: PointFeature, axes: [LocalAxis; N]) -> Self {
71 Self { point, axes }
72 }
73}
74
75#[derive(Clone, Copy, Debug, PartialEq)]
77#[non_exhaustive]
78pub struct CoordinateHypothesis {
79 pub source_index: usize,
81 pub coord: Coord,
83 pub confidence: Option<f32>,
86}
87
88impl CoordinateHypothesis {
89 pub fn new(source_index: usize, coord: Coord, confidence: Option<f32>) -> Self {
91 Self {
92 source_index,
93 coord,
94 confidence,
95 }
96 }
97
98 pub fn unweighted(source_index: usize, coord: Coord) -> Self {
100 Self::new(source_index, coord, None)
101 }
102}
103
104#[cfg(test)]
105mod tests {
106 use nalgebra::Point2;
107
108 use super::*;
109
110 #[test]
111 fn point_feature_constructs() {
112 let p = PointFeature::new(7, Point2::new(1.0_f32, 2.0));
113 assert_eq!(p.source_index, 7);
114 assert_eq!(p.position, Point2::new(1.0, 2.0));
115 }
116
117 #[test]
118 fn oriented_feature_arities_construct() {
119 let p = PointFeature::new(0, Point2::new(0.0_f32, 0.0));
120 let a = LocalAxis::new(0.0, Some(0.1));
121 let one = OrientedFeature::<1>::new(p, [a]);
122 let two = OrientedFeature::<2>::new(p, [a, LocalAxis::new(1.0, None)]);
123 let three =
124 OrientedFeature::<3>::new(p, [a, LocalAxis::new(1.0, None), LocalAxis::new(2.0, None)]);
125 assert_eq!(one.axes.len(), 1);
126 assert_eq!(two.axes.len(), 2);
127 assert_eq!(three.axes.len(), 3);
128 }
129
130 #[test]
131 fn coordinate_hypothesis_constructs() {
132 let h = CoordinateHypothesis::new(3, Coord::new(4, -2), Some(0.9_f32));
133 assert_eq!(h.source_index, 3);
134 assert_eq!(h.coord, Coord::new(4, -2));
135 assert_eq!(h.confidence, Some(0.9));
136 }
137
138 #[test]
139 fn coordinate_hypothesis_unweighted_has_no_confidence() {
140 let h = CoordinateHypothesis::unweighted(7, Coord::new(1, 2));
141 assert_eq!(h.source_index, 7);
142 assert_eq!(h.coord, Coord::new(1, 2));
143 assert_eq!(h.confidence, None);
144 }
145}