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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
//! Domain-agnostic conic geometry primitives.
//!
//! This module models conic-section shape and orientation without introducing
//! time scales, central bodies, or propagation semantics. It is the reusable
//! geometry layer that higher-level orbit or trajectory code can build on.
//!
//! ## Model
//!
//! A conic in `affn` has two independent parts:
//! - a validated shape parameterisation, carrying one characteristic length in a
//! `qtty` unit plus an eccentricity `e`;
//! - a [`ConicOrientation<F>`] tagged with a
//! [`ReferenceFrame`](crate::frames::ReferenceFrame), describing the 3-D
//! orientation of the conic plane and periapsis direction.
//!
//! [`OrientedConic<S, F>`] simply combines those two validated values.
//!
//! ## Choosing a shape type
//!
//! Use the erased runtime forms when the conic kind is not yet known:
//! - [`PeriapsisParam<U>`] stores periapsis distance `q` and supports elliptic,
//! parabolic, and hyperbolic shapes.
//! - [`SemiMajorAxisParam<U>`] stores semi-major axis `a` and supports only
//! non-parabolic shapes, so `try_new(...)` rejects `e == 1`.
//!
//! After validation, [`ConicShape::kind`] is infallible on either erased type.
//!
//! Use the typed forms when an API needs the conic family encoded in the type:
//! - [`TypedPeriapsisParam<U, K>`] brands a periapsis-based shape with
//! [`Elliptic`], [`Parabolic`], or [`Hyperbolic`].
//! - [`TypedSemiMajorAxisParam<U, K>`] brands a semi-major-axis shape with a
//! non-parabolic kind marker.
//! - [`ClassifiedPeriapsisParam<U>`] and [`ClassifiedSemiMajorAxisParam<U>`]
//! are the runtime classification results returned by `classify()`.
//! - Aliases such as [`EllipticPeriapsis<U, F>`] and
//! [`HyperbolicSemiMajorAxis<U, F>`] package the most common typed
//! [`OrientedConic`] forms.
//!
//! ## Conversion Rules
//!
//! The shape conversions preserve eccentricity:
//! - [`PeriapsisParam::to_semi_major_axis`] and the corresponding oriented
//! conversions return `None` for parabolic shapes because a semi-major axis is
//! undefined at `e == 1`.
//! - [`SemiMajorAxisParam::to_periapsis`] and the corresponding oriented
//! conversions return `None` only when the derived periapsis distance
//! overflows or becomes non-finite.
//! - Oriented conversions always preserve the reference-frame tag and the
//! existing [`ConicOrientation<F>`].
//!
//! ## Validation And `const` Construction
//!
//! Prefer `try_new(...)` in normal code so invalid distances, eccentricities,
//! and orientation angles are rejected immediately.
//!
//! For compile-time constants, `new_unchecked(...)` constructors are available
//! and skip validation. They are intended only for values whose invariants are
//! already guaranteed by the caller.
//!
//! ## Example
//!
//! ```rust
//! use affn::conic::{
//! ClassifiedPeriapsisParam, ConicKind, ConicOrientation, ConicShape,
//! OrientedConic, PeriapsisParam,
//! };
//! use affn::frames::ReferenceFrame;
//! use qtty::*;
//!
//! #[derive(Debug, Copy, Clone, PartialEq)]
//! struct Inertial;
//!
//! impl ReferenceFrame for Inertial {
//! fn frame_name() -> &'static str {
//! "Inertial"
//! }
//! }
//!
//! let shape = PeriapsisParam::try_new(7_000.0 * M, 0.42)?;
//! assert_eq!(shape.kind(), ConicKind::Elliptic);
//!
//! let ClassifiedPeriapsisParam::Elliptic(typed_shape) = shape.classify() else {
//! unreachable!("0.42 is elliptic");
//! };
//!
//! let orientation =
//! ConicOrientation::<Inertial>::try_new(28.5 * DEG, 40.0 * DEG, 15.0 * DEG)?;
//! let conic = OrientedConic::new(typed_shape, orientation);
//! let sma = conic
//! .to_semi_major_axis()
//! .expect("elliptic conics convert to semi-major-axis form");
//!
//! assert_eq!(sma.kind(), ConicKind::Elliptic);
//! assert_eq!(sma.orientation(), conic.orientation());
//! # Ok::<(), affn::conic::ConicValidationError>(())
//! ```
pub use ConicValidationError;
pub use ConicKind;
pub use ;
pub use Elliptic;
pub use Hyperbolic;
pub use Parabolic;
pub use ConicOrientation;
pub use OrientedConic;
pub use ;
pub use ;
/// Shorthand for an elliptic oriented conic expressed with periapsis distance.
pub type EllipticPeriapsis<U, F> = ;
/// Shorthand for a parabolic oriented conic expressed with periapsis distance.
pub type ParabolicPeriapsis<U, F> = ;
/// Shorthand for a hyperbolic oriented conic expressed with periapsis distance.
pub type HyperbolicPeriapsis<U, F> = ;
/// Shorthand for an elliptic oriented conic expressed with semi-major axis.
pub type EllipticSemiMajorAxis<U, F> = ;
/// Shorthand for a hyperbolic oriented conic expressed with semi-major axis.
pub type HyperbolicSemiMajorAxis<U, F> = ;