#[non_exhaustive]pub enum ElevationLaw {
Polynomial {
coefficients: Vec<Scalar>,
},
Piecewise {
breaks: Vec<Scalar>,
laws: Vec<ElevationLaw>,
},
CircularArc {
height: Scalar,
grade: Scalar,
radius: Scalar,
},
Intrinsic {
height: Scalar,
grade: Scalar,
curvature: CurvatureLaw,
},
}Expand description
Height as a function of distance along the plan.
Mirrors CurvatureLaw in shape so the two halves of
an alignment read the same way, but stays a separate type: a curvature law
is a property of a planar curve and an elevation law is not, and sharing one
enum would make a meaningless pairing representable.
Dirty imported data stays representable, as everywhere else in this crate.
Mismatched piece lists report None rather than guessing.
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
Polynomial
z(d) = coefficients[0] + coefficients[1] * d + coefficients[2] * d^2 + ...
Degree 1 is a constant gradient, degree 2 the parabolic vertical curve used to join two grades. Those are the two vertical segment kinds that carry most alignment data, and both are exact here.
An empty coefficient list is the zero polynomial: height zero.
Piecewise
Pieces laid end to end along plan distance, each with its own law.
breaks holds the INTERIOR seam positions measured from the start, so
laws.len() == breaks.len() + 1 and piece i spans
breaks[i - 1] .. breaks[i].
Each piece’s law is written in its OWN distance, restarting at zero at
its seam, so moving a piece never rewrites its coefficients. This
matches CurvatureLaw::Piecewise
deliberately: a vertical profile is authored as a run of segments and
the seams are observable data.
Fields
laws: Vec<ElevationLaw>One law per piece; laws.len() == breaks.len() + 1.
CircularArc
A circular arc in the (d, z) plane: the grade angle changes at a
constant rate along the profile’s own arc length.
With t0 = atan(grade) and the signed radius R (positive is a
sag, turning counter-clockwise in (d, z); negative is a crest):
sin t(d) = sin t0 + d / Rz(d) = height + R (cos t0 - cos t(d))grade(d) = tan t(d)
This is the circle itself, not the parabola d^2 / (2R) that
approximates it near the vertex; the two differ by O(d^4 / R^3).
The arc has heights only while |sin t0 + d / R| < 1: past that the
circle turns vertical, and height_at and grade_at report None.
Evaluated without cancellation: R (cos t0 - cos t(d)) is computed
as d (sin t(d) + sin t0) / (cos t0 + cos t(d)), which removes the
difference of nearly equal cosines that d / R -> 0 would otherwise
multiply by a large R.
Fields
Intrinsic
A profile given by its curvature against its OWN arc length.
The vertical counterpart of Curve2::Intrinsic: a planar curve in
(d, z) starting at (0, height) in the direction atan(grade),
whose curvature is curvature(s) with s the arc length of the
profile (not plan distance), positive counter-clockwise in (d, z)
– a sag. A linear law is the clothoid joining two grades; a constant
law is the circular arc that Self::CircularArc holds in closed
form.
Height at a plan distance has no closed form (see the module
documentation), so height_at and grade_at report None, and an
evaluator integrates the curve and inverts d(s) to a stated
tolerance. Only d >= 0 is defined, since the law is integrated
forward from its start, and only while d(s) keeps increasing.
Implementations§
Source§impl ElevationLaw
impl ElevationLaw
Sourcepub fn constant_grade(height: Scalar, grade: Scalar) -> Self
pub fn constant_grade(height: Scalar, grade: Scalar) -> Self
A constant gradient: z(d) = height + grade * d.
Sourcepub fn parabolic(
height: Scalar,
entry_grade: Scalar,
exit_grade: Scalar,
length: Scalar,
) -> Self
pub fn parabolic( height: Scalar, entry_grade: Scalar, exit_grade: Scalar, length: Scalar, ) -> Self
A parabolic vertical curve joining entry_grade to exit_grade over
length.
The rate of change of grade is (exit - entry) / length, so
z(d) = height + entry * d + (exit - entry) / (2 * length) * d^2.
A non-positive length is storable; naming it is a validator’s job.
Sourcepub const fn circular_arc(height: Scalar, grade: Scalar, radius: Scalar) -> Self
pub const fn circular_arc(height: Scalar, grade: Scalar, radius: Scalar) -> Self
A circular vertical arc from height at grade, of signed radius
(positive sag, negative crest). See Self::CircularArc.
Sourcepub const fn intrinsic(
height: Scalar,
grade: Scalar,
curvature: CurvatureLaw,
) -> Self
pub const fn intrinsic( height: Scalar, grade: Scalar, curvature: CurvatureLaw, ) -> Self
A profile from height at grade whose curvature runs along its own
arc length. See Self::Intrinsic.
Sourcepub fn is_well_formed(&self) -> bool
pub fn is_well_formed(&self) -> bool
Whether the piece lists agree and the seams ascend, and every stored number is finite (an arc’s radius also non-zero).
Sourcepub fn height_at(&self, distance: Scalar) -> Option<Scalar>
pub fn height_at(&self, distance: Scalar) -> Option<Scalar>
Height at distance along the plan.
Returns None when the law is malformed or the distance is not finite,
rather than extrapolating off a piece that does not exist.
Sourcepub fn grade_at(&self, distance: Scalar) -> Option<Scalar>
pub fn grade_at(&self, distance: Scalar) -> Option<Scalar>
Grade – dz/dd – at distance along the plan.
This is the slope the 3D tangent needs, and it is why the polynomial is differentiated exactly rather than differenced.
Sourcepub fn piece_at(&self, distance: Scalar) -> Option<(&Self, Scalar)>
pub fn piece_at(&self, distance: Scalar) -> Option<(&Self, Scalar)>
The innermost piece covering distance, and that distance rebased
to the piece’s own start.
Descends through nested Self::Piecewise laws, so the returned law
is never piecewise; any other law is its own piece at the unchanged
distance. Seams belong to the piece that starts there, as in
height_at (SeamSide::Outgoing). None when the distance is not finite or a piece list
is malformed.
This is what an evaluator needs to read a law it evaluates itself
(an Self::Intrinsic piece) inside a composed profile.
Trait Implementations§
Source§impl Clone for ElevationLaw
impl Clone for ElevationLaw
Source§fn clone(&self) -> ElevationLaw
fn clone(&self) -> ElevationLaw
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more