use core::ops::{Add, Neg, Sub};
use crate::linear_algebra::{Vector, Vector3D, Vector6D};
use crate::scalar::Numeric;
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Twist<T: Numeric = f64> {
linear: Vector3D<T>,
angular: Vector3D<T>,
}
impl<T: Numeric> Twist<T> {
#[inline]
#[must_use]
pub fn new(linear: Vector3D<T>, angular: Vector3D<T>) -> Self {
Twist { linear, angular }
}
#[inline]
#[must_use]
pub fn zeros() -> Self {
Twist {
linear: Vector::zeros(),
angular: Vector::zeros(),
}
}
#[inline]
#[must_use]
pub fn from_array(a: [T; 6]) -> Self {
let [vx, vy, vz, wx, wy, wz] = a;
Twist {
linear: Vector::new([vx, vy, vz]),
angular: Vector::new([wx, wy, wz]),
}
}
#[inline]
#[must_use]
pub fn as_array(self) -> [T; 6] {
let [vx, vy, vz] = *self.linear.as_array();
let [wx, wy, wz] = *self.angular.as_array();
[vx, vy, vz, wx, wy, wz]
}
#[inline]
#[must_use]
pub fn from_vector(v: Vector6D<T>) -> Self {
Self::from_array(v.into_array())
}
#[inline]
pub fn to_vector(self) -> Vector6D<T> {
Vector::new(self.as_array())
}
#[inline]
pub fn linear(self) -> Vector3D<T> {
self.linear
}
#[inline]
pub fn angular(self) -> Vector3D<T> {
self.angular
}
#[inline]
#[must_use]
pub fn scale(self, scalar: T) -> Self {
Twist {
linear: self.linear.scale(scalar),
angular: self.angular.scale(scalar),
}
}
}
impl<T: Numeric> Add for Twist<T> {
type Output = Self;
#[inline]
fn add(self, rhs: Self) -> Self {
Twist {
linear: self.linear + rhs.linear,
angular: self.angular + rhs.angular,
}
}
}
impl<T: Numeric> Sub for Twist<T> {
type Output = Self;
#[inline]
fn sub(self, rhs: Self) -> Self {
Twist {
linear: self.linear - rhs.linear,
angular: self.angular - rhs.angular,
}
}
}
impl<T: Numeric> Neg for Twist<T> {
type Output = Self;
#[inline]
fn neg(self) -> Self {
Twist {
linear: -self.linear,
angular: -self.angular,
}
}
}
impl<T: Numeric> From<Vector6D<T>> for Twist<T> {
#[inline]
fn from(v: Vector6D<T>) -> Self {
Self::from_vector(v)
}
}
impl<T: Numeric> From<Twist<T>> for Vector6D<T> {
#[inline]
fn from(t: Twist<T>) -> Self {
t.to_vector()
}
}
impl<T: Numeric> Default for Twist<T> {
fn default() -> Self {
Self::zeros()
}
}