1use nv_core::AffineTransform2D;
4
5use crate::view_state::ViewVersion;
6
7#[derive(Clone, Debug, PartialEq)]
12pub struct GlobalTransformEstimate {
13 pub transform: AffineTransform2D,
15 pub confidence: f32,
17 pub method: TransformEstimationMethod,
19 pub computed_at: ViewVersion,
23}
24
25impl GlobalTransformEstimate {
26 #[must_use]
31 pub fn displacement_magnitude(&self) -> f32 {
32 let tx = self.transform.m[2];
33 let ty = self.transform.m[5];
34 (tx * tx + ty * ty).sqrt() as f32
35 }
36}
37
38#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
40pub enum TransformEstimationMethod {
41 PtzModel,
43 FeatureMatching,
45 External,
47}
48
49#[cfg(test)]
50mod tests {
51 use super::*;
52 use nv_core::AffineTransform2D;
53
54 fn identity_transform() -> GlobalTransformEstimate {
55 GlobalTransformEstimate {
56 transform: AffineTransform2D::IDENTITY,
57 confidence: 1.0,
58 method: TransformEstimationMethod::FeatureMatching,
59 computed_at: ViewVersion::new(1),
60 }
61 }
62
63 #[test]
64 fn identity_has_zero_displacement() {
65 let est = identity_transform();
66 assert!((est.displacement_magnitude() - 0.0).abs() < 1e-6);
67 }
68
69 #[test]
70 fn translation_displacement() {
71 let est = GlobalTransformEstimate {
72 transform: AffineTransform2D {
74 m: [1.0, 0.0, 0.3, 0.0, 1.0, 0.4],
75 },
76 confidence: 0.9,
77 method: TransformEstimationMethod::PtzModel,
78 computed_at: ViewVersion::new(2),
79 };
80 assert!((est.displacement_magnitude() - 0.5).abs() < 1e-5);
81 }
82
83 #[test]
84 fn clone_eq() {
85 let est = identity_transform();
86 assert_eq!(est, est.clone());
87 }
88}