use na::Real;
use na::{Matrix2, Matrix3, RowVector2, Vector1, Vector2, Vector3};
pub trait GeneralizedCross {
type Rhs;
type CrossVector;
type CrossMatrix;
type CrossMatrixTr;
fn gcross(&self, rhs: &Self::Rhs) -> Self::CrossVector;
fn gcross_matrix(&self) -> Self::CrossMatrix;
fn gcross_matrix_tr(&self) -> Self::CrossMatrixTr;
}
impl<N: Real> GeneralizedCross for Vector1<N> {
type Rhs = Vector2<N>;
type CrossVector = Vector2<N>;
type CrossMatrix = Matrix2<N>;
type CrossMatrixTr = Matrix2<N>;
#[inline]
fn gcross(&self, rhs: &Vector2<N>) -> Vector2<N> {
Vector2::new(-rhs.y * self.x, rhs.x * self.x)
}
#[inline]
fn gcross_matrix(&self) -> Matrix2<N> {
Matrix2::new(N::zero(), -self.x, self.x, N::zero())
}
#[inline]
fn gcross_matrix_tr(&self) -> Matrix2<N> {
Matrix2::new(N::zero(), self.x, -self.x, N::zero())
}
}
impl<N: Real> GeneralizedCross for Vector2<N> {
type Rhs = Vector2<N>;
type CrossVector = Vector1<N>;
type CrossMatrix = RowVector2<N>;
type CrossMatrixTr = Vector2<N>;
#[inline]
fn gcross(&self, rhs: &Vector2<N>) -> Vector1<N> {
Vector1::new(self.x * rhs.y - self.y * rhs.x)
}
#[inline]
fn gcross_matrix(&self) -> RowVector2<N> {
RowVector2::new(-self.y, self.x)
}
#[inline]
fn gcross_matrix_tr(&self) -> Vector2<N> {
Vector2::new(-self.y, self.x)
}
}
impl<N: Real> GeneralizedCross for Vector3<N> {
type Rhs = Vector3<N>;
type CrossVector = Vector3<N>;
type CrossMatrix = Matrix3<N>;
type CrossMatrixTr = Matrix3<N>;
#[inline]
fn gcross(&self, rhs: &Vector3<N>) -> Vector3<N> {
self.cross(rhs)
}
#[inline]
fn gcross_matrix(&self) -> Matrix3<N> {
self.cross_matrix()
}
#[inline]
fn gcross_matrix_tr(&self) -> Matrix3<N> {
Matrix3::new(
N::zero(),
self.z,
-self.y,
-self.z,
N::zero(),
self.x,
self.y,
-self.x,
N::zero(),
)
}
}