nalgebra/src/structs/dvec.rs

151 lines
3.7 KiB
Rust
Raw Normal View History

//! Vector with dimensions unknown at compile-time.
#![allow(missing_docs)] // we hide doc to not have to document the $trhs double dispatch trait.
2014-05-31 05:14:16 +08:00
use std::rand::Rand;
use std::rand;
use std::slice::{Iter, IterMut};
2013-09-09 17:19:54 +08:00
use std::iter::FromIterator;
2015-01-02 06:23:35 +08:00
use std::iter::repeat;
2015-01-04 16:37:56 +08:00
use std::ops::{Add, Sub, Mul, Div, Neg, Index, IndexMut};
use traits::operations::{ApproxEq, Axpy};
Api change: deal with inplace/out of place methods. Before, it was too easy to use an out of place method instead of the inplace one since they name were pretty mutch the same. This kind of confusion may lead to silly bugs very hard to understand. Thus the following changes have been made when a method is available both inplace and out-of-place: * inplace version keep a short name. * out-of-place version are suffixed by `_cpy` (meaning `copy`), and are static methods. Methods applying transformations (rotation, translation or general transform) are now prefixed by `append`, and a `prepend` version is available too. Also, free functions doing in-place modifications dont really make sense. They have been removed. Here are the naming changes: * `invert` -> `inv` * `inverted` -> `Inv::inv_cpy` * `transpose` -> `transpose` * `transposed` -> `Transpose::transpose_cpy` * `transform_by` -> `append_transformation` * `transformed` -> `Transform::append_transformation_cpy` * `rotate_by` -> `apppend_rotation` * `rotated` -> `Rotation::append_rotation_cpy` * `translate_by` -> `apppend_translation` * `translate` -> `Translation::append_translation_cpy` * `normalized` -> `Norm::normalize_cpy` * `rotated_wrt_point` -> `RotationWithTranslation::append_rotation_wrt_point_cpy` * `rotated_wrt_center` -> `RotationWithTranslation::append_rotation_wrt_center_cpy` Note that using those static methods is very verbose, and using in-place methods require an explicit import of the related trait. This is a way to convince the user to use free functions most of the time.
2013-10-14 16:22:32 +08:00
use traits::geometry::{Dot, Norm};
use traits::structure::{Iterable, IterableMut, Indexable, Shape, BaseFloat, BaseNum, Zero, One};
#[cfg(feature="arbitrary")]
use quickcheck::{Arbitrary, Gen};
2013-05-31 17:01:07 +08:00
/// Heap allocated, dynamically sized vector.
2015-01-04 05:48:10 +08:00
#[derive(Eq, PartialEq, Show, Clone)]
2013-08-05 16:13:44 +08:00
pub struct DVec<N> {
2013-08-05 15:44:56 +08:00
/// Components of the vector. Contains as much elements as the vector dimension.
pub at: Vec<N>
2013-05-31 17:01:07 +08:00
}
impl<N> DVec<N> {
/// Creates an uninitialized vec.
#[inline]
pub unsafe fn new_uninitialized(dim: usize) -> DVec<N> {
let mut vec = Vec::with_capacity(dim);
2013-12-16 19:04:02 +08:00
vec.set_len(dim);
DVec {
at: vec
}
}
}
impl<N: Clone> DVec<N> {
/// Builds a vector filled with a constant.
#[inline]
pub fn from_elem(dim: usize, elem: N) -> DVec<N> {
2015-01-02 06:23:35 +08:00
DVec { at: repeat(elem).take(dim).collect() }
}
/// Builds a vector filled with the components provided by a vector.
///
/// The vector must have at least `dim` elements.
#[inline]
pub fn from_slice(dim: usize, vec: &[N]) -> DVec<N> {
assert!(dim <= vec.len());
DVec {
at: vec[.. dim].to_vec()
}
}
}
impl<N> DVec<N> {
/// Builds a vector filled with the result of a function.
#[inline(always)]
pub fn from_fn<F: FnMut(usize) -> N>(dim: usize, mut f: F) -> DVec<N> {
DVec { at: (0us .. dim).map(|i| f(i)).collect() }
}
#[inline]
pub fn len(&self) -> usize {
self.at.len()
}
}
2013-08-16 16:14:01 +08:00
impl<N> FromIterator<N> for DVec<N> {
#[inline]
fn from_iter<I: Iterator<Item = N>>(mut param: I) -> DVec<N> {
let mut res = DVec { at: Vec::new() };
2013-08-05 16:13:44 +08:00
for e in param {
res.at.push(e)
}
2013-08-05 15:44:56 +08:00
res
}
}
#[cfg(feature="arbitrary")]
impl<N: Arbitrary> Arbitrary for DVec<N> {
fn arbitrary<G: Gen>(g: &mut G) -> DVec<N> {
DVec { at: Arbitrary::arbitrary(g) }
}
}
2013-05-31 17:01:07 +08:00
dvec_impl!(DVec);
2013-05-31 17:01:07 +08:00
/// Stack-allocated, dynamically sized vector with a maximum size of 1.
pub struct DVec1<N> {
at: [N; 1],
dim: usize
2013-05-31 17:01:07 +08:00
}
small_dvec_impl!(DVec1, 1, 0);
small_dvec_from_impl!(DVec1, 1, ::zero());
2013-05-31 17:01:07 +08:00
/// Stack-allocated, dynamically sized vector with a maximum size of 2.
pub struct DVec2<N> {
at: [N; 2],
dim: usize
}
2013-05-31 17:01:07 +08:00
small_dvec_impl!(DVec2, 2, 0, 1);
small_dvec_from_impl!(DVec2, 2, ::zero(), ::zero());
2013-05-31 17:01:07 +08:00
/// Stack-allocated, dynamically sized vector with a maximum size of 3.
pub struct DVec3<N> {
at: [N; 3],
dim: usize
2013-05-31 17:01:07 +08:00
}
small_dvec_impl!(DVec3, 3, 0, 1, 2);
small_dvec_from_impl!(DVec3, 3, ::zero(), ::zero(), ::zero());
2013-05-31 17:01:07 +08:00
/// Stack-allocated, dynamically sized vector with a maximum size of 4.
pub struct DVec4<N> {
at: [N; 4],
dim: usize
}
2013-05-31 17:01:07 +08:00
small_dvec_impl!(DVec4, 4, 0, 1, 2, 3);
small_dvec_from_impl!(DVec4, 4, ::zero(), ::zero(), ::zero(), ::zero());
2013-05-31 17:01:07 +08:00
/// Stack-allocated, dynamically sized vector with a maximum size of 5.
pub struct DVec5<N> {
at: [N; 5],
dim: usize
2013-05-31 17:01:07 +08:00
}
small_dvec_impl!(DVec5, 5, 0, 1, 2, 3, 4);
small_dvec_from_impl!(DVec5, 5, ::zero(), ::zero(), ::zero(), ::zero(), ::zero());
2013-05-31 17:01:07 +08:00
2013-06-09 20:09:22 +08:00
/// Stack-allocated, dynamically sized vector with a maximum size of 6.
pub struct DVec6<N> {
at: [N; 6],
dim: usize
2013-05-31 17:01:07 +08:00
}
small_dvec_impl!(DVec6, 6, 0, 1, 2, 3, 4, 5);
small_dvec_from_impl!(DVec6, 6, ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero());