Make lots of methods take vectors and points by value
This commit is contained in:
parent
7af4ebb28d
commit
178272da3d
12 changed files with 245 additions and 245 deletions
|
@ -65,9 +65,9 @@ impl<S> Matrix2<S> {
|
|||
impl<S: BaseFloat> Matrix2<S> {
|
||||
/// Create a transformation matrix that will cause a vector to point at
|
||||
/// `dir`, using `up` for orientation.
|
||||
pub fn look_at(dir: &Vector2<S>, up: &Vector2<S>) -> Matrix2<S> {
|
||||
pub fn look_at(dir: Vector2<S>, up: Vector2<S>) -> Matrix2<S> {
|
||||
//TODO: verify look_at 2D
|
||||
Matrix2::from_cols(up.clone(), dir.clone()).transpose()
|
||||
Matrix2::from_cols(up, dir).transpose()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -110,10 +110,10 @@ impl<S> Matrix3<S> {
|
|||
impl<S: BaseFloat> Matrix3<S> {
|
||||
/// Create a transformation matrix that will cause a vector to point at
|
||||
/// `dir`, using `up` for orientation.
|
||||
pub fn look_at(dir: &Vector3<S>, up: &Vector3<S>) -> Matrix3<S> {
|
||||
pub fn look_at(dir: Vector3<S>, up: Vector3<S>) -> Matrix3<S> {
|
||||
let dir = dir.normalize();
|
||||
let side = up.cross(&dir).normalize();
|
||||
let up = dir.cross(&side).normalize();
|
||||
let side = up.cross(dir).normalize();
|
||||
let up = dir.cross(side).normalize();
|
||||
|
||||
Matrix3::from_cols(side, up, dir).transpose()
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ impl<S: BaseFloat> Matrix3<S> {
|
|||
}
|
||||
|
||||
/// Create a matrix from a rotation around an arbitrary axis
|
||||
pub fn from_axis_angle(axis: &Vector3<S>, angle: Rad<S>) -> Matrix3<S> {
|
||||
pub fn from_axis_angle(axis: Vector3<S>, angle: Rad<S>) -> Matrix3<S> {
|
||||
let (s, c) = sin_cos(angle);
|
||||
let _1subc = S::one() - c;
|
||||
|
||||
|
@ -215,7 +215,7 @@ impl<S> Matrix4<S> {
|
|||
impl<S: BaseNum> Matrix4<S> {
|
||||
/// Create a translation matrix from a Vector3
|
||||
#[inline]
|
||||
pub fn from_translation(v: &Vector3<S>) -> Matrix4<S> {
|
||||
pub fn from_translation(v: Vector3<S>) -> Matrix4<S> {
|
||||
Matrix4::new(S::one(), S::zero(), S::zero(), S::zero(),
|
||||
S::zero(), S::one(), S::zero(), S::zero(),
|
||||
S::zero(), S::zero(), S::one(), S::zero(),
|
||||
|
@ -226,15 +226,15 @@ impl<S: BaseNum> Matrix4<S> {
|
|||
impl<S: BaseFloat> Matrix4<S> {
|
||||
/// Create a transformation matrix that will cause a vector to point at
|
||||
/// `dir`, using `up` for orientation.
|
||||
pub fn look_at(eye: &Point3<S>, center: &Point3<S>, up: &Vector3<S>) -> Matrix4<S> {
|
||||
pub fn look_at(eye: Point3<S>, center: Point3<S>, up: Vector3<S>) -> Matrix4<S> {
|
||||
let f = (center - eye).normalize();
|
||||
let s = f.cross(up).normalize();
|
||||
let u = s.cross(&f);
|
||||
let u = s.cross(f);
|
||||
|
||||
Matrix4::new(s.x.clone(), u.x.clone(), -f.x.clone(), S::zero(),
|
||||
s.y.clone(), u.y.clone(), -f.y.clone(), S::zero(),
|
||||
s.z.clone(), u.z.clone(), -f.z.clone(), S::zero(),
|
||||
-eye.dot(&s), -eye.dot(&u), eye.dot(&f), S::one())
|
||||
-eye.dot(s), -eye.dot(u), eye.dot(f), S::one())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -275,7 +275,7 @@ pub trait Matrix where
|
|||
/// Create a new diagonal matrix using the supplied value.
|
||||
fn from_value(value: Self::Element) -> Self;
|
||||
/// Create a matrix from a non-uniform scale
|
||||
fn from_diagonal(diagonal: &Self::Column) -> Self;
|
||||
fn from_diagonal(diagonal: Self::Column) -> Self;
|
||||
|
||||
/// Create a matrix with all elements equal to zero.
|
||||
#[inline]
|
||||
|
@ -303,7 +303,7 @@ pub trait Matrix where
|
|||
fn sub_m(&self, m: &Self) -> Self;
|
||||
|
||||
/// Multiplay a vector by this matrix, returning a new vector.
|
||||
fn mul_v(&self, v: &Self::Column) -> Self::Column;
|
||||
fn mul_v(&self, v: Self::Column) -> Self::Column;
|
||||
|
||||
/// Multiply this matrix by another matrix, returning the new matrix.
|
||||
#[must_use]
|
||||
|
@ -440,7 +440,7 @@ impl<S: BaseFloat> Matrix for Matrix2<S> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn from_diagonal(value: &Vector2<S>) -> Matrix2<S> {
|
||||
fn from_diagonal(value: Vector2<S>) -> Matrix2<S> {
|
||||
Matrix2::new(value.x, S::zero(),
|
||||
S::zero(), value.y)
|
||||
}
|
||||
|
@ -451,7 +451,7 @@ impl<S: BaseFloat> Matrix for Matrix2<S> {
|
|||
#[inline] fn add_m(&self, m: &Matrix2<S>) -> Matrix2<S> { self + m }
|
||||
#[inline] fn sub_m(&self, m: &Matrix2<S>) -> Matrix2<S> { self - m }
|
||||
fn mul_m(&self, other: &Matrix2<S>) -> Matrix2<S> { self * other }
|
||||
#[inline] fn mul_v(&self, v: &Vector2<S>) -> Vector2<S> { self * v }
|
||||
#[inline] fn mul_v(&self, v: Vector2<S>) -> Vector2<S> { self * v }
|
||||
|
||||
#[inline]
|
||||
fn mul_self_s(&mut self, s: S) {
|
||||
|
@ -473,14 +473,14 @@ impl<S: BaseFloat> Matrix for Matrix2<S> {
|
|||
|
||||
#[inline]
|
||||
fn add_self_m(&mut self, m: &Matrix2<S>) {
|
||||
self[0].add_self_v(&m[0]);
|
||||
self[1].add_self_v(&m[1]);
|
||||
self[0].add_self_v(m[0]);
|
||||
self[1].add_self_v(m[1]);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn sub_self_m(&mut self, m: &Matrix2<S>) {
|
||||
self[0].sub_self_v(&m[0]);
|
||||
self[1].sub_self_v(&m[1]);
|
||||
self[0].sub_self_v(m[0]);
|
||||
self[1].sub_self_v(m[1]);
|
||||
}
|
||||
|
||||
fn transpose(&self) -> Matrix2<S> {
|
||||
|
@ -540,7 +540,7 @@ impl<S: BaseFloat> Matrix for Matrix3<S> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn from_diagonal(value: &Vector3<S>) -> Matrix3<S> {
|
||||
fn from_diagonal(value: Vector3<S>) -> Matrix3<S> {
|
||||
Matrix3::new(value.x, S::zero(), S::zero(),
|
||||
S::zero(), value.y, S::zero(),
|
||||
S::zero(), S::zero(), value.z)
|
||||
|
@ -552,7 +552,7 @@ impl<S: BaseFloat> Matrix for Matrix3<S> {
|
|||
#[inline] fn add_m(&self, m: &Matrix3<S>) -> Matrix3<S> { self + m }
|
||||
#[inline] fn sub_m(&self, m: &Matrix3<S>) -> Matrix3<S> { self - m }
|
||||
fn mul_m(&self, other: &Matrix3<S>) -> Matrix3<S> { self * other }
|
||||
#[inline] fn mul_v(&self, v: &Vector3<S>) -> Vector3<S> { self * v}
|
||||
#[inline] fn mul_v(&self, v: Vector3<S>) -> Vector3<S> { self * v}
|
||||
|
||||
#[inline]
|
||||
fn mul_self_s(&mut self, s: S) {
|
||||
|
@ -577,16 +577,16 @@ impl<S: BaseFloat> Matrix for Matrix3<S> {
|
|||
|
||||
#[inline]
|
||||
fn add_self_m(&mut self, m: &Matrix3<S>) {
|
||||
self[0].add_self_v(&m[0]);
|
||||
self[1].add_self_v(&m[1]);
|
||||
self[2].add_self_v(&m[2]);
|
||||
self[0].add_self_v(m[0]);
|
||||
self[1].add_self_v(m[1]);
|
||||
self[2].add_self_v(m[2]);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn sub_self_m(&mut self, m: &Matrix3<S>) {
|
||||
self[0].sub_self_v(&m[0]);
|
||||
self[1].sub_self_v(&m[1]);
|
||||
self[2].sub_self_v(&m[2]);
|
||||
self[0].sub_self_v(m[0]);
|
||||
self[1].sub_self_v(m[1]);
|
||||
self[2].sub_self_v(m[2]);
|
||||
}
|
||||
|
||||
fn transpose(&self) -> Matrix3<S> {
|
||||
|
@ -618,9 +618,9 @@ impl<S: BaseFloat> Matrix for Matrix3<S> {
|
|||
fn invert(&self) -> Option<Matrix3<S>> {
|
||||
let det = self.determinant();
|
||||
if det.approx_eq(&S::zero()) { None } else {
|
||||
Some(Matrix3::from_cols(&self[1].cross(&self[2]) / det,
|
||||
&self[2].cross(&self[0]) / det,
|
||||
&self[0].cross(&self[1]) / det).transpose())
|
||||
Some(Matrix3::from_cols(self[1].cross(self[2]) / det,
|
||||
self[2].cross(self[0]) / det,
|
||||
self[0].cross(self[1]) / det).transpose())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -659,7 +659,7 @@ impl<S: BaseFloat> Matrix for Matrix4<S> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn from_diagonal(value: &Vector4<S>) -> Matrix4<S> {
|
||||
fn from_diagonal(value: Vector4<S>) -> Matrix4<S> {
|
||||
Matrix4::new(value.x, S::zero(), S::zero(), S::zero(),
|
||||
S::zero(), value.y, S::zero(), S::zero(),
|
||||
S::zero(), S::zero(), value.z, S::zero(),
|
||||
|
@ -672,7 +672,7 @@ impl<S: BaseFloat> Matrix for Matrix4<S> {
|
|||
#[inline] fn add_m(&self, m: &Matrix4<S>) -> Matrix4<S> { self + m }
|
||||
#[inline] fn sub_m(&self, m: &Matrix4<S>) -> Matrix4<S> { self - m }
|
||||
fn mul_m(&self, other: &Matrix4<S>) -> Matrix4<S> { self * other }
|
||||
#[inline] fn mul_v(&self, v: &Vector4<S>) -> Vector4<S> { self * v }
|
||||
#[inline] fn mul_v(&self, v: Vector4<S>) -> Vector4<S> { self * v }
|
||||
|
||||
#[inline]
|
||||
fn mul_self_s(&mut self, s: S) {
|
||||
|
@ -700,18 +700,18 @@ impl<S: BaseFloat> Matrix for Matrix4<S> {
|
|||
|
||||
#[inline]
|
||||
fn add_self_m(&mut self, m: &Matrix4<S>) {
|
||||
self[0].add_self_v(&m[0]);
|
||||
self[1].add_self_v(&m[1]);
|
||||
self[2].add_self_v(&m[2]);
|
||||
self[3].add_self_v(&m[3]);
|
||||
self[0].add_self_v(m[0]);
|
||||
self[1].add_self_v(m[1]);
|
||||
self[2].add_self_v(m[2]);
|
||||
self[3].add_self_v(m[3]);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn sub_self_m(&mut self, m: &Matrix4<S>) {
|
||||
self[0].sub_self_v(&m[0]);
|
||||
self[1].sub_self_v(&m[1]);
|
||||
self[2].sub_self_v(&m[2]);
|
||||
self[3].sub_self_v(&m[3]);
|
||||
self[0].sub_self_v(m[0]);
|
||||
self[1].sub_self_v(m[1]);
|
||||
self[2].sub_self_v(m[2]);
|
||||
self[3].sub_self_v(m[3]);
|
||||
}
|
||||
|
||||
fn transpose(&self) -> Matrix4<S> {
|
||||
|
@ -928,7 +928,7 @@ macro_rules! impl_vector_mul_operators {
|
|||
type Output = $VectorN<S>;
|
||||
|
||||
fn mul(self, v: $VectorN<S>) -> $VectorN<S> {
|
||||
$VectorN::new($(self.row($row_index).dot(&v)),+)
|
||||
$VectorN::new($(self.row($row_index).dot(v)),+)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -936,7 +936,7 @@ macro_rules! impl_vector_mul_operators {
|
|||
type Output = $VectorN<S>;
|
||||
|
||||
fn mul(self, v: &'a $VectorN<S>) -> $VectorN<S> {
|
||||
$VectorN::new($(self.row($row_index).dot(v)),+)
|
||||
$VectorN::new($(self.row($row_index).dot(*v)),+)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -950,8 +950,8 @@ impl<'a, 'b, S: BaseNum> Mul<&'a Matrix2<S>> for &'b Matrix2<S> {
|
|||
type Output = Matrix2<S>;
|
||||
|
||||
fn mul(self, other: &'a Matrix2<S>) -> Matrix2<S> {
|
||||
Matrix2::new(self.row(0).dot(&other[0]), self.row(1).dot(&other[0]),
|
||||
self.row(0).dot(&other[1]), self.row(1).dot(&other[1]))
|
||||
Matrix2::new(self.row(0).dot(other[0]), self.row(1).dot(other[0]),
|
||||
self.row(0).dot(other[1]), self.row(1).dot(other[1]))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -959,9 +959,9 @@ impl<'a, 'b, S: BaseNum> Mul<&'a Matrix3<S>> for &'b Matrix3<S> {
|
|||
type Output = Matrix3<S>;
|
||||
|
||||
fn mul(self, other: &'a Matrix3<S>) -> Matrix3<S> {
|
||||
Matrix3::new(self.row(0).dot(&other[0]),self.row(1).dot(&other[0]),self.row(2).dot(&other[0]),
|
||||
self.row(0).dot(&other[1]),self.row(1).dot(&other[1]),self.row(2).dot(&other[1]),
|
||||
self.row(0).dot(&other[2]),self.row(1).dot(&other[2]),self.row(2).dot(&other[2]))
|
||||
Matrix3::new(self.row(0).dot(other[0]),self.row(1).dot(other[0]),self.row(2).dot(other[0]),
|
||||
self.row(0).dot(other[1]),self.row(1).dot(other[1]),self.row(2).dot(other[1]),
|
||||
self.row(0).dot(other[2]),self.row(1).dot(other[2]),self.row(2).dot(other[2]))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
72
src/point.rs
72
src/point.rs
|
@ -54,19 +54,19 @@ impl<S: BaseNum> Point3<S> {
|
|||
|
||||
impl<S: BaseNum> Point3<S> {
|
||||
#[inline]
|
||||
pub fn from_homogeneous(v: &Vector4<S>) -> Point3<S> {
|
||||
pub fn from_homogeneous(v: Vector4<S>) -> Point3<S> {
|
||||
let e = v.truncate() * (S::one() / v.w);
|
||||
Point3::new(e.x, e.y, e.z) //FIXME
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn to_homogeneous(&self) -> Vector4<S> {
|
||||
pub fn to_homogeneous(self) -> Vector4<S> {
|
||||
Vector4::new(self.x, self.y, self.z, S::one())
|
||||
}
|
||||
}
|
||||
|
||||
/// Specifies the numeric operations for point types.
|
||||
pub trait Point: Clone where
|
||||
pub trait Point: Copy + Clone where
|
||||
// FIXME: Ugly type signatures - blocked by rust-lang/rust#24092
|
||||
Self: Array1<Element = <Self as Point>::Scalar>,
|
||||
// FIXME: blocked by rust-lang/rust#20671
|
||||
|
@ -90,25 +90,25 @@ pub trait Point: Clone where
|
|||
fn origin() -> Self;
|
||||
|
||||
/// Create a point from a vector.
|
||||
fn from_vec(v: &Self::Vector) -> Self;
|
||||
fn from_vec(v: Self::Vector) -> Self;
|
||||
/// Convert a point to a vector.
|
||||
fn to_vec(&self) -> Self::Vector;
|
||||
fn to_vec(self) -> Self::Vector;
|
||||
|
||||
/// Multiply each component by a scalar, returning the new point.
|
||||
#[must_use]
|
||||
fn mul_s(&self, scalar: Self::Scalar) -> Self;
|
||||
fn mul_s(self, scalar: Self::Scalar) -> Self;
|
||||
/// Divide each component by a scalar, returning the new point.
|
||||
#[must_use]
|
||||
fn div_s(&self, scalar: Self::Scalar) -> Self;
|
||||
fn div_s(self, scalar: Self::Scalar) -> Self;
|
||||
/// Subtract a scalar from each component, returning the new point.
|
||||
#[must_use]
|
||||
fn rem_s(&self, scalar: Self::Scalar) -> Self;
|
||||
fn rem_s(self, scalar: Self::Scalar) -> Self;
|
||||
|
||||
/// Add a vector to this point, returning the new point.
|
||||
#[must_use]
|
||||
fn add_v(&self, v: &Self::Vector) -> Self;
|
||||
fn add_v(self, v: Self::Vector) -> Self;
|
||||
/// Subtract another point from this one, returning a new vector.
|
||||
fn sub_p(&self, p: &Self) -> Self::Vector;
|
||||
fn sub_p(self, p: Self) -> Self::Vector;
|
||||
|
||||
/// Multiply each component by a scalar, in-place.
|
||||
fn mul_self_s(&mut self, scalar: Self::Scalar);
|
||||
|
@ -118,16 +118,16 @@ pub trait Point: Clone where
|
|||
fn rem_self_s(&mut self, scalar: Self::Scalar);
|
||||
|
||||
/// Add a vector to this point, in-place.
|
||||
fn add_self_v(&mut self, v: &Self::Vector);
|
||||
fn add_self_v(&mut self, v: Self::Vector);
|
||||
|
||||
/// This is a weird one, but its useful for plane calculations.
|
||||
fn dot(&self, v: &Self::Vector) -> Self::Scalar;
|
||||
fn dot(self, v: Self::Vector) -> Self::Scalar;
|
||||
|
||||
#[must_use]
|
||||
fn min(&self, p: &Self) -> Self;
|
||||
fn min(self, p: Self) -> Self;
|
||||
|
||||
#[must_use]
|
||||
fn max(&self, p: &Self) -> Self;
|
||||
fn max(self, p: Self) -> Self;
|
||||
}
|
||||
|
||||
impl<S: BaseNum> Array1 for Point2<S> {
|
||||
|
@ -144,20 +144,20 @@ impl<S: BaseNum> Point for Point2<S> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn from_vec(v: &Vector2<S>) -> Point2<S> {
|
||||
fn from_vec(v: Vector2<S>) -> Point2<S> {
|
||||
Point2::new(v.x, v.y)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn to_vec(&self) -> Vector2<S> {
|
||||
fn to_vec(self) -> Vector2<S> {
|
||||
Vector2::new(self.x, self.y)
|
||||
}
|
||||
|
||||
#[inline] fn mul_s(&self, scalar: S) -> Point2<S> { self * scalar }
|
||||
#[inline] fn div_s(&self, scalar: S) -> Point2<S> { self / scalar }
|
||||
#[inline] fn rem_s(&self, scalar: S) -> Point2<S> { self % scalar }
|
||||
#[inline] fn add_v(&self, v: &Vector2<S>) -> Point2<S> { self + v }
|
||||
#[inline] fn sub_p(&self, p: &Point2<S>) -> Vector2<S> { self - p }
|
||||
#[inline] fn mul_s(self, scalar: S) -> Point2<S> { self * scalar }
|
||||
#[inline] fn div_s(self, scalar: S) -> Point2<S> { self / scalar }
|
||||
#[inline] fn rem_s(self, scalar: S) -> Point2<S> { self % scalar }
|
||||
#[inline] fn add_v(self, v: Vector2<S>) -> Point2<S> { self + v }
|
||||
#[inline] fn sub_p(self, p: Point2<S>) -> Vector2<S> { self - p }
|
||||
|
||||
#[inline]
|
||||
fn mul_self_s(&mut self, scalar: S) {
|
||||
|
@ -178,24 +178,24 @@ impl<S: BaseNum> Point for Point2<S> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn add_self_v(&mut self, v: &Vector2<S>) {
|
||||
fn add_self_v(&mut self, v: Vector2<S>) {
|
||||
self.x = self.x + v.x;
|
||||
self.y = self.y + v.y;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn dot(&self, v: &Vector2<S>) -> S {
|
||||
fn dot(self, v: Vector2<S>) -> S {
|
||||
self.x * v.x +
|
||||
self.y * v.y
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn min(&self, p: &Point2<S>) -> Point2<S> {
|
||||
fn min(self, p: Point2<S>) -> Point2<S> {
|
||||
Point2::new(self.x.partial_min(p.x), self.y.partial_min(p.y))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn max(&self, p: &Point2<S>) -> Point2<S> {
|
||||
fn max(self, p: Point2<S>) -> Point2<S> {
|
||||
Point2::new(self.x.partial_max(p.x), self.y.partial_max(p.y))
|
||||
}
|
||||
}
|
||||
|
@ -224,20 +224,20 @@ impl<S: BaseNum> Point for Point3<S> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn from_vec(v: &Vector3<S>) -> Point3<S> {
|
||||
fn from_vec(v: Vector3<S>) -> Point3<S> {
|
||||
Point3::new(v.x, v.y, v.z)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn to_vec(&self) -> Vector3<S> {
|
||||
fn to_vec(self) -> Vector3<S> {
|
||||
Vector3::new(self.x, self.y, self.z)
|
||||
}
|
||||
|
||||
#[inline] fn mul_s(&self, scalar: S) -> Point3<S> { self * scalar }
|
||||
#[inline] fn div_s(&self, scalar: S) -> Point3<S> { self / scalar }
|
||||
#[inline] fn rem_s(&self, scalar: S) -> Point3<S> { self % scalar }
|
||||
#[inline] fn add_v(&self, v: &Vector3<S>) -> Point3<S> { self + v }
|
||||
#[inline] fn sub_p(&self, p: &Point3<S>) -> Vector3<S> { self - p }
|
||||
#[inline] fn mul_s(self, scalar: S) -> Point3<S> { self * scalar }
|
||||
#[inline] fn div_s(self, scalar: S) -> Point3<S> { self / scalar }
|
||||
#[inline] fn rem_s(self, scalar: S) -> Point3<S> { self % scalar }
|
||||
#[inline] fn add_v(self, v: Vector3<S>) -> Point3<S> { self + v }
|
||||
#[inline] fn sub_p(self, p: Point3<S>) -> Vector3<S> { self - p }
|
||||
|
||||
#[inline]
|
||||
fn mul_self_s(&mut self, scalar: S) {
|
||||
|
@ -261,26 +261,26 @@ impl<S: BaseNum> Point for Point3<S> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn add_self_v(&mut self, v: &Vector3<S>) {
|
||||
fn add_self_v(&mut self, v: Vector3<S>) {
|
||||
self.x = self.x + v.x;
|
||||
self.y = self.y + v.y;
|
||||
self.z = self.z + v.z;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn dot(&self, v: &Vector3<S>) -> S {
|
||||
fn dot(self, v: Vector3<S>) -> S {
|
||||
self.x * v.x +
|
||||
self.y * v.y +
|
||||
self.z * v.z
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn min(&self, p: &Point3<S>) -> Point3<S> {
|
||||
fn min(self, p: Point3<S>) -> Point3<S> {
|
||||
Point3::new(self.x.partial_min(p.x), self.y.partial_min(p.y), self.z.partial_min(p.z))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn max(&self, p: &Point3<S>) -> Point3<S> {
|
||||
fn max(self, p: Point3<S>) -> Point3<S> {
|
||||
Point3::new(self.x.partial_max(p.x), self.y.partial_max(p.y), self.z.partial_max(p.z))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,21 +72,21 @@ impl<S: BaseFloat> Quaternion<S> {
|
|||
|
||||
/// The dot product of the quaternion and `q`.
|
||||
#[inline]
|
||||
pub fn dot(&self, q: &Quaternion<S>) -> S {
|
||||
self.s * q.s + self.v.dot(&q.v)
|
||||
pub fn dot(self, q: Quaternion<S>) -> S {
|
||||
self.s * q.s + self.v.dot(q.v)
|
||||
}
|
||||
|
||||
/// The conjugate of the quaternion.
|
||||
#[inline]
|
||||
pub fn conjugate(&self) -> Quaternion<S> {
|
||||
Quaternion::from_sv(self.s.clone(), -self.v.clone())
|
||||
pub fn conjugate(self) -> Quaternion<S> {
|
||||
Quaternion::from_sv(self.s, -self.v)
|
||||
}
|
||||
|
||||
/// The squared magnitude of the quaternion. This is useful for
|
||||
/// magnitude comparisons where the exact magnitude does not need to be
|
||||
/// calculated.
|
||||
#[inline]
|
||||
pub fn magnitude2(&self) -> S {
|
||||
pub fn magnitude2(self) -> S {
|
||||
self.s * self.s + self.v.length2()
|
||||
}
|
||||
|
||||
|
@ -104,12 +104,12 @@ impl<S: BaseFloat> Quaternion<S> {
|
|||
|
||||
/// Normalize this quaternion, returning the new quaternion.
|
||||
#[inline]
|
||||
pub fn normalize(&self) -> Quaternion<S> {
|
||||
pub fn normalize(self) -> Quaternion<S> {
|
||||
self * (S::one() / self.magnitude())
|
||||
}
|
||||
|
||||
/// Do a normalized linear interpolation with `other`, by `amount`.
|
||||
pub fn nlerp(&self, other: &Quaternion<S>, amount: S) -> Quaternion<S> {
|
||||
pub fn nlerp(self, other: Quaternion<S>, amount: S) -> Quaternion<S> {
|
||||
(&(self * (S::one() - amount)) + &(other * amount)).normalize()
|
||||
}
|
||||
}
|
||||
|
@ -156,8 +156,8 @@ impl<'a, 'b, S: BaseFloat> Mul<&'b Vector3<S>> for &'a Quaternion<S> {
|
|||
#[inline]
|
||||
fn mul(self, vec: &'b Vector3<S>) -> Vector3<S> {
|
||||
let two: S = cast(2i8).unwrap();
|
||||
let tmp = self.v.cross(vec) + (vec * self.s);
|
||||
(self.v.cross(&tmp) * two) + vec
|
||||
let tmp = self.v.cross(*vec) + (vec * self.s);
|
||||
(self.v.cross(tmp) * two) + vec
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -218,7 +218,7 @@ impl<S: BaseFloat> Quaternion<S> {
|
|||
/// (http://number-none.com/product/Understanding%20Slerp,%20Then%20Not%20Using%20It/)
|
||||
/// - [Arcsynthesis OpenGL tutorial]
|
||||
/// (http://www.arcsynthesis.org/gltut/Positioning/Tut08%20Interpolation.html)
|
||||
pub fn slerp(&self, other: &Quaternion<S>, amount: S) -> Quaternion<S> {
|
||||
pub fn slerp(self, other: Quaternion<S>, amount: S) -> Quaternion<S> {
|
||||
let dot = self.dot(other);
|
||||
let dot_threshold = cast(0.9995f64).unwrap();
|
||||
|
||||
|
@ -251,7 +251,7 @@ impl<S: BaseFloat> Quaternion<S> {
|
|||
/// Based on:
|
||||
/// - [Maths - Conversion Quaternion to Euler]
|
||||
/// (http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/)
|
||||
pub fn to_euler(&self) -> (Rad<S>, Rad<S>, Rad<S>) {
|
||||
pub fn to_euler(self) -> (Rad<S>, Rad<S>, Rad<S>) {
|
||||
let sig: S = cast(0.499f64).unwrap();
|
||||
let two: S = cast(2f64).unwrap();
|
||||
let one: S = cast(1f64).unwrap();
|
||||
|
@ -367,19 +367,19 @@ impl<S: BaseFloat> Rotation<Point3<S>> for Quaternion<S> {
|
|||
fn one() -> Quaternion<S> { Quaternion::one() }
|
||||
|
||||
#[inline]
|
||||
fn look_at(dir: &Vector3<S>, up: &Vector3<S>) -> Quaternion<S> {
|
||||
fn look_at(dir: Vector3<S>, up: Vector3<S>) -> Quaternion<S> {
|
||||
Matrix3::look_at(dir, up).into()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn between_vectors(a: &Vector3<S>, b: &Vector3<S>) -> Quaternion<S> {
|
||||
fn between_vectors(a: Vector3<S>, b: Vector3<S>) -> Quaternion<S> {
|
||||
//http://stackoverflow.com/questions/1171849/
|
||||
//finding-quaternion-representing-the-rotation-from-one-vector-to-another
|
||||
Quaternion::from_sv(S::one() + a.dot(b), a.cross(b)).normalize()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn rotate_vector(&self, vec: &Vector3<S>) -> Vector3<S> { self * vec }
|
||||
fn rotate_vector(&self, vec: Vector3<S>) -> Vector3<S> { self * &vec }
|
||||
|
||||
#[inline]
|
||||
fn concat(&self, other: &Quaternion<S>) -> Quaternion<S> { self * other }
|
||||
|
@ -396,7 +396,7 @@ impl<S: BaseFloat> Rotation<Point3<S>> for Quaternion<S> {
|
|||
|
||||
impl<S: BaseFloat> Rotation3<S> for Quaternion<S> where S: 'static {
|
||||
#[inline]
|
||||
fn from_axis_angle(axis: &Vector3<S>, angle: Rad<S>) -> Quaternion<S> {
|
||||
fn from_axis_angle(axis: Vector3<S>, angle: Rad<S>) -> Quaternion<S> {
|
||||
let (s, c) = sin_cos(angle.mul_s(cast(0.5f64).unwrap()));
|
||||
Quaternion::from_sv(c, axis.mul_s(s))
|
||||
}
|
||||
|
|
|
@ -34,20 +34,20 @@ pub trait Rotation<P: Point>: PartialEq + Sized where
|
|||
fn one() -> Self;
|
||||
|
||||
/// Create a rotation to a given direction with an 'up' vector
|
||||
fn look_at(dir: &P::Vector, up: &P::Vector) -> Self;
|
||||
fn look_at(dir: P::Vector, up: P::Vector) -> Self;
|
||||
|
||||
/// Create a shortest rotation to transform vector 'a' into 'b'.
|
||||
/// Both given vectors are assumed to have unit length.
|
||||
fn between_vectors(a: &P::Vector, b: &P::Vector) -> Self;
|
||||
fn between_vectors(a: P::Vector, b: P::Vector) -> Self;
|
||||
|
||||
/// Rotate a vector using this rotation.
|
||||
fn rotate_vector(&self, vec: &P::Vector) -> P::Vector;
|
||||
fn rotate_vector(&self, vec: P::Vector) -> P::Vector;
|
||||
|
||||
/// Rotate a point using this rotation, by converting it to its
|
||||
/// representation as a vector.
|
||||
#[inline]
|
||||
fn rotate_point(&self, point: &P) -> P {
|
||||
P::from_vec(&self.rotate_vector(&point.to_vec()))
|
||||
fn rotate_point(&self, point: P) -> P {
|
||||
P::from_vec(self.rotate_vector(point.to_vec()))
|
||||
}
|
||||
|
||||
/// Create a new rotation which combines both this rotation, and another.
|
||||
|
@ -85,7 +85,7 @@ pub trait Rotation3<S: BaseFloat>: Rotation<Point3<S>>
|
|||
+ Into<Basis3<S>>
|
||||
+ Into<Quaternion<S>> {
|
||||
/// Create a rotation using an angle around a given axis.
|
||||
fn from_axis_angle(axis: &Vector3<S>, angle: Rad<S>) -> Self;
|
||||
fn from_axis_angle(axis: Vector3<S>, angle: Rad<S>) -> Self;
|
||||
|
||||
/// Create a rotation from a set of euler angles.
|
||||
///
|
||||
|
@ -99,19 +99,19 @@ pub trait Rotation3<S: BaseFloat>: Rotation<Point3<S>>
|
|||
/// Create a rotation from an angle around the `x` axis (pitch).
|
||||
#[inline]
|
||||
fn from_angle_x(theta: Rad<S>) -> Self {
|
||||
Rotation3::from_axis_angle(&Vector3::unit_x(), theta)
|
||||
Rotation3::from_axis_angle(Vector3::unit_x(), theta)
|
||||
}
|
||||
|
||||
/// Create a rotation from an angle around the `y` axis (yaw).
|
||||
#[inline]
|
||||
fn from_angle_y(theta: Rad<S>) -> Self {
|
||||
Rotation3::from_axis_angle(&Vector3::unit_y(), theta)
|
||||
Rotation3::from_axis_angle(Vector3::unit_y(), theta)
|
||||
}
|
||||
|
||||
/// Create a rotation from an angle around the `z` axis (roll).
|
||||
#[inline]
|
||||
fn from_angle_z(theta: Rad<S>) -> Self {
|
||||
Rotation3::from_axis_angle(&Vector3::unit_z(), theta)
|
||||
Rotation3::from_axis_angle(Vector3::unit_z(), theta)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -143,7 +143,7 @@ pub trait Rotation3<S: BaseFloat>: Rotation<Point3<S>>
|
|||
/// let rot: Basis2<f64> = Rotation2::from_angle(rad(0.5f64 * f64::consts::PI));
|
||||
///
|
||||
/// // Rotate the vector using the two-dimensional rotation matrix:
|
||||
/// let unit_y = rot.rotate_vector(&unit_x);
|
||||
/// let unit_y = rot.rotate_vector(unit_x);
|
||||
///
|
||||
/// // Since sin(π/2) may not be exactly zero due to rounding errors, we can
|
||||
/// // use cgmath's approx_eq() feature to show that it is close enough.
|
||||
|
@ -151,12 +151,12 @@ pub trait Rotation3<S: BaseFloat>: Rotation<Point3<S>>
|
|||
///
|
||||
/// // This is exactly equivalent to using the raw matrix itself:
|
||||
/// let unit_y2: Matrix2<_> = rot.into();
|
||||
/// let unit_y2 = unit_y2.mul_v(&unit_x);
|
||||
/// let unit_y2 = unit_y2.mul_v(unit_x);
|
||||
/// assert_eq!(unit_y2, unit_y);
|
||||
///
|
||||
/// // Note that we can also concatenate rotations:
|
||||
/// let rot_half: Basis2<f64> = Rotation2::from_angle(rad(0.25f64 * f64::consts::PI));
|
||||
/// let unit_y3 = rot_half.concat(&rot_half).rotate_vector(&unit_x);
|
||||
/// let unit_y3 = rot_half.concat(&rot_half).rotate_vector(unit_x);
|
||||
/// assert!(unit_y3.approx_eq(&unit_y2));
|
||||
/// ```
|
||||
#[derive(PartialEq, Copy, Clone, RustcEncodable, RustcDecodable)]
|
||||
|
@ -181,17 +181,17 @@ impl<S: BaseFloat> Rotation<Point2<S>> for Basis2<S> {
|
|||
fn one() -> Basis2<S> { Basis2 { mat: Matrix2::one() } }
|
||||
|
||||
#[inline]
|
||||
fn look_at(dir: &Vector2<S>, up: &Vector2<S>) -> Basis2<S> {
|
||||
fn look_at(dir: Vector2<S>, up: Vector2<S>) -> Basis2<S> {
|
||||
Basis2 { mat: Matrix2::look_at(dir, up) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn between_vectors(a: &Vector2<S>, b: &Vector2<S>) -> Basis2<S> {
|
||||
fn between_vectors(a: Vector2<S>, b: Vector2<S>) -> Basis2<S> {
|
||||
Rotation2::from_angle(acos(a.dot(b)) )
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn rotate_vector(&self, vec: &Vector2<S>) -> Vector2<S> { self.mat.mul_v(vec) }
|
||||
fn rotate_vector(&self, vec: Vector2<S>) -> Vector2<S> { self.mat.mul_v(vec) }
|
||||
|
||||
#[inline]
|
||||
fn concat(&self, other: &Basis2<S>) -> Basis2<S> { Basis2 { mat: self.mat.mul_m(&other.mat) } }
|
||||
|
@ -264,18 +264,18 @@ impl<S: BaseFloat> Rotation<Point3<S>> for Basis3<S> {
|
|||
fn one() -> Basis3<S> { Basis3 { mat: Matrix3::one() } }
|
||||
|
||||
#[inline]
|
||||
fn look_at(dir: &Vector3<S>, up: &Vector3<S>) -> Basis3<S> {
|
||||
fn look_at(dir: Vector3<S>, up: Vector3<S>) -> Basis3<S> {
|
||||
Basis3 { mat: Matrix3::look_at(dir, up) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn between_vectors(a: &Vector3<S>, b: &Vector3<S>) -> Basis3<S> {
|
||||
fn between_vectors(a: Vector3<S>, b: Vector3<S>) -> Basis3<S> {
|
||||
let q: Quaternion<S> = Rotation::between_vectors(a, b);
|
||||
q.into()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn rotate_vector(&self, vec: &Vector3<S>) -> Vector3<S> { self.mat.mul_v(vec) }
|
||||
fn rotate_vector(&self, vec: Vector3<S>) -> Vector3<S> { self.mat.mul_v(vec) }
|
||||
|
||||
#[inline]
|
||||
fn concat(&self, other: &Basis3<S>) -> Basis3<S> { Basis3 { mat: self.mat.mul_m(&other.mat) } }
|
||||
|
@ -304,7 +304,7 @@ impl<S: BaseFloat> ApproxEq for Basis3<S> {
|
|||
}
|
||||
|
||||
impl<S: BaseFloat> Rotation3<S> for Basis3<S> {
|
||||
fn from_axis_angle(axis: &Vector3<S>, angle: Rad<S>) -> Basis3<S> {
|
||||
fn from_axis_angle(axis: Vector3<S>, angle: Rad<S>) -> Basis3<S> {
|
||||
Basis3 { mat: Matrix3::from_axis_angle(axis, angle) }
|
||||
}
|
||||
|
||||
|
|
|
@ -34,18 +34,18 @@ pub trait Transform<P: Point>: Sized {
|
|||
|
||||
/// Create a transformation that rotates a vector to look at `center` from
|
||||
/// `eye`, using `up` for orientation.
|
||||
fn look_at(eye: &P, center: &P, up: &P::Vector) -> Self;
|
||||
fn look_at(eye: P, center: P, up: P::Vector) -> Self;
|
||||
|
||||
/// Transform a vector using this transform.
|
||||
fn transform_vector(&self, vec: &P::Vector) -> P::Vector;
|
||||
fn transform_vector(&self, vec: P::Vector) -> P::Vector;
|
||||
|
||||
/// Transform a point using this transform.
|
||||
fn transform_point(&self, point: &P) -> P;
|
||||
fn transform_point(&self, point: P) -> P;
|
||||
|
||||
/// Transform a vector as a point using this transform.
|
||||
#[inline]
|
||||
fn transform_as_point(&self, vec: &P::Vector) -> P::Vector {
|
||||
self.transform_point(&P::from_vec(vec)).to_vec()
|
||||
fn transform_as_point(&self, vec: P::Vector) -> P::Vector {
|
||||
self.transform_point(P::from_vec(vec)).to_vec()
|
||||
}
|
||||
|
||||
/// Combine this transform with another, yielding a new transformation
|
||||
|
@ -92,9 +92,9 @@ impl<P: Point, R: Rotation<P>> Transform<P> for Decomposed<P::Vector, R> where
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn look_at(eye: &P, center: &P, up: &P::Vector) -> Decomposed<P::Vector, R> {
|
||||
let rot = R::look_at(¢er.sub_p(eye), up);
|
||||
let disp = rot.rotate_vector(&P::origin().sub_p(eye));
|
||||
fn look_at(eye: P, center: P, up: P::Vector) -> Decomposed<P::Vector, R> {
|
||||
let rot = R::look_at(center.sub_p(eye.clone()), up);
|
||||
let disp = rot.rotate_vector(P::origin().sub_p(eye));
|
||||
Decomposed {
|
||||
scale: <P as Point>::Scalar::one(),
|
||||
rot: rot,
|
||||
|
@ -103,20 +103,20 @@ impl<P: Point, R: Rotation<P>> Transform<P> for Decomposed<P::Vector, R> where
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn transform_vector(&self, vec: &P::Vector) -> P::Vector {
|
||||
self.rot.rotate_vector(&vec.mul_s(self.scale.clone()))
|
||||
fn transform_vector(&self, vec: P::Vector) -> P::Vector {
|
||||
self.rot.rotate_vector(vec.mul_s(self.scale))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn transform_point(&self, point: &P) -> P {
|
||||
self.rot.rotate_point(&point.mul_s(self.scale.clone())).add_v(&self.disp)
|
||||
fn transform_point(&self, point: P) -> P {
|
||||
self.rot.rotate_point(point.mul_s(self.scale)).add_v(self.disp.clone())
|
||||
}
|
||||
|
||||
fn concat(&self, other: &Decomposed<P::Vector, R>) -> Decomposed<P::Vector, R> {
|
||||
Decomposed {
|
||||
scale: self.scale * other.scale,
|
||||
rot: self.rot.concat(&other.rot),
|
||||
disp: self.transform_as_point(&other.disp),
|
||||
disp: self.transform_as_point(other.disp.clone()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,7 +126,7 @@ impl<P: Point, R: Rotation<P>> Transform<P> for Decomposed<P::Vector, R> where
|
|||
} else {
|
||||
let s = <P as Point>::Scalar::one() / self.scale;
|
||||
let r = self.rot.invert();
|
||||
let d = r.rotate_vector(&self.disp).mul_s(-s);
|
||||
let d = r.rotate_vector(self.disp.clone()).mul_s(-s);
|
||||
Some(Decomposed {
|
||||
scale: s,
|
||||
rot: r,
|
||||
|
@ -181,18 +181,18 @@ impl<S: BaseFloat> Transform<Point3<S>> for AffineMatrix3<S> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn look_at(eye: &Point3<S>, center: &Point3<S>, up: &Vector3<S>) -> AffineMatrix3<S> {
|
||||
fn look_at(eye: Point3<S>, center: Point3<S>, up: Vector3<S>) -> AffineMatrix3<S> {
|
||||
AffineMatrix3 { mat: Matrix4::look_at(eye, center, up) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn transform_vector(&self, vec: &Vector3<S>) -> Vector3<S> {
|
||||
self.mat.mul_v(&vec.extend(S::zero())).truncate()
|
||||
fn transform_vector(&self, vec: Vector3<S>) -> Vector3<S> {
|
||||
self.mat.mul_v(vec.extend(S::zero())).truncate()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn transform_point(&self, point: &Point3<S>) -> Point3<S> {
|
||||
Point3::from_homogeneous(&self.mat.mul_v(&point.to_homogeneous()))
|
||||
fn transform_point(&self, point: Point3<S>) -> Point3<S> {
|
||||
Point3::from_homogeneous(self.mat.mul_v(point.to_homogeneous()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
140
src/vector.rs
140
src/vector.rs
|
@ -39,9 +39,9 @@
|
|||
//! let a: Vector2<f64> = Vector2::new(3.0, 4.0);
|
||||
//! let b: Vector2<f64> = Vector2::new(-3.0, -4.0);
|
||||
//!
|
||||
//! assert_eq!(&a + &b, Vector2::zero());
|
||||
//! assert_eq!(-(&a * &b), Vector2::new(9.0f64, 16.0f64));
|
||||
//! assert_eq!(&a / &Vector2::one(), a);
|
||||
//! assert_eq!(a + b, Vector2::zero());
|
||||
//! assert_eq!(-(a * b), Vector2::new(9.0f64, 16.0f64));
|
||||
//! assert_eq!(a / Vector2::one(), a);
|
||||
//!
|
||||
//! // As with Rust's `int` and `f32` types, Vectors of different types cannot
|
||||
//! // be added and so on with impunity. The following will fail to compile:
|
||||
|
@ -49,10 +49,10 @@
|
|||
//!
|
||||
//! // Instead, we need to convert the Vector2 to a Vector3 by "extending" it
|
||||
//! // with the value for the last coordinate:
|
||||
//! let c: Vector3<f64> = &a.extend(0.0) + &Vector3::new(1.0, 0.0, 2.0);
|
||||
//! let c: Vector3<f64> = a.extend(0.0) + Vector3::new(1.0, 0.0, 2.0);
|
||||
//!
|
||||
//! // Similarly, we can "truncate" a Vector4 down to a Vector3:
|
||||
//! let d: Vector3<f64> = &c + &Vector4::unit_x().truncate();
|
||||
//! let d: Vector3<f64> = c + Vector4::unit_x().truncate();
|
||||
//!
|
||||
//! assert_eq!(d, Vector3::new(5.0f64, 4.0f64, 2.0f64));
|
||||
//! ```
|
||||
|
@ -68,10 +68,10 @@
|
|||
//! // All vectors implement the dot product as a method:
|
||||
//! let a: Vector2<f64> = Vector2::new(3.0, 6.0);
|
||||
//! let b: Vector2<f64> = Vector2::new(-2.0, 1.0);
|
||||
//! assert_eq!(a.dot(&b), 0.0);
|
||||
//! assert_eq!(a.dot(b), 0.0);
|
||||
//!
|
||||
//! // But there is also a top-level function:
|
||||
//! assert_eq!(a.dot(&b), dot(a, b));
|
||||
//! assert_eq!(a.dot(b), dot(a, b));
|
||||
//!
|
||||
//! // Scalar multiplication can return a new object, or be done in place
|
||||
//! // to avoid an allocation:
|
||||
|
@ -83,7 +83,7 @@
|
|||
//! // Cross products are defined for 3-dimensional vectors:
|
||||
//! let e: Vector3<f64> = Vector3::unit_x();
|
||||
//! let f: Vector3<f64> = Vector3::unit_y();
|
||||
//! assert_eq!(e.cross(&f), Vector3::unit_z());
|
||||
//! assert_eq!(e.cross(f), Vector3::unit_z());
|
||||
//! ```
|
||||
//!
|
||||
//! Several other useful methods are provided as well. Vector fields can be
|
||||
|
@ -111,7 +111,7 @@ use num::{BaseNum, BaseFloat};
|
|||
/// A trait that specifies a range of numeric operations for vectors. Not all
|
||||
/// of these make sense from a linear algebra point of view, but are included
|
||||
/// for pragmatic reasons.
|
||||
pub trait Vector: Clone where
|
||||
pub trait Vector: Copy + Clone where
|
||||
// FIXME: Ugly type signatures - blocked by rust-lang/rust#24092
|
||||
Self: Array1<Element = <Self as Vector>::Scalar>,
|
||||
// FIXME: blocked by rust-lang/rust#20671
|
||||
|
@ -144,35 +144,35 @@ pub trait Vector: Clone where
|
|||
|
||||
/// Add a scalar to this vector, returning a new vector.
|
||||
#[must_use]
|
||||
fn add_s(&self, scalar: Self::Scalar) -> Self;
|
||||
fn add_s(self, scalar: Self::Scalar) -> Self;
|
||||
/// Subtract a scalar from this vector, returning a new vector.
|
||||
#[must_use]
|
||||
fn sub_s(&self, scalar: Self::Scalar) -> Self;
|
||||
fn sub_s(self, scalar: Self::Scalar) -> Self;
|
||||
/// Multiply this vector by a scalar, returning a new vector.
|
||||
#[must_use]
|
||||
fn mul_s(&self, scalar: Self::Scalar) -> Self;
|
||||
fn mul_s(self, scalar: Self::Scalar) -> Self;
|
||||
/// Divide this vector by a scalar, returning a new vector.
|
||||
#[must_use]
|
||||
fn div_s(&self, scalar: Self::Scalar) -> Self;
|
||||
fn div_s(self, scalar: Self::Scalar) -> Self;
|
||||
/// Take the remainder of this vector by a scalar, returning a new vector.
|
||||
#[must_use]
|
||||
fn rem_s(&self, scalar: Self::Scalar) -> Self;
|
||||
fn rem_s(self, scalar: Self::Scalar) -> Self;
|
||||
|
||||
/// Add this vector to another, returning a new vector.
|
||||
#[must_use]
|
||||
fn add_v(&self, v: &Self) -> Self;
|
||||
fn add_v(self, v: Self) -> Self;
|
||||
/// Subtract another vector from this one, returning a new vector.
|
||||
#[must_use]
|
||||
fn sub_v(&self, v: &Self) -> Self;
|
||||
fn sub_v(self, v: Self) -> Self;
|
||||
/// Multiply this vector by another, returning a new vector.
|
||||
#[must_use]
|
||||
fn mul_v(&self, v: &Self) -> Self;
|
||||
fn mul_v(self, v: Self) -> Self;
|
||||
/// Divide this vector by another, returning a new vector.
|
||||
#[must_use]
|
||||
fn div_v(&self, v: &Self) -> Self;
|
||||
fn div_v(self, v: Self) -> Self;
|
||||
/// Take the remainder of this vector by another, returning a new scalar.
|
||||
#[must_use]
|
||||
fn rem_v(&self, v: &Self) -> Self;
|
||||
fn rem_v(self, v: Self) -> Self;
|
||||
|
||||
/// Add a scalar to this vector in-place.
|
||||
fn add_self_s(&mut self, scalar: Self::Scalar);
|
||||
|
@ -186,33 +186,33 @@ pub trait Vector: Clone where
|
|||
fn rem_self_s(&mut self, scalar: Self::Scalar);
|
||||
|
||||
/// Add another vector to this one, in-place.
|
||||
fn add_self_v(&mut self, v: &Self);
|
||||
fn add_self_v(&mut self, v: Self);
|
||||
/// Subtract another vector from this one, in-place.
|
||||
fn sub_self_v(&mut self, v: &Self);
|
||||
fn sub_self_v(&mut self, v: Self);
|
||||
/// Multiply this matrix by another, in-place.
|
||||
fn mul_self_v(&mut self, v: &Self);
|
||||
fn mul_self_v(&mut self, v: Self);
|
||||
/// Divide this matrix by anothor, in-place.
|
||||
fn div_self_v(&mut self, v: &Self);
|
||||
fn div_self_v(&mut self, v: Self);
|
||||
/// Take the remainder of this vector by another, in-place.
|
||||
fn rem_self_v(&mut self, v: &Self);
|
||||
fn rem_self_v(&mut self, v: Self);
|
||||
|
||||
/// The sum of the components of the vector.
|
||||
fn sum(&self) -> Self::Scalar;
|
||||
fn sum(self) -> Self::Scalar;
|
||||
/// The product of the components of the vector.
|
||||
fn product(&self) -> Self::Scalar;
|
||||
fn product(self) -> Self::Scalar;
|
||||
|
||||
/// Vector dot product.
|
||||
#[inline]
|
||||
fn dot(&self, v: &Self) -> Self::Scalar { self.mul_v(v).sum() }
|
||||
fn dot(self, v: Self) -> Self::Scalar { self.mul_v(v).sum() }
|
||||
|
||||
/// The minimum component of the vector.
|
||||
fn comp_min(&self) -> Self::Scalar;
|
||||
fn comp_min(self) -> Self::Scalar;
|
||||
/// The maximum component of the vector.
|
||||
fn comp_max(&self) -> Self::Scalar;
|
||||
fn comp_max(self) -> Self::Scalar;
|
||||
}
|
||||
|
||||
/// Dot product of two vectors.
|
||||
#[inline] pub fn dot<V: Vector>(a: V, b: V) -> V::Scalar { a.dot(&b) }
|
||||
#[inline] pub fn dot<V: Vector>(a: V, b: V) -> V::Scalar { a.dot(b) }
|
||||
|
||||
// Utility macro for generating associated functions for the vectors
|
||||
macro_rules! vec {
|
||||
|
@ -259,17 +259,17 @@ macro_rules! vec {
|
|||
|
||||
#[inline] fn from_value(scalar: S) -> $VectorN<S> { $VectorN { $($field: scalar),+ } }
|
||||
|
||||
#[inline] fn add_s(&self, scalar: S) -> $VectorN<S> { self + scalar }
|
||||
#[inline] fn sub_s(&self, scalar: S) -> $VectorN<S> { self - scalar }
|
||||
#[inline] fn mul_s(&self, scalar: S) -> $VectorN<S> { self * scalar }
|
||||
#[inline] fn div_s(&self, scalar: S) -> $VectorN<S> { self / scalar }
|
||||
#[inline] fn rem_s(&self, scalar: S) -> $VectorN<S> { self % scalar }
|
||||
#[inline] fn add_s(self, scalar: S) -> $VectorN<S> { self + scalar }
|
||||
#[inline] fn sub_s(self, scalar: S) -> $VectorN<S> { self - scalar }
|
||||
#[inline] fn mul_s(self, scalar: S) -> $VectorN<S> { self * scalar }
|
||||
#[inline] fn div_s(self, scalar: S) -> $VectorN<S> { self / scalar }
|
||||
#[inline] fn rem_s(self, scalar: S) -> $VectorN<S> { self % scalar }
|
||||
|
||||
#[inline] fn add_v(&self, v: &$VectorN<S>) -> $VectorN<S> { self + v }
|
||||
#[inline] fn sub_v(&self, v: &$VectorN<S>) -> $VectorN<S> { self - v }
|
||||
#[inline] fn mul_v(&self, v: &$VectorN<S>) -> $VectorN<S> { self * v }
|
||||
#[inline] fn div_v(&self, v: &$VectorN<S>) -> $VectorN<S> { self / v }
|
||||
#[inline] fn rem_v(&self, v: &$VectorN<S>) -> $VectorN<S> { self % v }
|
||||
#[inline] fn add_v(self, v: $VectorN<S>) -> $VectorN<S> { self + v }
|
||||
#[inline] fn sub_v(self, v: $VectorN<S>) -> $VectorN<S> { self - v }
|
||||
#[inline] fn mul_v(self, v: $VectorN<S>) -> $VectorN<S> { self * v }
|
||||
#[inline] fn div_v(self, v: $VectorN<S>) -> $VectorN<S> { self / v }
|
||||
#[inline] fn rem_v(self, v: $VectorN<S>) -> $VectorN<S> { self % v }
|
||||
|
||||
#[inline] fn add_self_s(&mut self, scalar: S) { *self = &*self + scalar; }
|
||||
#[inline] fn sub_self_s(&mut self, scalar: S) { *self = &*self - scalar; }
|
||||
|
@ -277,16 +277,16 @@ macro_rules! vec {
|
|||
#[inline] fn div_self_s(&mut self, scalar: S) { *self = &*self / scalar; }
|
||||
#[inline] fn rem_self_s(&mut self, scalar: S) { *self = &*self % scalar; }
|
||||
|
||||
#[inline] fn add_self_v(&mut self, v: &$VectorN<S>) { *self = &*self + v; }
|
||||
#[inline] fn sub_self_v(&mut self, v: &$VectorN<S>) { *self = &*self - v; }
|
||||
#[inline] fn mul_self_v(&mut self, v: &$VectorN<S>) { *self = &*self * v; }
|
||||
#[inline] fn div_self_v(&mut self, v: &$VectorN<S>) { *self = &*self / v; }
|
||||
#[inline] fn rem_self_v(&mut self, v: &$VectorN<S>) { *self = &*self % v; }
|
||||
#[inline] fn add_self_v(&mut self, v: $VectorN<S>) { *self = &*self + v; }
|
||||
#[inline] fn sub_self_v(&mut self, v: $VectorN<S>) { *self = &*self - v; }
|
||||
#[inline] fn mul_self_v(&mut self, v: $VectorN<S>) { *self = &*self * v; }
|
||||
#[inline] fn div_self_v(&mut self, v: $VectorN<S>) { *self = &*self / v; }
|
||||
#[inline] fn rem_self_v(&mut self, v: $VectorN<S>) { *self = &*self % v; }
|
||||
|
||||
#[inline] fn sum(&self) -> S { fold!(add, { $(self.$field),+ }) }
|
||||
#[inline] fn product(&self) -> S { fold!(mul, { $(self.$field),+ }) }
|
||||
#[inline] fn comp_min(&self) -> S { fold!(partial_min, { $(self.$field),+ }) }
|
||||
#[inline] fn comp_max(&self) -> S { fold!(partial_max, { $(self.$field),+ }) }
|
||||
#[inline] fn sum(self) -> S { fold!(add, { $(self.$field),+ }) }
|
||||
#[inline] fn product(self) -> S { fold!(mul, { $(self.$field),+ }) }
|
||||
#[inline] fn comp_min(self) -> S { fold!(partial_min, { $(self.$field),+ }) }
|
||||
#[inline] fn comp_max(self) -> S { fold!(partial_max, { $(self.$field),+ }) }
|
||||
}
|
||||
|
||||
impl<S: Neg<Output = S>> Neg for $VectorN<S> {
|
||||
|
@ -555,14 +555,14 @@ impl<S: BaseNum> Vector2<S> {
|
|||
|
||||
/// The perpendicular dot product of the vector and `other`.
|
||||
#[inline]
|
||||
pub fn perp_dot(&self, other: &Vector2<S>) -> S {
|
||||
pub fn perp_dot(self, other: Vector2<S>) -> S {
|
||||
(self.x * other.y) - (self.y * other.x)
|
||||
}
|
||||
|
||||
/// Create a `Vector3`, using the `x` and `y` values from this vector, and the
|
||||
/// provided `z`.
|
||||
#[inline]
|
||||
pub fn extend(&self, z: S)-> Vector3<S> {
|
||||
pub fn extend(self, z: S)-> Vector3<S> {
|
||||
Vector3::new(self.x, self.y, z)
|
||||
}
|
||||
}
|
||||
|
@ -590,7 +590,7 @@ impl<S: BaseNum> Vector3<S> {
|
|||
/// Returns the cross product of the vector and `other`.
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn cross(&self, other: &Vector3<S>) -> Vector3<S> {
|
||||
pub fn cross(self, other: Vector3<S>) -> Vector3<S> {
|
||||
Vector3::new((self.y * other.z) - (self.z * other.y),
|
||||
(self.z * other.x) - (self.x * other.z),
|
||||
(self.x * other.y) - (self.y * other.x))
|
||||
|
@ -599,20 +599,20 @@ impl<S: BaseNum> Vector3<S> {
|
|||
/// Calculates the cross product of the vector and `other`, then stores the
|
||||
/// result in `self`.
|
||||
#[inline]
|
||||
pub fn cross_self(&mut self, other: &Vector3<S>) {
|
||||
pub fn cross_self(&mut self, other: Vector3<S>) {
|
||||
*self = self.cross(other)
|
||||
}
|
||||
|
||||
/// Create a `Vector4`, using the `x`, `y` and `z` values from this vector, and the
|
||||
/// provided `w`.
|
||||
#[inline]
|
||||
pub fn extend(&self, w: S)-> Vector4<S> {
|
||||
pub fn extend(self, w: S)-> Vector4<S> {
|
||||
Vector4::new(self.x, self.y, self.z, w)
|
||||
}
|
||||
|
||||
/// Create a `Vector2`, dropping the `z` value.
|
||||
#[inline]
|
||||
pub fn truncate(&self)-> Vector2<S> {
|
||||
pub fn truncate(self)-> Vector2<S> {
|
||||
Vector2::new(self.x, self.y)
|
||||
}
|
||||
}
|
||||
|
@ -645,7 +645,7 @@ impl<S: BaseNum> Vector4<S> {
|
|||
|
||||
/// Create a `Vector3`, dropping the `w` value.
|
||||
#[inline]
|
||||
pub fn truncate(&self)-> Vector3<S> {
|
||||
pub fn truncate(self)-> Vector3<S> {
|
||||
Vector3::new(self.x, self.y, self.z)
|
||||
}
|
||||
|
||||
|
@ -671,7 +671,7 @@ pub trait EuclideanVector: Vector + Sized where
|
|||
{
|
||||
/// Returns `true` if the vector is perpendicular (at right angles) to the
|
||||
/// other vector.
|
||||
fn is_perpendicular(&self, other: &Self) -> bool {
|
||||
fn is_perpendicular(self, other: Self) -> bool {
|
||||
self.dot(other).approx_eq(&Self::Scalar::zero())
|
||||
}
|
||||
|
||||
|
@ -679,32 +679,32 @@ pub trait EuclideanVector: Vector + Sized where
|
|||
/// expensive square root operation like in the `length` method and can
|
||||
/// therefore be more efficient for comparing the lengths of two vectors.
|
||||
#[inline]
|
||||
fn length2(&self) -> Self::Scalar {
|
||||
fn length2(self) -> Self::Scalar {
|
||||
self.dot(self)
|
||||
}
|
||||
|
||||
/// The norm of the vector.
|
||||
#[inline]
|
||||
fn length(&self) -> Self::Scalar {
|
||||
fn length(self) -> Self::Scalar {
|
||||
// Not sure why these annotations are needed
|
||||
<<Self as Vector>::Scalar as ::rust_num::Float>::sqrt(self.dot(self))
|
||||
}
|
||||
|
||||
/// The angle between the vector and `other`, in radians.
|
||||
fn angle(&self, other: &Self) -> Rad<Self::Scalar>;
|
||||
fn angle(self, other: Self) -> Rad<Self::Scalar>;
|
||||
|
||||
/// Returns a vector with the same direction, but with a `length` (or
|
||||
/// `norm`) of `1`.
|
||||
#[inline]
|
||||
#[must_use]
|
||||
fn normalize(&self) -> Self {
|
||||
fn normalize(self) -> Self {
|
||||
self.normalize_to(Self::Scalar::one())
|
||||
}
|
||||
|
||||
/// Returns a vector with the same direction and a given `length`.
|
||||
#[inline]
|
||||
#[must_use]
|
||||
fn normalize_to(&self, length: Self::Scalar) -> Self {
|
||||
fn normalize_to(self, length: Self::Scalar) -> Self {
|
||||
self.mul_s(length / self.length())
|
||||
}
|
||||
|
||||
|
@ -712,8 +712,8 @@ pub trait EuclideanVector: Vector + Sized where
|
|||
/// towards the length of `other` by the specified amount.
|
||||
#[inline]
|
||||
#[must_use]
|
||||
fn lerp(&self, other: &Self, amount: Self::Scalar) -> Self {
|
||||
self.add_v(&other.sub_v(self).mul_s(amount))
|
||||
fn lerp(self, other: Self, amount: Self::Scalar) -> Self {
|
||||
self.add_v(other.sub_v(self).mul_s(amount))
|
||||
}
|
||||
|
||||
/// Normalises the vector to a length of `1`.
|
||||
|
@ -733,29 +733,29 @@ pub trait EuclideanVector: Vector + Sized where
|
|||
|
||||
/// Linearly interpolates the length of the vector towards the length of
|
||||
/// `other` by the specified amount.
|
||||
fn lerp_self(&mut self, other: &Self, amount: Self::Scalar) {
|
||||
let v = other.sub_v(self).mul_s(amount);
|
||||
self.add_self_v(&v);
|
||||
fn lerp_self(&mut self, other: Self, amount: Self::Scalar) {
|
||||
let v = other.sub_v(*self).mul_s(amount);
|
||||
self.add_self_v(v);
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> EuclideanVector for Vector2<S> {
|
||||
#[inline]
|
||||
fn angle(&self, other: &Vector2<S>) -> Rad<S> {
|
||||
fn angle(self, other: Vector2<S>) -> Rad<S> {
|
||||
atan2(self.perp_dot(other), self.dot(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> EuclideanVector for Vector3<S> {
|
||||
#[inline]
|
||||
fn angle(&self, other: &Vector3<S>) -> Rad<S> {
|
||||
fn angle(self, other: Vector3<S>) -> Rad<S> {
|
||||
atan2(self.cross(other).length(), self.dot(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> EuclideanVector for Vector4<S> {
|
||||
#[inline]
|
||||
fn angle(&self, other: &Vector4<S>) -> Rad<S> {
|
||||
fn angle(self, other: Vector4<S>) -> Rad<S> {
|
||||
acos(self.dot(other) / (self.length() * other.length()))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -193,9 +193,9 @@ fn test_sub_m() {
|
|||
|
||||
#[test]
|
||||
fn test_mul_v() {
|
||||
assert_eq!(matrix2::A.mul_v(&matrix2::V), Vector2::new(5.0f64, 11.0f64));
|
||||
assert_eq!(matrix3::A.mul_v(&matrix3::V), Vector3::new(14.0f64, 32.0f64, 50.0f64));
|
||||
assert_eq!(matrix4::A.mul_v(&matrix4::V), Vector4::new(30.0f64, 70.0f64, 110.0f64, 150.0f64));
|
||||
assert_eq!(matrix2::A.mul_v(matrix2::V), Vector2::new(5.0f64, 11.0f64));
|
||||
assert_eq!(matrix3::A.mul_v(matrix3::V), Vector3::new(14.0f64, 32.0f64, 50.0f64));
|
||||
assert_eq!(matrix4::A.mul_v(matrix4::V), Vector4::new(30.0f64, 70.0f64, 110.0f64, 150.0f64));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -328,9 +328,9 @@ fn test_invert() {
|
|||
|
||||
#[test]
|
||||
fn test_from_translation() {
|
||||
let mat = Matrix4::from_translation(&Vector3::new(1.0f64, 2.0f64, 3.0f64));
|
||||
let mat = Matrix4::from_translation(Vector3::new(1.0f64, 2.0f64, 3.0f64));
|
||||
let vertex = Vector4::new(0.0f64, 0.0f64, 0.0f64, 1.0f64);
|
||||
let res = mat.mul_v(&vertex);
|
||||
let res = mat.mul_v(vertex);
|
||||
assert_eq!(res, Vector4::new(1., 2., 3., 1.));
|
||||
}
|
||||
|
||||
|
@ -398,13 +398,13 @@ fn test_predicates() {
|
|||
fn test_from_angle() {
|
||||
// Rotate the vector (1, 0) by π/2 radians to the vector (0, 1)
|
||||
let rot1 = Matrix2::from_angle(rad(0.5f64 * f64::consts::PI));
|
||||
assert!(rot1.mul_v(&Vector2::unit_x()).approx_eq(&Vector2::unit_y()));
|
||||
assert!(rot1.mul_v(Vector2::unit_x()).approx_eq(&Vector2::unit_y()));
|
||||
|
||||
// Rotate the vector (-1, 0) by -π/2 radians to the vector (0, 1)
|
||||
let rot2 = -rot1;
|
||||
assert!(rot2.mul_v(&-Vector2::unit_x()).approx_eq(&Vector2::unit_y()));
|
||||
assert!(rot2.mul_v(-Vector2::unit_x()).approx_eq(&Vector2::unit_y()));
|
||||
|
||||
// Rotate the vector (1, 1) by π radians to the vector (-1, -1)
|
||||
let rot3: Matrix2<f64> = Matrix2::from_angle(rad(f64::consts::PI));
|
||||
assert!(rot3.mul_v(&Vector2::new(1.0, 1.0)).approx_eq(&Vector2::new(-1.0, -1.0)));
|
||||
assert!(rot3.mul_v(Vector2::new(1.0, 1.0)).approx_eq(&Vector2::new(-1.0, -1.0)));
|
||||
}
|
||||
|
|
|
@ -22,5 +22,5 @@ use cgmath::ApproxEq;
|
|||
#[test]
|
||||
fn test_homogeneous() {
|
||||
let p = Point3::new(1.0f64, 2.0f64, 3.0f64);
|
||||
assert!(p.approx_eq(&Point3::from_homogeneous(&p.to_homogeneous())));
|
||||
assert!(p.approx_eq(&Point3::from_homogeneous(p.to_homogeneous())));
|
||||
}
|
||||
|
|
|
@ -28,9 +28,9 @@ fn test_ortho_scale() {
|
|||
let vec_far: Vector4<f32> = Vector4::new(1., 1., 1., 1.);
|
||||
|
||||
let o: Matrix4<f32> = ortho(-1., 1., -1., 1., -1., 1.);
|
||||
let near = o.mul_v(&vec_near);
|
||||
let orig = o.mul_v(&vec_orig);
|
||||
let far = o.mul_v(&vec_far);
|
||||
let near = o.mul_v(vec_near);
|
||||
let orig = o.mul_v(vec_orig);
|
||||
let far = o.mul_v(vec_far);
|
||||
|
||||
assert_eq!(near, Vector4::new(-1f32, -1., 1., 1.));
|
||||
assert_eq!(orig, Vector4::new(0f32, 0., 0., 1.));
|
||||
|
@ -38,9 +38,9 @@ fn test_ortho_scale() {
|
|||
|
||||
|
||||
let o: Matrix4<f32> = ortho(-2., 2., -2., 2., -2., 2.);
|
||||
let near = o.mul_v(&vec_near);
|
||||
let orig = o.mul_v(&vec_orig);
|
||||
let far = o.mul_v(&vec_far);
|
||||
let near = o.mul_v(vec_near);
|
||||
let orig = o.mul_v(vec_orig);
|
||||
let far = o.mul_v(vec_far);
|
||||
|
||||
assert_eq!(near, Vector4::new(-0.5f32, -0.5, 0.5, 1.));
|
||||
assert_eq!(orig, Vector4::new(0f32, 0., 0., 1.));
|
||||
|
@ -56,14 +56,14 @@ fn test_ortho_translate() {
|
|||
let vec_orig: Vector4<f32> = Vector4::new(0., 0., 0., 1.);
|
||||
|
||||
let o: Matrix4<f32> = ortho(-1., 1., -1., 1., -1., 1.);
|
||||
let orig = o.mul_v(&vec_orig);
|
||||
let orig = o.mul_v(vec_orig);
|
||||
assert_eq!(orig, Vector4::new(0., 0., 0., 1.));
|
||||
|
||||
let o: Matrix4<f32> = ortho(0., 2., 0., 2., 0., 2.);
|
||||
let orig = o.mul_v(&vec_orig);
|
||||
let orig = o.mul_v(vec_orig);
|
||||
assert_eq!(orig, Vector4::new(-1., -1., -1., 1.));
|
||||
|
||||
let o: Matrix4<f32> = ortho(-2., 0., -2., 0., -2., 0.);
|
||||
let orig = o.mul_v(&vec_orig);
|
||||
let orig = o.mul_v(vec_orig);
|
||||
assert_eq!(orig, Vector4::new(1., 1., 1., 1.));
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ mod rotation {
|
|||
|
||||
pub fn a3<R: Rotation3<f64>>() -> R {
|
||||
let axis = Vector3::new(1.0, 1.0, 0.0).normalize();
|
||||
Rotation3::from_axis_angle(&axis, deg(30.0).into())
|
||||
Rotation3::from_axis_angle(axis, deg(30.0).into())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,8 +27,8 @@ fn test_invert() {
|
|||
disp: Vector3::new(6.0f64,-7.0,8.0)
|
||||
};
|
||||
let ti = t.invert().expect("Expected successful inversion");
|
||||
let vt = t.transform_vector( &v );
|
||||
assert!(v.approx_eq( &ti.transform_vector( &vt ) ));
|
||||
let vt = t.transform_vector(v);
|
||||
assert!(v.approx_eq(&ti.transform_vector(vt)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -36,10 +36,10 @@ fn test_look_at() {
|
|||
let eye = Point3::new(0.0f64, 0.0, -5.0);
|
||||
let center = Point3::new(0.0f64, 0.0, 0.0);
|
||||
let up = Vector3::new(1.0f64, 0.0, 0.0);
|
||||
let t: Decomposed<Vector3<f64>, Quaternion<f64>> = Transform::look_at(&eye, ¢er, &up);
|
||||
let t: Decomposed<Vector3<f64>, Quaternion<f64>> = Transform::look_at(eye, center, up);
|
||||
let point = Point3::new(1.0f64, 0.0, 0.0);
|
||||
let view_point = Point3::new(0.0f64, 1.0, 5.0);
|
||||
assert!( t.transform_point(&point).approx_eq(&view_point) );
|
||||
assert!(t.transform_point(point).approx_eq(&view_point));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -35,9 +35,9 @@ fn test_from_value() {
|
|||
|
||||
#[test]
|
||||
fn test_dot() {
|
||||
assert_eq!(Vector2::new(1isize, 2isize).dot(&Vector2::new(3isize, 4isize)), 11isize);
|
||||
assert_eq!(Vector3::new(1isize, 2isize, 3isize).dot(&Vector3::new(4isize, 5isize, 6isize)), 32isize);
|
||||
assert_eq!(Vector4::new(1isize, 2isize, 3isize, 4isize).dot(&Vector4::new(5isize, 6isize, 7isize, 8isize)), 70isize);
|
||||
assert_eq!(Vector2::new(1isize, 2isize).dot(Vector2::new(3isize, 4isize)), 11isize);
|
||||
assert_eq!(Vector3::new(1isize, 2isize, 3isize).dot(Vector3::new(4isize, 5isize, 6isize)), 32isize);
|
||||
assert_eq!(Vector4::new(1isize, 2isize, 3isize, 4isize).dot(Vector4::new(5isize, 6isize, 7isize, 8isize)), 70isize);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -89,18 +89,18 @@ fn test_cross() {
|
|||
let a = Vector3::new(1isize, 2isize, 3isize);
|
||||
let b = Vector3::new(4isize, 5isize, 6isize);
|
||||
let r = Vector3::new(-3isize, 6isize, -3isize);
|
||||
assert_eq!(a.cross(&b), r);
|
||||
assert_eq!(a.cross(b), r);
|
||||
|
||||
let mut a = a;
|
||||
a.cross_self(&b);
|
||||
a.cross_self(b);
|
||||
assert_eq!(a, r);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_perpendicular() {
|
||||
assert!(Vector2::new(1.0f64, 0.0f64).is_perpendicular(&Vector2::new(0.0f64, 1.0f64)));
|
||||
assert!(Vector3::new(0.0f64, 1.0f64, 0.0f64).is_perpendicular(&Vector3::new(0.0f64, 0.0f64, 1.0f64)));
|
||||
assert!(Vector4::new(1.0f64, 0.0f64, 0.0f64, 0.0f64).is_perpendicular(&Vector4::new(0.0f64, 0.0f64, 0.0f64, 1.0f64)));
|
||||
assert!(Vector2::new(1.0f64, 0.0f64).is_perpendicular(Vector2::new(0.0f64, 1.0f64)));
|
||||
assert!(Vector3::new(0.0f64, 1.0f64, 0.0f64).is_perpendicular(Vector3::new(0.0f64, 0.0f64, 1.0f64)));
|
||||
assert!(Vector4::new(1.0f64, 0.0f64, 0.0f64, 0.0f64).is_perpendicular(Vector4::new(0.0f64, 0.0f64, 0.0f64, 1.0f64)));
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -146,17 +146,17 @@ mod test_length {
|
|||
|
||||
#[test]
|
||||
fn test_angle() {
|
||||
assert!(Vector2::new(1.0f64, 0.0f64).angle(&Vector2::new(0.0f64, 1.0f64)).approx_eq( &rad(f64::consts::FRAC_PI_2) ));
|
||||
assert!(Vector2::new(10.0f64, 0.0f64).angle(&Vector2::new(0.0f64, 5.0f64)).approx_eq( &rad(f64::consts::FRAC_PI_2) ));
|
||||
assert!(Vector2::new(-1.0f64, 0.0f64).angle(&Vector2::new(0.0f64, 1.0f64)).approx_eq( &-rad(f64::consts::FRAC_PI_2) ));
|
||||
assert!(Vector2::new(1.0f64, 0.0f64).angle(Vector2::new(0.0f64, 1.0f64)).approx_eq( &rad(f64::consts::FRAC_PI_2) ));
|
||||
assert!(Vector2::new(10.0f64, 0.0f64).angle(Vector2::new(0.0f64, 5.0f64)).approx_eq( &rad(f64::consts::FRAC_PI_2) ));
|
||||
assert!(Vector2::new(-1.0f64, 0.0f64).angle(Vector2::new(0.0f64, 1.0f64)).approx_eq( &-rad(f64::consts::FRAC_PI_2) ));
|
||||
|
||||
assert!(Vector3::new(1.0f64, 0.0f64, 1.0f64).angle(&Vector3::new(1.0f64, 1.0f64, 0.0f64)).approx_eq( &rad(f64::consts::FRAC_PI_3) ));
|
||||
assert!(Vector3::new(10.0f64, 0.0f64, 10.0f64).angle(&Vector3::new(5.0f64, 5.0f64, 0.0f64)).approx_eq( &rad(f64::consts::FRAC_PI_3) ));
|
||||
assert!(Vector3::new(-1.0f64, 0.0f64, -1.0f64).angle(&Vector3::new(1.0f64, -1.0f64, 0.0f64)).approx_eq( &rad(2.0f64 * f64::consts::FRAC_PI_3) ));
|
||||
assert!(Vector3::new(1.0f64, 0.0f64, 1.0f64).angle(Vector3::new(1.0f64, 1.0f64, 0.0f64)).approx_eq( &rad(f64::consts::FRAC_PI_3) ));
|
||||
assert!(Vector3::new(10.0f64, 0.0f64, 10.0f64).angle(Vector3::new(5.0f64, 5.0f64, 0.0f64)).approx_eq( &rad(f64::consts::FRAC_PI_3) ));
|
||||
assert!(Vector3::new(-1.0f64, 0.0f64, -1.0f64).angle(Vector3::new(1.0f64, -1.0f64, 0.0f64)).approx_eq( &rad(2.0f64 * f64::consts::FRAC_PI_3) ));
|
||||
|
||||
assert!(Vector4::new(1.0f64, 0.0f64, 1.0f64, 0.0f64).angle(&Vector4::new(0.0f64, 1.0f64, 0.0f64, 1.0f64)).approx_eq( &rad(f64::consts::FRAC_PI_2) ));
|
||||
assert!(Vector4::new(10.0f64, 0.0f64, 10.0f64, 0.0f64).angle(&Vector4::new(0.0f64, 5.0f64, 0.0f64, 5.0f64)).approx_eq( &rad(f64::consts::FRAC_PI_2) ));
|
||||
assert!(Vector4::new(-1.0f64, 0.0f64, -1.0f64, 0.0f64).angle(&Vector4::new(0.0f64, 1.0f64, 0.0f64, 1.0f64)).approx_eq( &rad(f64::consts::FRAC_PI_2) ));
|
||||
assert!(Vector4::new(1.0f64, 0.0f64, 1.0f64, 0.0f64).angle(Vector4::new(0.0f64, 1.0f64, 0.0f64, 1.0f64)).approx_eq( &rad(f64::consts::FRAC_PI_2) ));
|
||||
assert!(Vector4::new(10.0f64, 0.0f64, 10.0f64, 0.0f64).angle(Vector4::new(0.0f64, 5.0f64, 0.0f64, 5.0f64)).approx_eq( &rad(f64::consts::FRAC_PI_2) ));
|
||||
assert!(Vector4::new(-1.0f64, 0.0f64, -1.0f64, 0.0f64).angle(Vector4::new(0.0f64, 1.0f64, 0.0f64, 1.0f64)).approx_eq( &rad(f64::consts::FRAC_PI_2) ));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Reference in a new issue