Add similarity transformations Sim2 and Sim3 (uniform scale followed by a rotation followed by a translation).

This commit is contained in:
Sébastien Crozet 2016-03-24 19:03:40 +01:00
parent f8f4924e47
commit 0c8b8bfcdb
9 changed files with 444 additions and 19 deletions

View File

@ -44,15 +44,17 @@ fn main() {
**nalgebra** is meant to be a general-purpose, low-dimensional, linear algebra library, with
an optimized set of tools for computer graphics and physics. Those features include:
* Vectors with static sizes: `Vec0`, `Vec1`, `Vec2`, `Vec3`, `Vec4`, `Vec5`, `Vec6`.
* Vectors with predefined static sizes: `Vec0`, `Vec1`, `Vec2`, `Vec3`, `Vec4`, `Vec5`, `Vec6`.
* Vector with a user-defined static size: `VecN`.
* Points with static sizes: `Pnt0`, `Pnt1`, `Pnt2`, `Pnt3`, `Pnt4`, `Pnt5`, `Pnt6`.
* Square matrices with static sizes: `Mat1`, `Mat2`, `Mat3`, `Mat4`, `Mat5`, `Mat6 `.
* Rotation matrices: `Rot2`, `Rot3`, `Rot4`.
* Quaternions: `Quat`, `UnitQuat`.
* Isometries: `Iso2`, `Iso3`, `Iso4`.
* Isometries (translation * rotation): `Iso2`, `Iso3`, `Iso4`.
* Similarities (translation * rotation * uniform scale): `Sim2`, `Sim3`.
* 3D projections for computer graphics: `Persp3`, `PerspMat3`, `Ortho3`, `OrthoMat3`.
* Dynamically sized vector: `DVec`.
* Dynamically sized (square or rectangular) matrix: `DMat`.
* Dynamically sized heap-allocated vector: `DVec`.
* Dynamically sized stack-allocated vectors with a maximum size: `DVec1` to `DVec6`.
* Dynamically sized heap-allocated (square or rectangular) matrix: `DMat`.
* A few methods for data analysis: `Cov`, `Mean`.
* Almost one trait per functionality: useful for generic programming.
* Operator overloading using multidispatch.

View File

@ -41,18 +41,20 @@ fn main() {
**nalgebra** is meant to be a general-purpose, low-dimensional, linear algebra library, with
an optimized set of tools for computer graphics and physics. Those features include:
* Vectors with static sizes: `Vec0`, `Vec1`, `Vec2`, `Vec3`, `Vec4`, `Vec5`, `Vec6`.
* Vectors with predefined static sizes: `Vec0`, `Vec1`, `Vec2`, `Vec3`, `Vec4`, `Vec5`, `Vec6`.
* Vector with a user-defined static size: `VecN`.
* Points with static sizes: `Pnt0`, `Pnt1`, `Pnt2`, `Pnt3`, `Pnt4`, `Pnt5`, `Pnt6`.
* Square matrices with static sizes: `Mat1`, `Mat2`, `Mat3`, `Mat4`, `Mat5`, `Mat6 `.
* Rotation matrices: `Rot2`, `Rot3`, `Rot4`.
* Quaternions: `Quat`, `UnitQuat`.
* Isometries: `Iso2`, `Iso3`, `Iso4`.
* Isometries (translation * rotation): `Iso2`, `Iso3`, `Iso4`.
* Similarity transformations (translation * rotation * uniform scale): `Sim2`, `Sim3`.
* 3D projections for computer graphics: `Persp3`, `PerspMat3`, `Ortho3`, `OrthoMat3`.
* Dynamically sized vector: `DVec`.
* Dynamically sized (square or rectangular) matrix: `DMat`.
* Dynamically sized heap-allocated vector: `DVec`.
* Dynamically sized stack-allocated vectors with a maximum size: `DVec1` to `DVec6`.
* Dynamically sized heap-allocated (square or rectangular) matrix: `DMat`.
* A few methods for data analysis: `Cov`, `Mean`.
* Almost one trait per functionality: useful for generic programming.
* Operator overloading using multidispatch.
## **nalgebra** in use
@ -139,6 +141,7 @@ pub use structs::{
DMat, DMat1, DMat2, DMat3, DMat4, DMat5, DMat6,
DVec, DVec1, DVec2, DVec3, DVec4, DVec5, DVec6,
Iso2, Iso3, Iso4,
Sim2, Sim3,
Mat1, Mat2, Mat3, Mat4,
Mat5, Mat6,
Rot2, Rot3, Rot4,

View File

@ -1,7 +1,3 @@
//! Isometric transformations.
#![allow(missing_docs)]
use std::ops::{Add, Sub, Mul, Neg};
use rand::{Rand, Rng};
@ -22,7 +18,8 @@ use quickcheck::{Arbitrary, Gen};
/// Two dimensional isometry.
///
/// This is the composition of a rotation followed by a translation.
/// This is the composition of a rotation followed by a translation. Vectors `Vec2` are not
/// affected by the translational component of this transformation while points `Pnt2` are.
/// Isometries conserve angles and distances, hence do not allow shearing nor scaling.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
@ -35,7 +32,8 @@ pub struct Iso2<N> {
/// Three dimensional isometry.
///
/// This is the composition of a rotation followed by a translation.
/// This is the composition of a rotation followed by a translation. Vectors `Vec3` are not
/// affected by the translational component of this transformation while points `Pnt3` are.
/// Isometries conserve angles and distances, hence do not allow shearing nor scaling.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
@ -48,6 +46,8 @@ pub struct Iso3<N> {
/// Four dimensional isometry.
///
/// This is the composition of a rotation followed by a translation. Vectors `Vec4` are not
/// affected by the translational component of this transformation while points `Pnt4` are.
/// Isometries conserve angles and distances, hence do not allow shearing nor scaling.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
@ -117,6 +117,8 @@ translate_impl!(Iso2, Pnt2);
iso_mul_iso_impl!(Iso2);
iso_mul_pnt_impl!(Iso2, Pnt2);
pnt_mul_iso_impl!(Iso2, Pnt2);
iso_mul_vec_impl!(Iso2, Vec2);
vec_mul_iso_impl!(Iso2, Vec2);
arbitrary_iso_impl!(Iso2);
iso_impl!(Iso3, Rot3, Vec3, Vec3);
@ -137,6 +139,8 @@ translate_impl!(Iso3, Pnt3);
iso_mul_iso_impl!(Iso3);
iso_mul_pnt_impl!(Iso3, Pnt3);
pnt_mul_iso_impl!(Iso3, Pnt3);
iso_mul_vec_impl!(Iso3, Vec3);
vec_mul_iso_impl!(Iso3, Vec3);
arbitrary_iso_impl!(Iso3);
// iso_impl!(Iso4, Rot4, Vec4, Vec4);
@ -157,5 +161,7 @@ translate_impl!(Iso4, Pnt4);
iso_mul_iso_impl!(Iso4);
iso_mul_pnt_impl!(Iso4, Pnt4);
pnt_mul_iso_impl!(Iso4, Pnt4);
iso_mul_vec_impl!(Iso4, Vec4);
vec_mul_iso_impl!(Iso4, Vec4);
// FIXME: as soon as Rot4<N>: Arbitrary
// arbitrary_iso_impl!(Iso4);

View File

@ -3,7 +3,7 @@
macro_rules! iso_impl(
($t: ident, $submat: ident, $subvec: ident, $subrotvec: ident) => (
impl<N: BaseFloat> $t<N> {
/// Creates a new isometry from a rotation matrix and a vector.
/// Creates a new isometry from an axis-angle rotation, and a vector.
#[inline]
pub fn new(translation: $subvec<N>, rotation: $subrotvec<N>) -> $t<N> {
$t {
@ -89,6 +89,19 @@ macro_rules! iso_mul_pnt_impl(
)
);
macro_rules! iso_mul_vec_impl(
($t: ident, $tv: ident) => (
impl<N: BaseNum> Mul<$tv<N>> for $t<N> {
type Output = $tv<N>;
#[inline]
fn mul(self, right: $tv<N>) -> $tv<N> {
self.rotation * right
}
}
)
);
macro_rules! pnt_mul_iso_impl(
($t: ident, $tv: ident) => (
impl<N: BaseNum> Mul<$t<N>> for $tv<N> {
@ -101,6 +114,18 @@ macro_rules! pnt_mul_iso_impl(
)
);
macro_rules! vec_mul_iso_impl(
($t: ident, $tv: ident) => (
impl<N: BaseNum> Mul<$t<N>> for $tv<N> {
type Output = $tv<N>;
#[inline]
fn mul(self, right: $t<N>) -> $tv<N> {
self * right.rotation
}
}
)
);
macro_rules! translation_impl(
($t: ident, $tv: ident) => (
impl<N: BaseFloat> Translation<$tv<N>> for $t<N> {

View File

@ -8,6 +8,7 @@ pub use self::pnt::{Pnt0, Pnt1, Pnt2, Pnt3, Pnt4, Pnt5, Pnt6};
pub use self::mat::{Identity, Mat1, Mat2, Mat3, Mat4, Mat5, Mat6};
pub use self::rot::{Rot2, Rot3, Rot4};
pub use self::iso::{Iso2, Iso3, Iso4};
pub use self::sim::{Sim2, Sim3};
pub use self::persp::{Persp3, PerspMat3};
pub use self::ortho::{Ortho3, OrthoMat3};
pub use self::quat::{Quat, UnitQuat};
@ -29,6 +30,8 @@ mod rot_macros;
mod rot;
mod iso_macros;
mod iso;
mod sim_macros;
mod sim;
mod persp;
mod ortho;

View File

@ -1,4 +1,4 @@
//! Points with dimensions known at compile-time.
//! Points with dimension known at compile-time.
#![allow(missing_docs)] // we allow missing to avoid having to document the point components.
@ -19,6 +19,9 @@ use quickcheck::{Arbitrary, Gen};
/// Point of dimension 0.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, Clone, Debug, Copy)]
pub struct Pnt0<N>(pub PhantomData<N>);
@ -39,6 +42,9 @@ impl<N> Repeat<N> for Pnt0<N> {
}
/// Point of dimension 1.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Pnt1<N> {
@ -79,6 +85,9 @@ arbitrary_pnt_impl!(Pnt1, x);
rand_impl!(Pnt1, x);
/// Point of dimension 2.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Pnt2<N> {
@ -121,6 +130,9 @@ arbitrary_pnt_impl!(Pnt2, x, y);
rand_impl!(Pnt2, x, y);
/// Point of dimension 3.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Pnt3<N> {
@ -165,6 +177,9 @@ arbitrary_pnt_impl!(Pnt3, x, y, z);
rand_impl!(Pnt3, x, y, z);
/// Point of dimension 4.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Pnt4<N> {
@ -211,6 +226,9 @@ arbitrary_pnt_impl!(Pnt4, x, y, z, w);
rand_impl!(Pnt4, x, y, z, w);
/// Point of dimension 5.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Pnt5<N> {
@ -259,6 +277,9 @@ arbitrary_pnt_impl!(Pnt5, x, y, z, w, a);
rand_impl!(Pnt5, x, y, z, w, a);
/// Point of dimension 6.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Pnt6<N> {

80
src/structs/sim.rs Normal file
View File

@ -0,0 +1,80 @@
use std::ops::{Mul, Neg};
use rand::{Rand, Rng};
use num::One;
use structs::mat::{Mat3, Mat4};
use traits::structure::{Dim, Col, BaseFloat, BaseNum};
use traits::operations::{Inv, ApproxEq};
use traits::geometry::{Rotation, Transform, Transformation, Translation, ToHomogeneous};
use structs::vec::{Vec1, Vec2, Vec3};
use structs::pnt::{Pnt2, Pnt3};
use structs::rot::{Rot2, Rot3};
use structs::iso::{Iso2, Iso3};
// FIXME: the name is not explicit at all but coherent with the other tree-letters names…
/// A two-dimensional similarity transformation.
///
/// This is a composition of a uniform scale, followed by a rotation, followed by a translation.
/// Vectors `Vec2` are not affected by the translational component of this transformation while
/// points `Pnt2` are.
/// Similarity transformations conserve angles. Distances are multiplied by some constant (the
/// scale factor). The scale factor cannot be zero.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
pub struct Sim2<N> {
/// The uniform scale applicable by this similarity transformation.
scale: N,
/// The isometry applicable by this similarity transformation.
pub isometry: Iso2<N>
}
/// A three-dimensional similarity transformation.
///
/// This is a composition of a scale, followed by a rotation, followed by a translation.
/// Vectors `Vec3` are not affected by the translational component of this transformation while
/// points `Pnt3` are.
/// Similarity transformations conserve angles. Distances are multiplied by some constant (the
/// scale factor). The scale factor cannot be zero.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)]
pub struct Sim3<N> {
/// The uniform scale applicable by this similarity transformation.
scale: N,
/// The isometry applicable by this similarity transformation.
pub isometry: Iso3<N>
}
sim_impl!(Sim2, Iso2, Rot2, Vec2, Vec1);
dim_impl!(Sim2, 2);
sim_scale_impl!(Sim2);
sim_one_impl!(Sim2);
sim_mul_sim_impl!(Sim2);
sim_mul_pnt_vec_impl!(Sim2, Pnt2);
pnt_vec_mul_sim_impl!(Sim2, Pnt2);
sim_mul_pnt_vec_impl!(Sim2, Vec2);
pnt_vec_mul_sim_impl!(Sim2, Vec2);
transformation_impl!(Sim2);
sim_transform_impl!(Sim2, Pnt2);
sim_inv_impl!(Sim2);
sim_to_homogeneous_impl!(Sim2, Mat3);
sim_approx_eq_impl!(Sim2);
sim_rand_impl!(Sim2);
sim_arbitrary_impl!(Sim2);
sim_impl!(Sim3, Iso3, Rot3, Vec3, Vec3);
dim_impl!(Sim3, 3);
sim_scale_impl!(Sim3);
sim_one_impl!(Sim3);
sim_mul_sim_impl!(Sim3);
sim_mul_pnt_vec_impl!(Sim3, Pnt3);
pnt_vec_mul_sim_impl!(Sim3, Pnt3);
sim_mul_pnt_vec_impl!(Sim3, Vec3);
pnt_vec_mul_sim_impl!(Sim3, Vec3);
transformation_impl!(Sim3);
sim_transform_impl!(Sim3, Pnt3);
sim_inv_impl!(Sim3);
sim_to_homogeneous_impl!(Sim3, Mat4);
sim_approx_eq_impl!(Sim3);
sim_rand_impl!(Sim3);
sim_arbitrary_impl!(Sim3);

264
src/structs/sim_macros.rs Normal file
View File

@ -0,0 +1,264 @@
#![macro_use]
macro_rules! sim_impl(
($t: ident, $iso: ident, $rotmat: ident, $subvec: ident, $subrotvec: ident) => (
impl<N: BaseFloat> $t<N> {
/// Creates a new similarity transformation from a vector, an axis-angle rotation, and a scale factor.
///
/// The scale factor may be negative but not zero.
#[inline]
pub fn new(translation: $subvec<N>, rotation: $subrotvec<N>, scale: N) -> $t<N> {
assert!(!scale.is_zero(), "A similarity transformation scale factor cannot be zero.");
$t {
scale: scale,
isometry: $iso::new(translation, rotation)
}
}
/// Creates a new similarity transformation from a rotation matrix, a vector, and a scale factor.
///
/// The scale factor may be negative but not zero.
#[inline]
pub fn new_with_rotmat(translation: $subvec<N>, rotation: $rotmat<N>, scale: N) -> $t<N> {
assert!(!scale.is_zero(), "A similarity transformation scale factor cannot be zero.");
$t {
scale: scale,
isometry: $iso::new_with_rotmat(translation, rotation)
}
}
/// Creates a new similarity transformation from an isometry and a scale factor.
///
/// The scale factor may be negative but not zero.
#[inline]
pub fn new_with_iso(isometry: $iso<N>, scale: N) -> $t<N> {
assert!(!scale.is_zero(), "A similarity transformation scale factor cannot be zero.");
$t {
scale: scale,
isometry: isometry
}
}
}
)
);
macro_rules! sim_scale_impl(
($t: ident) => (
impl<N: BaseFloat> $t<N> {
/// The scale factor of this similarity transformation.
#[inline]
pub fn scale(&self) -> N {
self.scale
}
/// The inverse scale factor of this similarity transformation.
#[inline]
pub fn inv_scale(&self) -> N {
::one::<N>() / self.scale
}
/// Appends in-place a scale to this similarity transformation.
#[inline]
pub fn append_scale_mut(&mut self, s: &N) {
assert!(!s.is_zero(), "Cannot append a zero scale to a similarity transformation.");
self.scale = *s * self.scale;
self.isometry.translation = self.isometry.translation * *s;
}
/// Appends a scale to this similarity transformation.
#[inline]
pub fn append_scale(&self, s: &N) -> $t<N> {
assert!(!s.is_zero(), "Cannot append a zero scale to a similarity transformation.");
$t::new_with_rotmat(self.isometry.translation * *s, self.isometry.rotation, self.scale * *s)
}
/// Prepends in-place a scale to this similarity transformation.
#[inline]
pub fn prepend_scale_mut(&mut self, s: &N) {
assert!(!s.is_zero(), "Cannot prepend a zero scale to a similarity transformation.");
self.scale = self.scale * *s;
}
/// Prepends a scale to this similarity transformation.
#[inline]
pub fn prepend_scale(&self, s: &N) -> $t<N> {
assert!(!s.is_zero(), "A similarity transformation scale must not be zero.");
$t::new_with_iso(self.isometry, self.scale * *s)
}
/// Sets the scale of this similarity transformation.
#[inline]
pub fn set_scale(&mut self, s: N) {
assert!(!s.is_zero(), "A similarity transformation scale must not be zero.");
self.scale = s
}
}
)
);
macro_rules! sim_one_impl(
($t: ident) => (
impl<N: BaseFloat> One for $t<N> {
#[inline]
fn one() -> $t<N> {
$t::new_with_iso(::one(), ::one())
}
}
)
);
macro_rules! sim_mul_sim_impl(
($t: ident) => (
impl<N: BaseFloat> Mul<$t<N>> for $t<N> {
type Output = $t<N>;
#[inline]
fn mul(self, right: $t<N>) -> $t<N> {
$t::new_with_rotmat(
self.isometry.translation + self.isometry.rotation * (right.isometry.translation * right.scale),
self.isometry.rotation * right.isometry.rotation,
self.scale * right.scale)
}
}
)
);
macro_rules! sim_mul_pnt_vec_impl(
($t: ident, $tv: ident) => (
impl<N: BaseNum> Mul<$tv<N>> for $t<N> {
type Output = $tv<N>;
#[inline]
fn mul(self, right: $tv<N>) -> $tv<N> {
self.isometry * (right * self.scale)
}
}
)
);
macro_rules! pnt_vec_mul_sim_impl(
($t: ident, $tv: ident) => (
impl<N: BaseNum> Mul<$t<N>> for $tv<N> {
type Output = $tv<N>;
#[inline]
fn mul(self, right: $t<N>) -> $tv<N> {
self * right.isometry * right.scale
}
}
)
);
macro_rules! sim_transform_impl(
($t: ident, $tp: ident) => (
impl<N: BaseNum> Transform<$tp<N>> for $t<N> {
#[inline]
fn transform(&self, p: &$tp<N>) -> $tp<N> {
self.isometry.transform(p) * self.scale
}
#[inline]
fn inv_transform(&self, p: &$tp<N>) -> $tp<N> {
self.isometry.inv_transform(p) / self.scale
}
}
)
);
macro_rules! sim_inv_impl(
($t: ident) => (
impl<N: BaseNum + Neg<Output = N>> Inv for $t<N> {
#[inline]
fn inv_mut(&mut self) -> bool {
self.scale = ::one::<N>() / self.scale;
self.isometry.inv_mut();
// We multiply by self.scale because the scale has been inverted on the previous line.
self.isometry.translation = self.isometry.translation * self.scale;
// always succeed
true
}
#[inline]
fn inv(&self) -> Option<$t<N>> {
let mut res = *self;
res.inv_mut();
// always succeed
Some(res)
}
}
)
);
macro_rules! sim_to_homogeneous_impl(
($t: ident, $th: ident) => (
impl<N: BaseNum> ToHomogeneous<$th<N>> for $t<N> {
fn to_homogeneous(&self) -> $th<N> {
let mut res = (*self.isometry.rotation.submat() * self.scale).to_homogeneous();
// copy the translation
let dim = Dim::dim(None::<$th<N>>);
res.set_col(dim - 1, self.isometry.translation.as_pnt().to_homogeneous().to_vec());
res
}
}
)
);
macro_rules! sim_approx_eq_impl(
($t: ident) => (
impl<N: ApproxEq<N>> ApproxEq<N> for $t<N> {
#[inline]
fn approx_epsilon(_: Option<$t<N>>) -> N {
ApproxEq::approx_epsilon(None::<N>)
}
#[inline]
fn approx_ulps(_: Option<$t<N>>) -> u32 {
ApproxEq::approx_ulps(None::<N>)
}
#[inline]
fn approx_eq_eps(&self, other: &$t<N>, epsilon: &N) -> bool {
ApproxEq::approx_eq_eps(&self.scale, &other.scale, epsilon) &&
ApproxEq::approx_eq_eps(&self.isometry, &other.isometry, epsilon)
}
#[inline]
fn approx_eq_ulps(&self, other: &$t<N>, ulps: u32) -> bool {
ApproxEq::approx_eq_ulps(&self.scale, &other.scale, ulps) &&
ApproxEq::approx_eq_ulps(&self.isometry, &other.isometry, ulps)
}
}
)
);
macro_rules! sim_rand_impl(
($t: ident) => (
impl<N: Rand + BaseFloat> Rand for $t<N> {
#[inline]
fn rand<R: Rng>(rng: &mut R) -> $t<N> {
$t::new_with_iso(rng.gen(), rng.gen())
}
}
)
);
macro_rules! sim_arbitrary_impl(
($t: ident) => (
#[cfg(feature="arbitrary")]
impl<N: Arbitrary + BaseFloat> Arbitrary for $t<N> {
fn arbitrary<G: Gen>(g: &mut G) -> $t<N> {
$t::new_with_iso(
Arbitrary::arbitrary(g),
Arbitrary::arbitrary(g)
)
}
}
)
);

View File

@ -1,4 +1,4 @@
//! Vectors with dimensions known at compile-time.
//! Vectors with dimension known at compile-time.
#![allow(missing_docs)] // we allow missing to avoid having to document the dispatch traits.
@ -21,6 +21,9 @@ use quickcheck::{Arbitrary, Gen};
/// Vector of dimension 0.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, Clone, Debug, Copy)]
pub struct Vec0<N>(pub PhantomData<N>);
@ -41,6 +44,9 @@ impl<N> Repeat<N> for Vec0<N> {
}
/// Vector of dimension 1.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Vec1<N> {
@ -93,6 +99,9 @@ rand_impl!(Vec1, x);
mean_impl!(Vec1);
/// Vector of dimension 2.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Vec2<N> {
@ -147,6 +156,9 @@ rand_impl!(Vec2, x, y);
mean_impl!(Vec2);
/// Vector of dimension 3.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Vec3<N> {
@ -204,6 +216,9 @@ mean_impl!(Vec3);
/// Vector of dimension 4.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Vec4<N> {
@ -262,6 +277,9 @@ rand_impl!(Vec4, x, y, z, w);
mean_impl!(Vec4);
/// Vector of dimension 5.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Vec5<N> {
@ -322,6 +340,9 @@ rand_impl!(Vec5, x, y, z, w, a);
mean_impl!(Vec5);
/// Vector of dimension 6.
///
/// The main differance between a point and a vector is that a vector is not affected by
/// translations.
#[repr(C)]
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
pub struct Vec6<N> {