#[cfg(feature = "nalgebra-0_32")]
use nalgebra_0_32 as na;
#[cfg(feature = "nalgebra-0_33")]
use nalgebra_0_33 as na;
#[cfg(feature = "nalgebra-0_34")]
use nalgebra_0_34 as na;
use crate::scalar::Float;
use super::{Rotor, Vector};
impl<T: Float + na::Scalar> From<na::Vector2<T>> for Vector<T> {
#[inline]
fn from(v: na::Vector2<T>) -> Self {
Vector::new(v.x, v.y)
}
}
impl<T: Float + na::Scalar> From<Vector<T>> for na::Vector2<T> {
#[inline]
fn from(v: Vector<T>) -> Self {
na::Vector2::new(v.x(), v.y())
}
}
impl<T: Float + na::RealField> From<na::Rotation2<T>> for Rotor<T> {
#[inline]
fn from(rotation: na::Rotation2<T>) -> Self {
Rotor::from_angle(rotation.angle())
}
}
impl<T: Float + na::RealField> From<Rotor<T>> for na::Rotation2<T> {
#[inline]
fn from(rotor: Rotor<T>) -> Self {
na::Rotation2::new(rotor.angle())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::ops::Transform;
use crate::test_utils::RELATIVE_EQ_EPS;
use crate::wrappers::Unit;
use approx::relative_eq;
use proptest::prelude::*;
proptest! {
#[test]
fn vector_roundtrip(v in any::<Vector<f64>>()) {
let na_v: na::Vector2<f64> = v.into();
let back: Vector<f64> = na_v.into();
prop_assert!(relative_eq!(v, back, epsilon = RELATIVE_EQ_EPS, max_relative = RELATIVE_EQ_EPS));
}
#[test]
fn rotor_angle_roundtrip(angle in -std::f64::consts::PI..std::f64::consts::PI) {
let rotor = Rotor::from_angle(angle);
let rotation: na::Rotation2<f64> = rotor.into();
let back: Rotor<f64> = rotation.into();
prop_assert!(relative_eq!(rotor.angle(), back.angle(), epsilon = RELATIVE_EQ_EPS, max_relative = RELATIVE_EQ_EPS));
}
#[test]
fn rotor_rotation_equivalence(
r in any::<Unit<Rotor<f64>>>(),
v in any::<Vector<f64>>(),
) {
let na_v: na::Vector2<f64> = v.into();
let rotated_ga = r.as_inner().transform(&v);
let rotation: na::Rotation2<f64> = r.into_inner().into();
let rotated_na = rotation * na_v;
let rotated_back: Vector<f64> = rotated_na.into();
prop_assert!(relative_eq!(rotated_ga, rotated_back, epsilon = RELATIVE_EQ_EPS, max_relative = RELATIVE_EQ_EPS));
}
}
}