Skip to main content

ElevationLaw

Enum ElevationLaw 

Source
#[non_exhaustive]
pub enum ElevationLaw { Polynomial { coefficients: Vec<f64>, }, Piecewise { breaks: Vec<f64>, laws: Vec<ElevationLaw>, }, CircularArc { height: f64, grade: f64, radius: f64, }, Intrinsic { height: f64, grade: f64, 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
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

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.

Fields

§coefficients: Vec<f64>

Coefficients in ascending powers of plan distance.

§

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

§breaks: Vec<f64>

Interior seam positions in plan distance, ascending.

§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 / R
  • z(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

§height: f64

Height at the piece start.

§grade: f64

Grade dz/dd at the piece start.

§radius: f64

Signed radius: positive sag, negative crest. Finite and non-zero.

§

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.

Fields

§height: f64

Height at the piece start.

§grade: f64

Grade dz/dd at the piece start.

§curvature: CurvatureLaw

Curvature against the profile’s own arc length from its start.

Implementations§

Source§

impl ElevationLaw

Source

pub fn level(height: f64) -> ElevationLaw

A constant height.

Source

pub fn constant_grade(height: f64, grade: f64) -> ElevationLaw

A constant gradient: z(d) = height + grade * d.

Source

pub fn parabolic( height: f64, entry_grade: f64, exit_grade: f64, length: f64, ) -> ElevationLaw

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.

Source

pub const fn circular_arc(height: f64, grade: f64, radius: f64) -> ElevationLaw

A circular vertical arc from height at grade, of signed radius (positive sag, negative crest). See Self::CircularArc.

Source

pub const fn intrinsic( height: f64, grade: f64, curvature: CurvatureLaw, ) -> ElevationLaw

A profile from height at grade whose curvature runs along its own arc length. See Self::Intrinsic.

Source

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).

Source

pub fn height_at(&self, distance: f64) -> Option<f64>

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.

Source

pub fn grade_at(&self, distance: f64) -> Option<f64>

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.

Source

pub fn piece_at(&self, distance: f64) -> Option<(&ElevationLaw, f64)>

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

Source§

fn clone(&self) -> ElevationLaw

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ElevationLaw

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for ElevationLaw

Source§

fn deserialize<__D>( __deserializer: __D, ) -> Result<ElevationLaw, <__D as Deserializer<'de>>::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl PartialEq for ElevationLaw

Source§

fn eq(&self, other: &ElevationLaw) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl Serialize for ElevationLaw

Source§

fn serialize<__S>( &self, __serializer: __S, ) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for ElevationLaw

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.