use crate::DType;
use numr::error::Result;
use numr::runtime::Runtime;
use numr::tensor::Tensor;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum EulerOrder {
#[default]
XYZ,
XZY,
YXZ,
YZX,
ZXY,
ZYX,
}
#[derive(Debug, Clone)]
pub struct Rotation<R: Runtime<DType = DType>> {
pub quaternions: Tensor<R>,
pub is_batch: bool,
}
pub trait RotationAlgorithms<R: Runtime<DType = DType>> {
fn rotation_from_quat(&self, quaternion: &Tensor<R>) -> Result<Rotation<R>>;
fn rotation_from_matrix(&self, matrix: &Tensor<R>) -> Result<Rotation<R>>;
fn rotation_from_euler(&self, angles: &Tensor<R>, order: EulerOrder) -> Result<Rotation<R>>;
fn rotation_from_axis_angle(&self, axis: &Tensor<R>, angle: &Tensor<R>) -> Result<Rotation<R>>;
fn rotation_from_rotvec(&self, rotvec: &Tensor<R>) -> Result<Rotation<R>>;
fn rotation_as_quat(&self, rot: &Rotation<R>) -> Result<Tensor<R>>;
fn rotation_as_matrix(&self, rot: &Rotation<R>) -> Result<Tensor<R>>;
fn rotation_as_euler(&self, rot: &Rotation<R>, order: EulerOrder) -> Result<Tensor<R>>;
fn rotation_as_rotvec(&self, rot: &Rotation<R>) -> Result<Tensor<R>>;
fn rotation_apply(&self, rot: &Rotation<R>, vectors: &Tensor<R>) -> Result<Tensor<R>>;
fn rotation_compose(&self, r1: &Rotation<R>, r2: &Rotation<R>) -> Result<Rotation<R>>;
fn rotation_inverse(&self, rot: &Rotation<R>) -> Result<Rotation<R>>;
fn rotation_slerp(&self, r1: &Rotation<R>, r2: &Rotation<R>, t: f64) -> Result<Rotation<R>>;
fn rotation_identity(&self, n: Option<usize>) -> Result<Rotation<R>>;
fn rotation_random(&self, n: Option<usize>) -> Result<Rotation<R>>;
fn rotation_magnitude(&self, rot: &Rotation<R>) -> Result<Tensor<R>>;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_euler_order() {
assert_eq!(EulerOrder::default(), EulerOrder::XYZ);
}
}