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
//! Compass swing observations.
use crate;
use crateResult;
/// One observed heading of a swing.
///
/// Deviation is not measured directly: a bearing of an object with known true
/// bearing (transit, distant mark, celestial body) is taken by compass on each
/// heading. Deviation follows from:
///
/// ```text
/// deviation = reference bearing − variation − observed bearing
/// ```
///
/// # Example
///
/// ```rust
/// use kinavis::{
/// CompassBearing, CompassCourse, DeviationTable, NavigationError, SwingObservation,
/// TrueBearing, Variation,
/// };
///
/// fn main() -> Result<(), NavigationError> {
/// let variation = Variation::new(-2.0)?;
/// // A transit whose charted direction is 045°T, observed from four headings.
/// let transit = TrueBearing::new(45.0)?;
/// let observations = [
/// (0.0, 48.5),
/// (90.0, 46.0),
/// (180.0, 45.5),
/// (270.0, 48.0),
/// ]
/// .into_iter()
/// .map(|(heading, observed)| {
/// Ok(SwingObservation {
/// compass_heading: CompassCourse::new(heading)?,
/// observed_bearing: CompassBearing::new(observed)?,
/// reference_bearing: transit,
/// })
/// })
/// .collect::<Result<Vec<_>, NavigationError>>()?;
///
/// let table = DeviationTable::from_swing(&observations, variation)?;
///
/// // On north the compass read 048.5 for something that is really 045.0,
/// // with 2°W variation: deviation is 045.0 − (−2.0) − 048.5 = −1.5°.
/// assert_eq!(table.deviation_at_node(0).unwrap().degrees(), -1.5);
/// Ok(())
/// }
/// ```