Struct nalgebra_spacetime::FrameN
source · pub struct FrameN<N, D>{ /* private fields */ }
Expand description
Inertial frame of reference in $n$-dimensional Lorentzian space $\R^{-,+} = \R^{1,n-1}$.
Holds a statically sized direction axis $\hat u \in \R^{n-1}$ and two boost parameters
precomputed from either velocity $u^\mu$, rapidity $\vec \zeta$, or velocity ratio $\vec \beta$
whether using Self::from_velocity
, Self::from_zeta
, or Self::from_beta
:
$$ \cosh \zeta = \gamma $$
$$ \sinh \zeta = \beta \gamma $$
Where $\gamma$ is the Lorentz factor.
Implementations§
source§impl<N, D> FrameN<N, D>where
N: SimdRealField + Signed + Real,
D: DimNameSub<U1>,
DefaultAllocator: Allocator<N, DimNameDiff<D, U1>>,
impl<N, D> FrameN<N, D>where
N: SimdRealField + Signed + Real,
D: DimNameSub<U1>,
DefaultAllocator: Allocator<N, DimNameDiff<D, U1>>,
sourcepub fn from_velocity<R, C>(u: &OMatrix<N, R, C>) -> Selfwhere
R: DimNameSub<U1>,
C: Dim,
ShapeConstraint: SameNumberOfRows<R, D> + SameNumberOfColumns<C, U1>,
DefaultAllocator: Allocator<N, R, C>,
pub fn from_velocity<R, C>(u: &OMatrix<N, R, C>) -> Selfwhere
R: DimNameSub<U1>,
C: Dim,
ShapeConstraint: SameNumberOfRows<R, D> + SameNumberOfColumns<C, U1>,
DefaultAllocator: Allocator<N, R, C>,
Inertial frame of reference with velocity $u^\mu$.
sourcepub fn from_zeta(scaled_axis: OVector<N, DimNameDiff<D, U1>>) -> Self
pub fn from_zeta(scaled_axis: OVector<N, DimNameDiff<D, U1>>) -> Self
Inertial frame of reference with rapidity $\vec \zeta$.
sourcepub fn from_axis_zeta(
axis: Unit<OVector<N, DimNameDiff<D, U1>>>,
zeta: N
) -> Self
pub fn from_axis_zeta( axis: Unit<OVector<N, DimNameDiff<D, U1>>>, zeta: N ) -> Self
Inertial frame of reference along $\hat u$ with rapidity $\zeta$.
sourcepub fn from_beta(scaled_axis: OVector<N, DimNameDiff<D, U1>>) -> Self
pub fn from_beta(scaled_axis: OVector<N, DimNameDiff<D, U1>>) -> Self
Inertial frame of reference with velocity ratio $\vec \beta$.
sourcepub fn from_axis_beta(
axis: Unit<OVector<N, DimNameDiff<D, U1>>>,
beta: N
) -> Self
pub fn from_axis_beta( axis: Unit<OVector<N, DimNameDiff<D, U1>>>, beta: N ) -> Self
Inertial frame of reference along $\hat u$ with velocity ratio $\beta$.
sourcepub fn velocity(&self) -> OVector<N, D>where
DefaultAllocator: Allocator<N, D>,
pub fn velocity(&self) -> OVector<N, D>where
DefaultAllocator: Allocator<N, D>,
Velocity $u^\mu$.
sourcepub const fn beta_gamma(&self) -> N
pub const fn beta_gamma(&self) -> N
Product of velocity ratio $\beta$ and Lorentz factor $\gamma$.
sourcepub fn compose(&self, frame: &Self) -> Selfwhere
DefaultAllocator: Allocator<N, D>,
pub fn compose(&self, frame: &Self) -> Selfwhere
DefaultAllocator: Allocator<N, D>,
Relativistic velocity addition self
$\oplus$frame
.
Equals frame.velocity().boost(&-self.clone()).frame()
.
source§impl<N, D> FrameN<N, D>where
ShapeConstraint: DimEq<D, U4>,
N: SimdRealField + Signed + Real,
D: DimNameSub<U1>,
DefaultAllocator: Allocator<N, DimNameDiff<D, U1>>,
impl<N, D> FrameN<N, D>where
ShapeConstraint: DimEq<D, U4>,
N: SimdRealField + Signed + Real,
D: DimNameSub<U1>,
DefaultAllocator: Allocator<N, DimNameDiff<D, U1>>,
sourcepub fn axis_angle(
&self,
frame: &Self
) -> (Unit<OVector<N, DimNameDiff<D, U1>>>, N)
pub fn axis_angle( &self, frame: &Self ) -> (Unit<OVector<N, DimNameDiff<D, U1>>>, N)
$
\gdef \Bu {B^{\mu’}_{\phantom {\mu’} \mu} (\vec \beta_u)}
\gdef \Bv {B^{\mu’‘}_{\phantom {\mu’‘} \mu’} (\vec \beta_v)}
\gdef \Puv {u \oplus v}
\gdef \Buv {B^{\mu’}_{\phantom {\mu’} \mu} (\vec \beta_{\Puv})}
\gdef \Ruv {R^{\mu’‘}_{\phantom {\mu’‘} \mu’} (\epsilon)}
\gdef \Luv {\Lambda^{\mu’‘}_{\phantom {\mu’’} \mu} (\vec \beta_{\Puv})}
$
Wigner rotation axis $\widehat {\vec \beta_u \times \vec \beta_v}$ and angle $\epsilon$ of
the boost composition self
$\oplus$frame
.
The composition of two pure boosts, $\Bu$ to self
followed by $\Bv$ to frame
, results in
a composition of a pure boost $\Buv$ and a non-vanishing spatial rotation $\Ruv$ for
non-collinear boosts:
$$ \Luv = \Ruv \Buv = \Bv \Bu $$
$$ \epsilon = \arcsin \Bigg({ 1 + \gamma + \gamma_u + \gamma_v \over (1 + \gamma) (1 + \gamma_u) (1 + \gamma_v) } \gamma_u \gamma_v |\vec \beta_u \times \vec \beta_v| \Bigg) $$
$$ \gamma = \gamma_u \gamma_v (1 + \vec \beta_u \cdot \vec \beta_v) $$
use approx::{assert_abs_diff_ne, assert_ulps_eq};
use nalgebra::Vector3;
use nalgebra_spacetime::{Frame4, LorentzianN};
let u = Frame4::from_beta(Vector3::new(0.18, 0.73, 0.07));
let v = Frame4::from_beta(Vector3::new(0.41, 0.14, 0.25));
let ucv = u.compose(&v).axis();
let vcu = v.compose(&u).axis();
let (axis, angle) = u.axis_angle(&v);
let axis = axis.into_inner();
assert_abs_diff_ne!(angle, 0.0, epsilon = 1e-15);
assert_ulps_eq!(angle, ucv.angle(&vcu), epsilon = 1e-15);
assert_ulps_eq!(axis, ucv.cross(&vcu).normalize(), epsilon = 1e-15);
sourcepub fn rotation(&self, frame: &Self) -> Matrix4<N>
pub fn rotation(&self, frame: &Self) -> Matrix4<N>
Wigner rotation matrix $R(\widehat {\vec \beta_u \times \vec \beta_v}, \epsilon)$ of the
boost composition self
$\oplus$frame
.
See Self::axis_angle
for further details.
use approx::{assert_ulps_eq, assert_ulps_ne};
use nalgebra::{Matrix4, Vector3};
use nalgebra_spacetime::{Frame4, LorentzianN};
let u = Frame4::from_beta(Vector3::new(0.18, 0.73, 0.07));
let v = Frame4::from_beta(Vector3::new(0.41, 0.14, 0.25));
let ucv = u.compose(&v);
let vcu = v.compose(&u);
let boost_u = Matrix4::new_boost(&u);
let boost_v = Matrix4::new_boost(&v);
let boost_ucv = Matrix4::new_boost(&ucv);
let boost_vcu = Matrix4::new_boost(&vcu);
let rotation_ucv = u.rotation(&v);
assert_ulps_ne!(boost_ucv, boost_v * boost_u);
assert_ulps_ne!(boost_vcu, boost_u * boost_v);
assert_ulps_eq!(rotation_ucv * boost_ucv, boost_v * boost_u);
assert_ulps_eq!(boost_vcu * rotation_ucv, boost_v * boost_u);
Trait Implementations§
source§impl<N, D> Add for FrameN<N, D>where
N: SimdRealField + Signed + Real,
D: DimNameSub<U1>,
DefaultAllocator: Allocator<N, DimNameDiff<D, U1>> + Allocator<N, D>,
impl<N, D> Add for FrameN<N, D>where
N: SimdRealField + Signed + Real,
D: DimNameSub<U1>,
DefaultAllocator: Allocator<N, DimNameDiff<D, U1>> + Allocator<N, D>,
source§impl<N, D> Clone for FrameN<N, D>where
N: Scalar + Clone,
D: DimNameSub<U1> + Clone,
DefaultAllocator: Allocator<N, DimNameDiff<D, U1>>,
impl<N, D> Clone for FrameN<N, D>where
N: Scalar + Clone,
D: DimNameSub<U1> + Clone,
DefaultAllocator: Allocator<N, DimNameDiff<D, U1>>,
source§impl<N, D> Debug for FrameN<N, D>where
N: Scalar + Debug,
D: DimNameSub<U1> + Debug,
DefaultAllocator: Allocator<N, DimNameDiff<D, U1>>,
impl<N, D> Debug for FrameN<N, D>where
N: Scalar + Debug,
D: DimNameSub<U1> + Debug,
DefaultAllocator: Allocator<N, DimNameDiff<D, U1>>,
source§impl<N, D> From<FrameN<N, D>> for OVector<N, D>where
N: SimdRealField + Signed + Real,
D: DimNameSub<U1>,
DefaultAllocator: Allocator<N, DimNameDiff<D, U1>> + Allocator<N, D>,
impl<N, D> From<FrameN<N, D>> for OVector<N, D>where
N: SimdRealField + Signed + Real,
D: DimNameSub<U1>,
DefaultAllocator: Allocator<N, DimNameDiff<D, U1>> + Allocator<N, D>,
source§impl<N, R, C> From<Matrix<N, R, C, <DefaultAllocator as Allocator<N, R, C>>::Buffer>> for FrameN<N, R>where
N: SimdRealField + Signed + Real,
R: DimNameSub<U1>,
C: DimName,
ShapeConstraint: SameNumberOfColumns<C, U1>,
DefaultAllocator: Allocator<N, R, C> + Allocator<N, DimNameDiff<R, U1>>,
impl<N, R, C> From<Matrix<N, R, C, <DefaultAllocator as Allocator<N, R, C>>::Buffer>> for FrameN<N, R>where
N: SimdRealField + Signed + Real,
R: DimNameSub<U1>,
C: DimName,
ShapeConstraint: SameNumberOfColumns<C, U1>,
DefaultAllocator: Allocator<N, R, C> + Allocator<N, DimNameDiff<R, U1>>,
source§impl<N, D> Neg for FrameN<N, D>where
N: SimdRealField + Signed + Real,
D: DimNameSub<U1>,
DefaultAllocator: Allocator<N, DimNameDiff<D, U1>>,
impl<N, D> Neg for FrameN<N, D>where
N: SimdRealField + Signed + Real,
D: DimNameSub<U1>,
DefaultAllocator: Allocator<N, DimNameDiff<D, U1>>,
source§impl<N, D> PartialEq for FrameN<N, D>where
N: Scalar + PartialEq,
D: DimNameSub<U1> + PartialEq,
DefaultAllocator: Allocator<N, DimNameDiff<D, U1>>,
impl<N, D> PartialEq for FrameN<N, D>where
N: Scalar + PartialEq,
D: DimNameSub<U1> + PartialEq,
DefaultAllocator: Allocator<N, DimNameDiff<D, U1>>,
impl<N, D> Copy for FrameN<N, D>where
N: SimdRealField + Signed + Real,
D: DimNameSub<U1>,
DefaultAllocator: Allocator<N, DimNameDiff<D, U1>>,
Owned<N, DimNameDiff<D, U1>>: Copy,
impl<N, D> Eq for FrameN<N, D>
impl<N, D> StructuralEq for FrameN<N, D>
impl<N, D> StructuralPartialEq for FrameN<N, D>
Auto Trait Implementations§
impl<N, D> !RefUnwindSafe for FrameN<N, D>
impl<N, D> !Send for FrameN<N, D>
impl<N, D> !Sync for FrameN<N, D>
impl<N, D> !Unpin for FrameN<N, D>
impl<N, D> !UnwindSafe for FrameN<N, D>
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self
from the equivalent element of its
superset. Read moresource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self
is actually part of its subset T
(and can be converted to it).source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset
but without any property checks. Always succeeds.source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self
to the equivalent element of its superset.