1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
//! Deviation tables and their interpolation.
//!
//! A deviation table gives, for a set of compass headings, the displacement of
//! compass north from magnetic north caused by the ship's magnetism:
//!
//! ```text
//! magnetic course = compass course + deviation(compass course)
//! ```
//!
//! Deviation is a *periodic* function of the **compass** course, and is treated
//! as such throughout.
//!
//! # Interpolation methods
//!
//! | Method | Continuity | Nodes needed | Use when |
//! |---|---|---|---|
//! | [`InterpolationMethod::Linear`] | C⁰ | 2 | results must never overshoot tabulated values |
//! | [`InterpolationMethod::Cubic`] | C² | 3 | dense swing, smooth curve wanted |
//! | [`InterpolationMethod::Parametric`] | analytic | 5 | classical A–E model, or smoothing a noisy swing |
//!
//! All are periodic: the arc from the last node through `360°/0°` to the first
//! is a real interval, not a flat extrapolation.
//!
//! # Example
//!
//! ```rust
//! use kinavis::{CompassCourse, Deviation, DeviationTable, InterpolationMethod};
//!
//! let mut table = DeviationTable::from_step(90)?;
//! table.set_deviation(0, Deviation::new(10.0)?)?;
//! table.set_deviation(180, Deviation::new(-10.0)?)?;
//!
//! // Halfway between the 270° node (0.0) and the 0° node (10.0), the long way
//! // round through north — a segment a naive lookup does not see.
//! let deviation = table.deviation_at(CompassCourse::new(315.0)?, InterpolationMethod::Linear)?;
//! assert!((deviation.degrees() - 5.0).abs() < 1e-12);
//! # Ok::<(), kinavis::NavigationError>(())
//! ```
//! # Structure
//!
//! The table stores observations; numerical methods are services on it, so new
//! reading methods never modify the storage type.
//!
//! - `table` — [`DeviationTable`]: storage, invariants, mutators.
//! - `node`, `swing` — a table row ([`DeviationNode`]) and an observed heading
//! ([`SwingObservation`]).
//! - `interpolation` — the four reading methods.
//! - `ring` — nodes as a closed circle.
//! - `smith` — five-coefficient model and least-squares fit,
//! [`smith_coefficients`].
//! - `analysis` — residuals, extremes, spacing, invertibility, [`analyze`].
//! - `model` — table and coefficients as the kernel's
//! [`CompassModel`](kinavis_kernel::environment::CompassModel);
//! [`InterpolatedTable`] for a table with a prepared reading.
//!
//! Submodules are private; types are re-exported flat
//! (`deviation::DeviationTable`).
pub use ;
pub use ;
pub use InterpolatedTable;
pub use DeviationNode;
pub use ;
pub use SwingObservation;
pub use ;