Module truster::tuple[][src]

Expand description

A 3D tuple which can represent points and vectors. The coordinates are floating point numbers. Support for generics may be added in the future.

Examples

You can create points and vectors with Tuple::point and Tuple::vector respectively:

let p = Tuple::point(1.0, 4.2, -3.7);
assert!(p.is_point());
assert!(!p.is_vector());
let v = Tuple::vector(1.0, 4.2, -3.7);
assert!(!v.is_point());
assert!(v.is_vector());

Points and vectors are not the same:

let p = Tuple::point(1.0, 4.2, -3.7);
let v = Tuple::vector(1.0, 4.2, -3.7);
assert_ne!(p, v);

Points represent a position in 3D space. Vectors represent a displacement or movement.

Individual coordinates can be accessed with their respective methods:

let p = Tuple::point(1.0, 4.2, -3.7);
assert_eq!(p.x(), 1.0);
assert_eq!(p.y(), 4.2);
assert_eq!(p.z(), -3.7);

… or with indexing:

let p = Tuple::point(1.0, 4.2, -3.7);
assert_eq!(p[0], 1.0);
assert_eq!(p[1], 4.2);
assert_eq!(p[2], -3.7);

Arithmetic

Tuples support all common arithmetic operations. However, be careful, as for example points can’t be added to points. You have to add vectors to points to get another point. This library won’t check this for you, because of simplicity and for performance reasons. You should make sure you handle everything correctly to avoid bugs. All operations which support operator overloading support mutable assignment. The available operations are:

  • Addition (p+v -> v, v+p -> p, v+v -> v)
let mut p = Tuple::point(3.0, -2.0, 5.0);
let v = Tuple::vector(-2.0, 3.0, 1.0);
assert_eq!(p + v, Tuple::point(1.0, 1.0, 6.0));
p += v;
assert_eq!(p, Tuple::point(1.0, 1.0, 6.0));
  • Subtraction (p-p -> v, p-v -> p, v-v -> v)
let p1 = Tuple::point(3.0, 2.0, 1.0);
let p2 = Tuple::point(5.0, 6.0, 7.0);
assert_eq!(p1 - p2, Tuple::vector(-2.0, -4.0, -6.0));

let v1 = Tuple::vector(5.0, 6.0, 7.0);
assert_eq!(p1 - v1, Tuple::point(-2.0, -4.0, -6.0));

let v2 = Tuple::vector(3.0, 2.0, 1.0);
assert_eq!(v2 - v1, Tuple::vector(-2.0, -4.0, -6.0));
  • Negation (-v -> v)
let v = Tuple::vector(1.0, -2.0, 3.0);
assert_eq!(-v, Tuple::vector(-1.0, 2.0, -3.0));
  • Scalar multiplication (v*f -> v)
let v = Tuple::vector(1.0, -2.0, 3.0);
assert_eq!(v * 3.5, Tuple::vector(3.5, -7.0, 10.5));
assert_eq!(v * 0.5, Tuple::vector(0.5, -1.0, 1.5));
  • Scalar division (v/f -> v)
let v = Tuple::vector(1.0, -2.0, 3.0);
assert_eq!(v / 2.0, Tuple::vector(0.5, -1.0, 1.5));
  • Dot product (v⋅v -> f)
let v1 = Tuple::vector(1.0, 2.0, 3.0);
let v2 = Tuple::vector(2.0, 3.0, 4.0);
assert_eq!(v1.dot(v2), 20.0);
  • Cross product (v×v -> v)
let v1 = Tuple::vector(1.0, 2.0, 3.0);
let v2 = Tuple::vector(2.0, 3.0, 4.0);
assert_eq!(v1.cross(v2), Tuple::vector(-1.0, 2.0, -1.0));
assert_eq!(v2.cross(v1), Tuple::vector(1.0, -2.0, 1.0));
  • Reflection (v.reflect(v) -> v)
let v = Tuple::vector(1.0, -1.0, 0.0);
let n = Tuple::vector(0.0, 1.0, 0.0);
let r = v.reflect(n);
assert_eq!(r, Tuple::vector(1.0, 1.0, 0.0));

Normalization

When working with vectors (so not points), you can take the norm of vectors and normalize them. You can also ask the square of the norm. This is faster than the norm itself, because no square root has to be taken.


let sqrt14 = (14.0 as f64).sqrt();
let mut v = Tuple::vector(1.0, 2.0, 3.0);
assert_eq!(v.norm_squared(), 14.0);
assert_eq!(v.norm(), sqrt14);
assert_eq!(v.normalized(), Tuple::vector(1.0 / sqrt14, 2.0 / sqrt14, 3.0 / sqrt14));

v.normalize();
assert_eq!(v, Tuple::vector(1.0 / sqrt14, 2.0 / sqrt14, 3.0 / sqrt14));

Structs

Tuple represents a 3D tuple. See the module’s documentation for more information.