From 5c25683cfb6257ab3146bacdfc416b455dc2f19e Mon Sep 17 00:00:00 2001 From: Aaron Jacobs Date: Mon, 28 Jul 2014 23:05:15 -0700 Subject: [PATCH] Adds a tutorial of sorts for working with cgmath's vectors. There are several runnable code examples that should compile when using `make doctest`. Signed-off-by: Aaron Jacobs --- src/vector.rs | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/src/vector.rs b/src/vector.rs index 36f3e4b..25c93da 100644 --- a/src/vector.rs +++ b/src/vector.rs @@ -13,6 +13,92 @@ // See the License for the specific language governing permissions and // limitations under the License. +//! Types and traits for two, three, and four-dimensional vectors. +//! +//! ## Working with Vectors +//! +//! Vectors can be created in several different ways. There is, of course, the +//! traditional `new()` method, but unit vectors, zero vectors, and an identity +//! vector are also provided: +//! +//! ```rust +//! use cgmath::vector::{Vector2, Vector3, Vector4}; +//! +//! assert_eq!(Vector2::new(1.0f64, 0.0f64), Vector2::unit_x()); +//! assert_eq!(Vector3::new(0.0f64, 0.0f64, 0.0f64), Vector3::zero()); +//! assert_eq!(Vector4::from_value(1.0f64), Vector4::ident()); +//! ``` +//! +//! Vectors can be manipulated with typical mathematical operations (addition, +//! subtraction, element-wise multiplication, element-wise division, negation) +//! using the built-in operators. The additive and multiplicative inverses +//! (zero and one) provided by the standard library's `Zero` and `One` are also +//! available: +//! +//! ```rust +//! use std::num::{Zero, One}; +//! use cgmath::vector::{Vector2, Vector3, Vector4}; +//! +//! let a: Vector2 = Vector2::new(3.0, 4.0); +//! let b: Vector2 = Vector2::new(-3.0, -4.0); +//! +//! assert_eq!(a + b, Zero::zero()); +//! assert_eq!(-(a * b), Vector2::new(9.0f64, 16.0f64)); +//! assert_eq!(a / One::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: +//! // let c = a + Vector3::new(1.0, 0.0, 2.0); +//! +//! // Instead, we need to convert the Vector2 to a Vector3 by "extending" it +//! // with the value for the last coordinate: +//! let c: Vector3 = 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 = c + Vector4::unit_x().truncate(); +//! +//! assert_eq!(d, Vector3::new(5.0f64, 4.0f64, 2.0f64)); +//! ``` +//! +//! Vectors also provide methods for typical operations such as +//! [scalar multiplication](http://en.wikipedia.org/wiki/Scalar_multiplication), +//! [dot products](http://en.wikipedia.org/wiki/Dot_product), +//! and [cross products](http://en.wikipedia.org/wiki/Cross_product). +//! +//! ```rust +//! use std::num::Zero; +//! use cgmath::vector::{Vector, Vector2, Vector3, Vector4, dot}; +//! +//! // All vectors implement the dot product as a method: +//! let a: Vector2 = Vector2::new(3.0, 6.0); +//! let b: Vector2 = Vector2::new(-2.0, 1.0); +//! assert_eq!(a.dot(&b), Zero::zero()); +//! +//! // But there is also a top-level function: +//! assert_eq!(a.dot(&b), dot(a, b)); +//! +//! // Scalar multiplication can return a new object, or be done in place +//! // to avoid an allocation: +//! let mut c: Vector4 = Vector4::from_value(3.0); +//! let d: Vector4 = c.mul_s(2.0); +//! c.mul_self_s(2.0); +//! assert_eq!(c, d); +//! +//! // Cross products are defined for 3-dimensional vectors: +//! let e: Vector3 = Vector3::unit_x(); +//! let f: Vector3 = Vector3::unit_y(); +//! assert_eq!(e.cross(&f), Vector3::unit_z()); +//! ``` +//! +//! Several other useful methods are provided as well. Vector fields can be +//! accessed using array syntax (i.e. `vector[0] == vector.x`), or by using +//! the methods provided by the [`Array1`](../array/trait.Array1.html) trait. +//! This trait also provides a `map()` method for applying arbitrary functions. +//! +//! The [`Vector`](../trait.Vector.html) trait presents the most general +//! features of the vectors, while [`EuclideanVector`] +//! (../array/trait.EuclideanVector.html) is more specific to Euclidean space. + use std::fmt; use std::mem; use std::num::{Zero, zero, One, one};