#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum EulerRot {
Zyx,
Zxy,
Yxz,
Yzx,
Xyz,
Xzy,
Zyz,
Zxz,
Yxy,
Yzy,
Xyx,
Xzx,
ZyxEx,
ZxyEx,
YxzEx,
YzxEx,
XyzEx,
XzyEx,
ZyzEx,
ZxzEx,
YxyEx,
YzyEx,
XyxEx,
XzxEx,
}
impl Default for EulerRot {
#[inline]
fn default() -> Self {
Self::Yxz
}
}
#[derive(Clone, Copy)]
pub(crate) struct EulerRotProperties {
pub(crate) initial_axis: usize,
pub(crate) parity_even: bool,
pub(crate) initial_repeated: bool,
pub(crate) frame_static: bool,
}
impl EulerRot {
pub(crate) fn properties(self) -> EulerRotProperties {
enum Axis {
X = 0,
Y = 1,
Z = 2,
}
enum Parity {
Odd = 0,
Even = 1,
}
enum Repeated {
No = 0,
Yes = 1,
}
enum Frame {
Relative = 0,
Static = 1,
}
fn properties(
initial_axis: Axis,
parity: Parity,
repeated: Repeated,
frame: Frame,
) -> EulerRotProperties {
EulerRotProperties {
initial_axis: initial_axis as usize,
parity_even: parity as u32 == Parity::Even as u32,
initial_repeated: repeated as u32 == Repeated::Yes as u32,
frame_static: frame as u32 == Frame::Static as u32,
}
}
match self {
Self::Zyx => properties(Axis::Z, Parity::Odd, Repeated::No, Frame::Static),
Self::Zxy => properties(Axis::Z, Parity::Even, Repeated::No, Frame::Static),
Self::Yxz => properties(Axis::Y, Parity::Odd, Repeated::No, Frame::Static),
Self::Yzx => properties(Axis::Y, Parity::Even, Repeated::No, Frame::Static),
Self::Xyz => properties(Axis::X, Parity::Even, Repeated::No, Frame::Static),
Self::Xzy => properties(Axis::X, Parity::Odd, Repeated::No, Frame::Static),
Self::Zyz => properties(Axis::Z, Parity::Odd, Repeated::Yes, Frame::Static),
Self::Zxz => properties(Axis::Z, Parity::Even, Repeated::Yes, Frame::Static),
Self::Yxy => properties(Axis::Y, Parity::Odd, Repeated::Yes, Frame::Static),
Self::Yzy => properties(Axis::Y, Parity::Even, Repeated::Yes, Frame::Static),
Self::Xyx => properties(Axis::X, Parity::Even, Repeated::Yes, Frame::Static),
Self::Xzx => properties(Axis::X, Parity::Odd, Repeated::Yes, Frame::Static),
Self::ZyxEx => properties(Axis::X, Parity::Even, Repeated::No, Frame::Relative),
Self::ZxyEx => properties(Axis::Y, Parity::Odd, Repeated::No, Frame::Relative),
Self::YxzEx => properties(Axis::Z, Parity::Even, Repeated::No, Frame::Relative),
Self::YzxEx => properties(Axis::X, Parity::Odd, Repeated::No, Frame::Relative),
Self::XyzEx => properties(Axis::Z, Parity::Odd, Repeated::No, Frame::Relative),
Self::XzyEx => properties(Axis::Y, Parity::Even, Repeated::No, Frame::Relative),
Self::ZyzEx => properties(Axis::Z, Parity::Odd, Repeated::Yes, Frame::Relative),
Self::ZxzEx => properties(Axis::Z, Parity::Even, Repeated::Yes, Frame::Relative),
Self::YxyEx => properties(Axis::Y, Parity::Odd, Repeated::Yes, Frame::Relative),
Self::YzyEx => properties(Axis::Y, Parity::Even, Repeated::Yes, Frame::Relative),
Self::XyxEx => properties(Axis::X, Parity::Even, Repeated::Yes, Frame::Relative),
Self::XzxEx => properties(Axis::X, Parity::Odd, Repeated::Yes, Frame::Relative),
}
}
#[cfg(test)]
pub(crate) fn values() -> impl Iterator<Item = Self> {
[
Self::Zyx,
Self::Zxy,
Self::Yxz,
Self::Yzx,
Self::Xyz,
Self::Xzy,
Self::Zyz,
Self::Zxz,
Self::Yxy,
Self::Yzy,
Self::Xyx,
Self::Xzx,
Self::ZyxEx,
Self::ZxyEx,
Self::YxzEx,
Self::YzxEx,
Self::XyzEx,
Self::XzyEx,
Self::ZyzEx,
Self::ZxzEx,
Self::YxyEx,
Self::YzyEx,
Self::XyxEx,
Self::XzxEx,
]
.into_iter()
}
}
impl EulerRotProperties {
pub(crate) fn axes_indices(self) -> (usize, usize, usize) {
fn next_axis(i: usize) -> usize {
(i + 1) % 3
}
fn prev_axis(i: usize) -> usize {
if i > 0 { i - 1 } else { 2 }
}
let i = self.initial_axis;
let j = if self.parity_even {
next_axis(i)
} else {
prev_axis(i)
};
let k = if self.parity_even {
prev_axis(i)
} else {
next_axis(i)
};
(i, j, k)
}
}