- right-handed coordinate system: X, Y, Z -- right, forward, up
- prefer `AngelWrappedSigned` as it can be computed with a single `atan2` call
- in generic code, prefer to use trait methods like `norm` which don't require the
`num_traits::real::Real` trait because it is only implemented for floating point
numbers
- in generic code, `self_dot()` as a means of computing squared magnitude has a more
generic trait bound (`Ring`) than `norm_squared` (`Field`)
- when defining methods, prefer to define trait bounds as locally as possible rather
than for the entire impl block, however for types that have a scalar bound it may be
convenient to give a number trait bound on the impl block to avoid having to give very
verbose trait bounds that all number types should implement (i.e. `Ring` will provide
most commonly required traits: `Copy`, `PartialEq`, `PartialOrd`, `Add`, `Sub`, `Mul`,
etc.):
* `Ring` -- addition/subtraction + multiplication
* `OrderedRing` -- `Ring` with `PartialOrd`, `Rem`, `MinMax`, `SignedExt`
* `Field` -- `Ring` with division and `Powi`
* `OrderedField` -- `Field` plus `OrderedRing` traits
* `Real` -- `OrderedField` with `Exp`, `Powf`, `Sqrt`, `Trig`
- to access components of a points, prefer to use method `.x()` to acessing the internal
vector directly with `.0.x`; this is only aesthetic as the number of characters is the
same; however since `.x()` returns a copy of the component, `.0.x` is required to
mutate the component