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 <atheriel@gmail.com>
This commit is contained in:
Aaron Jacobs 2014-07-28 23:05:15 -07:00
parent fddb3a7903
commit 5c25683cfb

View file

@ -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<f64> = Vector2::new(3.0, 4.0);
//! let b: Vector2<f64> = 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<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();
//!
//! 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<f64> = Vector2::new(3.0, 6.0);
//! let b: Vector2<f64> = 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<f64> = Vector4::from_value(3.0);
//! let d: Vector4<f64> = 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<f64> = Vector3::unit_x();
//! let f: Vector3<f64> = 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};