2013-09-26 23:18:14 +08:00
|
|
|
//! Traits of operations having a well-known or explicit geometric meaning.
|
|
|
|
|
|
|
|
|
2013-09-22 16:58:21 +08:00
|
|
|
use traits::structure::Mat;
|
|
|
|
|
|
|
|
/// Trait of object which represent a translation, and to wich new translation
|
|
|
|
/// can be appended.
|
|
|
|
pub trait Translation<V> {
|
|
|
|
// FIXME: add a "from translation: translantion(V) -> Self ?
|
|
|
|
/// Gets the translation associated with this object.
|
|
|
|
fn translation(&self) -> V;
|
|
|
|
|
|
|
|
/// Gets the inverse translation associated with this object.
|
|
|
|
fn inv_translation(&self) -> V;
|
|
|
|
|
2013-10-14 16:22:32 +08:00
|
|
|
/// Appends a translation to this object.
|
|
|
|
fn append_translation(&mut self, &V);
|
2013-09-22 16:58:21 +08:00
|
|
|
|
2013-10-14 16:22:32 +08:00
|
|
|
/// Appends the translation `amount` to a copy of `t`.
|
|
|
|
fn append_translation_cpy(t: &Self, amount: &V) -> Self;
|
|
|
|
|
|
|
|
/// Prepends a translation to this object.
|
|
|
|
fn prepend_translation(&mut self, &V);
|
|
|
|
|
|
|
|
/// Prepends the translation `amount` to a copy of `t`.
|
|
|
|
fn prepend_translation_cpy(t: &Self, amount: &V) -> Self;
|
2013-09-22 16:58:21 +08:00
|
|
|
|
|
|
|
/// Sets the translation.
|
|
|
|
fn set_translation(&mut self, V);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Trait of objects able to rotate other objects. This is typically implemented by matrices which
|
|
|
|
/// rotate vectors.
|
|
|
|
pub trait Translate<V> {
|
|
|
|
/// Apply a translation to an object.
|
2013-10-14 16:22:32 +08:00
|
|
|
fn translate(&self, &V) -> V;
|
|
|
|
|
2013-09-22 16:58:21 +08:00
|
|
|
/// Apply an inverse translation to an object.
|
|
|
|
fn inv_translate(&self, &V) -> V;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Trait of object which can represent a rotation, and to which new rotations can be appended. A
|
|
|
|
/// rotation is assumed to be an isometry without translation and without reflexion.
|
|
|
|
pub trait Rotation<V> {
|
|
|
|
/// Gets the rotation associated with `self`.
|
|
|
|
fn rotation(&self) -> V;
|
|
|
|
|
|
|
|
/// Gets the inverse rotation associated with `self`.
|
|
|
|
fn inv_rotation(&self) -> V;
|
|
|
|
|
2013-10-14 16:22:32 +08:00
|
|
|
/// Appends a rotation to this object.
|
|
|
|
fn append_rotation(&mut self, &V);
|
|
|
|
|
|
|
|
/// Appends the rotation `amount` to a copy of `t`.
|
|
|
|
fn append_rotation_cpy(t: &Self, amount: &V) -> Self;
|
|
|
|
|
|
|
|
/// Prepends a rotation to this object.
|
|
|
|
fn prepend_rotation(&mut self, &V);
|
2013-09-22 16:58:21 +08:00
|
|
|
|
2013-10-14 16:22:32 +08:00
|
|
|
/// Prepends the rotation `amount` to a copy of `t`.
|
|
|
|
fn prepend_rotation_cpy(t: &Self, amount: &V) -> Self;
|
2013-09-22 16:58:21 +08:00
|
|
|
|
|
|
|
/// Sets the rotation of `self`.
|
|
|
|
fn set_rotation(&mut self, V);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Trait of objects able to rotate other objects.
|
|
|
|
///
|
|
|
|
/// This is typically implemented by matrices which rotate vectors.
|
|
|
|
pub trait Rotate<V> {
|
|
|
|
/// Applies a rotation to `v`.
|
|
|
|
fn rotate(&self, v: &V) -> V;
|
2013-10-14 16:22:32 +08:00
|
|
|
|
2013-09-22 16:58:21 +08:00
|
|
|
/// Applies an inverse rotation to `v`.
|
|
|
|
fn inv_rotate(&self, v: &V) -> V;
|
|
|
|
}
|
|
|
|
|
2013-10-06 22:54:09 +08:00
|
|
|
/// Various composition of rotation and translation.
|
|
|
|
///
|
|
|
|
/// Utilities to make rotations with regard to a point different than the origin. All those
|
|
|
|
/// operations are the composition of rotations and translations.
|
|
|
|
///
|
|
|
|
/// Those operations are automatically implemented in term of the `Rotation` and `Translation`
|
|
|
|
/// traits.
|
|
|
|
pub trait RotationWithTranslation<LV: Neg<LV>, AV>: Rotation<AV> + Translation<LV> {
|
|
|
|
/// Applies a rotation centered on a specific point.
|
|
|
|
///
|
|
|
|
/// # Arguments
|
2013-10-14 16:22:32 +08:00
|
|
|
/// * `t` - the object to be rotated.
|
2013-10-06 22:54:09 +08:00
|
|
|
/// * `amount` - the rotation to apply.
|
|
|
|
/// * `point` - the center of rotation.
|
|
|
|
#[inline]
|
2013-10-14 16:22:32 +08:00
|
|
|
fn append_rotation_wrt_point_cpy(t: &Self, amount: &AV, center: &LV) -> Self {
|
2014-03-15 19:23:54 +08:00
|
|
|
let mut res = Translation::append_translation_cpy(t, &-*center);
|
2013-10-06 22:54:09 +08:00
|
|
|
|
2013-10-14 16:22:32 +08:00
|
|
|
res.append_rotation(amount);
|
|
|
|
res.append_translation(center);
|
2013-10-06 22:54:09 +08:00
|
|
|
|
|
|
|
res
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Rotates `self` using a specific center of rotation.
|
|
|
|
///
|
|
|
|
/// The rotation is applied in-place.
|
|
|
|
///
|
|
|
|
/// # Arguments
|
|
|
|
/// * `amount` - the rotation to be applied
|
|
|
|
/// * `center` - the new center of rotation
|
|
|
|
#[inline]
|
2013-10-14 16:22:32 +08:00
|
|
|
fn append_rotation_wrt_point(&mut self, amount: &AV, center: &LV) {
|
2014-03-15 19:23:54 +08:00
|
|
|
self.append_translation(&-*center);
|
2013-10-14 16:22:32 +08:00
|
|
|
self.append_rotation(amount);
|
|
|
|
self.append_translation(center);
|
2013-10-06 22:54:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Applies a rotation centered on the translation of `m`.
|
|
|
|
///
|
|
|
|
/// # Arguments
|
2013-10-14 16:22:32 +08:00
|
|
|
/// * `t` - the object to be rotated.
|
2013-10-06 22:54:09 +08:00
|
|
|
/// * `amount` - the rotation to apply.
|
|
|
|
#[inline]
|
2013-10-14 16:22:32 +08:00
|
|
|
fn append_rotation_wrt_center_cpy(t: &Self, amount: &AV) -> Self {
|
|
|
|
RotationWithTranslation::append_rotation_wrt_point_cpy(t, amount, &t.translation())
|
2013-10-06 22:54:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Applies a rotation centered on the translation of `m`.
|
|
|
|
///
|
|
|
|
/// The rotation os applied on-place.
|
|
|
|
///
|
|
|
|
/// # Arguments
|
|
|
|
/// * `amount` - the rotation to apply.
|
|
|
|
#[inline]
|
2013-10-14 16:22:32 +08:00
|
|
|
fn append_rotation_wrt_center(&mut self, amount: &AV) {
|
2013-10-06 22:54:09 +08:00
|
|
|
let center = self.translation();
|
2013-10-14 16:22:32 +08:00
|
|
|
self.append_rotation_wrt_point(amount, ¢er)
|
2013-10-06 22:54:09 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<LV: Neg<LV>, AV, M: Rotation<AV> + Translation<LV>> RotationWithTranslation<LV, AV> for M {
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Trait of transformation having a rotation extractable as a rotation matrix. This can typically
|
|
|
|
/// be implemented by quaternions to convert them to a rotation matrix.
|
|
|
|
pub trait RotationMatrix<LV, AV, M: Mat<LV, LV> + Rotation<AV>> : Rotation<AV> {
|
|
|
|
/// Gets the rotation matrix represented by `self`.
|
|
|
|
fn to_rot_mat(&self) -> M;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Composition of a rotation and an absolute value.
|
|
|
|
///
|
|
|
|
/// The operation is accessible using the `RotationMatrix`, `Absolute`, and `RMul` traits, but
|
|
|
|
/// doing so is not easy in generic code as it can be a cause of type over-parametrization.
|
|
|
|
pub trait AbsoluteRotate<V> {
|
|
|
|
/// This is the same as:
|
|
|
|
///
|
2014-02-18 19:13:40 +08:00
|
|
|
/// ```.ignore
|
2013-10-06 22:54:09 +08:00
|
|
|
/// self.rotation_matrix().absolute().rmul(v)
|
2014-02-18 19:13:40 +08:00
|
|
|
/// ```
|
2013-10-06 22:54:09 +08:00
|
|
|
fn absolute_rotate(&self, v: &V) -> V;
|
|
|
|
}
|
|
|
|
|
2013-09-22 16:58:21 +08:00
|
|
|
/// Trait of object which represent a transformation, and to which new transformations can
|
|
|
|
/// be appended.
|
|
|
|
///
|
|
|
|
/// A transformation is assumed to be an isometry without reflexion.
|
|
|
|
pub trait Transformation<M> {
|
|
|
|
/// Gets the transformation of `self`.
|
|
|
|
fn transformation(&self) -> M;
|
|
|
|
|
|
|
|
/// Gets the inverse transformation of `self`.
|
|
|
|
fn inv_transformation(&self) -> M;
|
|
|
|
|
2013-10-14 16:22:32 +08:00
|
|
|
/// Appends a transformation to this object.
|
|
|
|
fn append_transformation(&mut self, &M);
|
|
|
|
|
|
|
|
/// Appends the transformation `amount` to a copy of `t`.
|
|
|
|
fn append_transformation_cpy(t: &Self, amount: &M) -> Self;
|
2013-09-22 16:58:21 +08:00
|
|
|
|
2013-10-14 16:22:32 +08:00
|
|
|
/// Prepends a transformation to this object.
|
|
|
|
fn prepend_transformation(&mut self, &M);
|
|
|
|
|
|
|
|
/// Prepends the transformation `amount` to a copy of `t`.
|
|
|
|
fn prepend_transformation_cpy(t: &Self, amount: &M) -> Self;
|
2013-09-22 16:58:21 +08:00
|
|
|
|
|
|
|
/// Sets the transformation of `self`.
|
|
|
|
fn set_transformation(&mut self, M);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Trait of objects able to transform other objects.
|
|
|
|
///
|
|
|
|
/// This is typically implemented by matrices which transform vectors.
|
|
|
|
pub trait Transform<V> {
|
|
|
|
/// Applies a transformation to `v`.
|
|
|
|
fn transform(&self, &V) -> V;
|
2013-10-14 16:22:32 +08:00
|
|
|
|
2013-09-22 16:58:21 +08:00
|
|
|
/// Applies an inverse transformation to `v`.
|
|
|
|
fn inv_transform(&self, &V) -> V;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Traits of objects having a dot product.
|
|
|
|
pub trait Dot<N> {
|
|
|
|
/// Computes the dot (inner) product of two vectors.
|
|
|
|
#[inline]
|
2013-10-17 03:44:33 +08:00
|
|
|
fn dot(&Self, &Self) -> N;
|
2013-09-22 16:58:21 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Short-cut to compute the projection of a point on a vector, but without
|
|
|
|
* computing intermediate vectors.
|
2013-09-26 23:18:14 +08:00
|
|
|
* The following equation must be verified:
|
2013-09-22 16:58:21 +08:00
|
|
|
*
|
2014-02-18 19:13:40 +08:00
|
|
|
* ```.ignore
|
2013-09-26 23:18:14 +08:00
|
|
|
* a.sub_dot(b, c) == (a - b).dot(c)
|
2014-02-18 19:13:40 +08:00
|
|
|
* ```
|
2013-09-22 16:58:21 +08:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
#[inline]
|
2013-10-17 03:44:33 +08:00
|
|
|
fn sub_dot(a: &Self, b: &Self, c: &Self) -> N;
|
2013-09-22 16:58:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Traits of objects having an euclidian norm.
|
2014-02-18 19:13:40 +08:00
|
|
|
pub trait Norm<N: Float> {
|
2013-09-22 16:58:21 +08:00
|
|
|
/// Computes the norm of `self`.
|
|
|
|
#[inline]
|
2013-10-17 03:44:33 +08:00
|
|
|
fn norm(v: &Self) -> N {
|
|
|
|
Norm::sqnorm(v).sqrt()
|
2013-09-22 16:58:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Computes the squared norm of `self`.
|
|
|
|
///
|
|
|
|
/// This is usually faster than computing the norm itself.
|
|
|
|
#[inline]
|
2013-10-17 03:44:33 +08:00
|
|
|
fn sqnorm(&Self) -> N;
|
2013-09-22 16:58:21 +08:00
|
|
|
|
2013-10-14 16:22:32 +08:00
|
|
|
/// Gets the normalized version of a copy of `v`.
|
2013-09-22 16:58:21 +08:00
|
|
|
#[inline]
|
2013-10-14 16:22:32 +08:00
|
|
|
fn normalize_cpy(v: &Self) -> Self;
|
2013-09-22 16:58:21 +08:00
|
|
|
|
2013-10-14 16:22:32 +08:00
|
|
|
/// Normalizes `self`.
|
2013-09-22 16:58:21 +08:00
|
|
|
#[inline]
|
|
|
|
fn normalize(&mut self) -> N;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Trait of elements having a cross product.
|
|
|
|
*/
|
|
|
|
pub trait Cross<V> {
|
|
|
|
/// Computes the cross product between two elements (usually vectors).
|
2013-10-17 03:44:33 +08:00
|
|
|
fn cross(&Self, other: &Self) -> V;
|
2013-09-22 16:58:21 +08:00
|
|
|
}
|
|
|
|
|
2013-10-06 22:54:09 +08:00
|
|
|
/**
|
|
|
|
* Trait of elements having a cross product operation which can be expressed as a matrix.
|
|
|
|
*/
|
|
|
|
pub trait CrossMatrix<M> {
|
|
|
|
/// The matrix associated to any cross product with this vector. I.e. `v.cross(anything)` =
|
|
|
|
/// `v.cross_matrix().rmul(anything)`.
|
2013-10-17 03:44:33 +08:00
|
|
|
fn cross_matrix(&Self) -> M;
|
2013-10-06 22:54:09 +08:00
|
|
|
}
|
|
|
|
|
2013-09-22 16:58:21 +08:00
|
|
|
/// Traits of objects which can be put in homogeneous coordinates form.
|
|
|
|
pub trait ToHomogeneous<U> {
|
|
|
|
/// Gets the homogeneous coordinates form of this object.
|
2013-10-17 03:44:33 +08:00
|
|
|
fn to_homogeneous(&Self) -> U;
|
2013-09-22 16:58:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Traits of objects which can be build from an homogeneous coordinate form.
|
|
|
|
pub trait FromHomogeneous<U> {
|
|
|
|
/// Builds an object from its homogeneous coordinate form.
|
|
|
|
///
|
|
|
|
/// Note that this this is not required that `from` is the inverse of `to_homogeneous`.
|
|
|
|
/// Typically, `from` will remove some informations unrecoverable by `to_homogeneous`.
|
|
|
|
fn from(&U) -> Self;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Trait of vectors able to sample a unit sphere.
|
|
|
|
///
|
|
|
|
/// The number of sample must be sufficient to approximate a sphere using a support mapping
|
|
|
|
/// function.
|
|
|
|
pub trait UniformSphereSample {
|
|
|
|
/// Iterate through the samples.
|
2013-11-27 18:16:16 +08:00
|
|
|
fn sample(|Self| -> ());
|
2013-09-22 16:58:21 +08:00
|
|
|
}
|