diff --git a/src/rotation.rs b/src/rotation.rs index 993188e..614a5ac 100644 --- a/src/rotation.rs +++ b/src/rotation.rs @@ -22,7 +22,7 @@ use matrix::{Matrix2, Matrix3}; use num::BaseFloat; use point::{Point, Point2, Point3}; use quaternion::Quaternion; -use vector::{Vector, Vector2, Vector3}; +use vector::{EuclideanVector, Vector2, Vector3}; /// A trait for a generic rotation. A rotation is a transformation that /// creates a circular motion, and preserves at least one point in the space. diff --git a/src/vector.rs b/src/vector.rs index 47decd2..b443c32 100644 --- a/src/vector.rs +++ b/src/vector.rs @@ -62,7 +62,8 @@ //! and [cross products](http://en.wikipedia.org/wiki/Cross_product). //! //! ```rust -//! use cgmath::{Vector, Vector2, Vector3, Vector4, dot}; +//! use cgmath::{Vector, EuclideanVector}; +//! use cgmath::{Vector2, Vector3, Vector4}; //! //! // All vectors implement the dot product as a method: //! let a: Vector2 = Vector2::new(3.0, 6.0); @@ -70,7 +71,7 @@ //! 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), cgmath::dot(a, b)); //! //! // Cross products are defined for 3-dimensional vectors: //! let e: Vector3 = Vector3::unit_x(); @@ -121,14 +122,8 @@ pub trait Vector: Copy + Clone where /// The additive identity vector. Adding this vector with another has no effect. #[inline] fn zero() -> Self { Self::from_value(Self::Scalar::zero()) } - - /// Vector dot product - fn dot(self, other: Self) -> Self::Scalar; } -/// Dot product of two vectors. -#[inline] pub fn dot(a: V, b: V) -> V::Scalar { V::dot(a, b) } - /// A 2-dimensional vector. /// /// This type is marked as `#[repr(C, packed)]`. @@ -207,9 +202,10 @@ macro_rules! impl_vector { impl Vector for $VectorN { type Scalar = S; - #[inline] fn from_value(scalar: S) -> $VectorN { $VectorN { $($field: scalar),+ } } - - #[inline] fn dot(self, other: $VectorN) -> S { $VectorN::mul_element_wise(self, other).sum() } + #[inline] + fn from_value(scalar: S) -> $VectorN { + $VectorN { $($field: scalar),+ } + } } impl> Neg for $VectorN { @@ -468,6 +464,9 @@ pub trait EuclideanVector: Vector + Sized where ::Scalar: BaseFloat, Self: ApproxEq::Scalar>, { + /// Vector dot (or inner) product. + fn dot(self, other: Self) -> Self::Scalar; + /// Returns `true` if the vector is perpendicular (at right angles) to the /// other vector. fn is_perpendicular(self, other: Self) -> bool { @@ -519,7 +518,20 @@ pub trait EuclideanVector: Vector + Sized where } } +/// Dot product of two vectors. +#[inline] +pub fn dot(a: V, b: V) -> V::Scalar where + V::Scalar: BaseFloat, +{ + V::dot(a, b) +} + impl EuclideanVector for Vector2 { + #[inline] + fn dot(self, other: Vector2) -> S { + Vector2::mul_element_wise(self, other).sum() + } + #[inline] fn angle(self, other: Vector2) -> Rad { Rad::atan2(Self::perp_dot(self, other), Self::dot(self, other)) @@ -527,6 +539,11 @@ impl EuclideanVector for Vector2 { } impl EuclideanVector for Vector3 { + #[inline] + fn dot(self, other: Vector3) -> S { + Vector3::mul_element_wise(self, other).sum() + } + #[inline] fn angle(self, other: Vector3) -> Rad { Rad::atan2(self.cross(other).magnitude(), Self::dot(self, other)) @@ -534,6 +551,11 @@ impl EuclideanVector for Vector3 { } impl EuclideanVector for Vector4 { + #[inline] + fn dot(self, other: Vector4) -> S { + Vector4::mul_element_wise(self, other).sum() + } + #[inline] fn angle(self, other: Vector4) -> Rad { Rad::acos(Self::dot(self, other) / (self.magnitude() * other.magnitude())) diff --git a/tests/vector.rs b/tests/vector.rs index c8d84f7..d7ed20b 100644 --- a/tests/vector.rs +++ b/tests/vector.rs @@ -122,9 +122,9 @@ fn test_rem() { #[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(1.0, 2.0).dot(Vector2::new(3.0, 4.0)), 11.0); + assert_eq!(Vector3::new(1.0, 2.0, 3.0).dot(Vector3::new(4.0, 5.0, 6.0)), 32.0); + assert_eq!(Vector4::new(1.0, 2.0, 3.0, 4.0).dot(Vector4::new(5.0, 6.0, 7.0, 8.0)), 70.0); } #[test]