forked from M-Labs/nalgebra
Fix some clippy warning.
The following lints were disabled: * wrong_self_convention * needless_range_loop * reverse_range_loop * len_without_is_empty * explicit_iter_loop * many_single_char_names * similar_names * too_many_arguments * float_cmp * new_without_default
This commit is contained in:
parent
6a495013d3
commit
7b4a57c224
147
src/lib.rs
147
src/lib.rs
@ -173,7 +173,7 @@ mod macros;
|
|||||||
// mod chol;
|
// mod chol;
|
||||||
|
|
||||||
/// Change the input value to ensure it is on the range `[min, max]`.
|
/// Change the input value to ensure it is on the range `[min, max]`.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn clamp<T: PartialOrd>(val: T, min: T, max: T) -> T {
|
pub fn clamp<T: PartialOrd>(val: T, min: T, max: T) -> T {
|
||||||
if val > min {
|
if val > min {
|
||||||
if val < max {
|
if val < max {
|
||||||
@ -189,74 +189,74 @@ pub fn clamp<T: PartialOrd>(val: T, min: T, max: T) -> T {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Same as `cmp::max`.
|
/// Same as `cmp::max`.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn max<T: Ord>(a: T, b: T) -> T {
|
pub fn max<T: Ord>(a: T, b: T) -> T {
|
||||||
cmp::max(a, b)
|
cmp::max(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Same as `cmp::min`.
|
/// Same as `cmp::min`.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn min<T: Ord>(a: T, b: T) -> T {
|
pub fn min<T: Ord>(a: T, b: T) -> T {
|
||||||
cmp::min(a, b)
|
cmp::min(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the infimum of `a` and `b`.
|
/// Returns the infimum of `a` and `b`.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn inf<T: PartialOrder>(a: &T, b: &T) -> T {
|
pub fn inf<T: PartialOrder>(a: &T, b: &T) -> T {
|
||||||
PartialOrder::inf(a, b)
|
PartialOrder::inf(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the supremum of `a` and `b`.
|
/// Returns the supremum of `a` and `b`.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn sup<T: PartialOrder>(a: &T, b: &T) -> T {
|
pub fn sup<T: PartialOrder>(a: &T, b: &T) -> T {
|
||||||
PartialOrder::sup(a, b)
|
PartialOrder::sup(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compare `a` and `b` using a partial ordering relation.
|
/// Compare `a` and `b` using a partial ordering relation.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn partial_cmp<T: PartialOrder>(a: &T, b: &T) -> PartialOrdering {
|
pub fn partial_cmp<T: PartialOrder>(a: &T, b: &T) -> PartialOrdering {
|
||||||
PartialOrder::partial_cmp(a, b)
|
PartialOrder::partial_cmp(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` iff `a` and `b` are comparable and `a < b`.
|
/// Returns `true` iff `a` and `b` are comparable and `a < b`.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn partial_lt<T: PartialOrder>(a: &T, b: &T) -> bool {
|
pub fn partial_lt<T: PartialOrder>(a: &T, b: &T) -> bool {
|
||||||
PartialOrder::partial_lt(a, b)
|
PartialOrder::partial_lt(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` iff `a` and `b` are comparable and `a <= b`.
|
/// Returns `true` iff `a` and `b` are comparable and `a <= b`.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn partial_le<T: PartialOrder>(a: &T, b: &T) -> bool {
|
pub fn partial_le<T: PartialOrder>(a: &T, b: &T) -> bool {
|
||||||
PartialOrder::partial_le(a, b)
|
PartialOrder::partial_le(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` iff `a` and `b` are comparable and `a > b`.
|
/// Returns `true` iff `a` and `b` are comparable and `a > b`.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn partial_gt<T: PartialOrder>(a: &T, b: &T) -> bool {
|
pub fn partial_gt<T: PartialOrder>(a: &T, b: &T) -> bool {
|
||||||
PartialOrder::partial_gt(a, b)
|
PartialOrder::partial_gt(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` iff `a` and `b` are comparable and `a >= b`.
|
/// Returns `true` iff `a` and `b` are comparable and `a >= b`.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn partial_ge<T: PartialOrder>(a: &T, b: &T) -> bool {
|
pub fn partial_ge<T: PartialOrder>(a: &T, b: &T) -> bool {
|
||||||
PartialOrder::partial_ge(a, b)
|
PartialOrder::partial_ge(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the minimum of `a` and `b` if they are comparable.
|
/// Return the minimum of `a` and `b` if they are comparable.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn partial_min<'a, T: PartialOrder>(a: &'a T, b: &'a T) -> Option<&'a T> {
|
pub fn partial_min<'a, T: PartialOrder>(a: &'a T, b: &'a T) -> Option<&'a T> {
|
||||||
PartialOrder::partial_min(a, b)
|
PartialOrder::partial_min(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the maximum of `a` and `b` if they are comparable.
|
/// Return the maximum of `a` and `b` if they are comparable.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn partial_max<'a, T: PartialOrder>(a: &'a T, b: &'a T) -> Option<&'a T> {
|
pub fn partial_max<'a, T: PartialOrder>(a: &'a T, b: &'a T) -> Option<&'a T> {
|
||||||
PartialOrder::partial_max(a, b)
|
PartialOrder::partial_max(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clamp `value` between `min` and `max`. Returns `None` if `value` is not comparable to
|
/// Clamp `value` between `min` and `max`. Returns `None` if `value` is not comparable to
|
||||||
/// `min` or `max`.
|
/// `min` or `max`.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn partial_clamp<'a, T: PartialOrder>(value: &'a T, min: &'a T, max: &'a T) -> Option<&'a T> {
|
pub fn partial_clamp<'a, T: PartialOrder>(value: &'a T, min: &'a T, max: &'a T) -> Option<&'a T> {
|
||||||
PartialOrder::partial_clamp(value, min, max)
|
PartialOrder::partial_clamp(value, min, max)
|
||||||
}
|
}
|
||||||
@ -270,7 +270,7 @@ pub fn partial_clamp<'a, T: PartialOrder>(value: &'a T, min: &'a T, max: &'a T)
|
|||||||
/// Create a special identity object.
|
/// Create a special identity object.
|
||||||
///
|
///
|
||||||
/// Same as `Identity::new()`.
|
/// Same as `Identity::new()`.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn identity() -> Identity {
|
pub fn identity() -> Identity {
|
||||||
Identity::new()
|
Identity::new()
|
||||||
}
|
}
|
||||||
@ -278,13 +278,13 @@ pub fn identity() -> Identity {
|
|||||||
/// Create a zero-valued value.
|
/// Create a zero-valued value.
|
||||||
///
|
///
|
||||||
/// This is the same as `std::num::zero()`.
|
/// This is the same as `std::num::zero()`.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn zero<T: Zero>() -> T {
|
pub fn zero<T: Zero>() -> T {
|
||||||
Zero::zero()
|
Zero::zero()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tests is a value is iqual to zero.
|
/// Tests is a value is iqual to zero.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn is_zero<T: Zero>(val: &T) -> bool {
|
pub fn is_zero<T: Zero>(val: &T) -> bool {
|
||||||
val.is_zero()
|
val.is_zero()
|
||||||
}
|
}
|
||||||
@ -292,7 +292,7 @@ pub fn is_zero<T: Zero>(val: &T) -> bool {
|
|||||||
/// Create a one-valued value.
|
/// Create a one-valued value.
|
||||||
///
|
///
|
||||||
/// This is the same as `std::num::one()`.
|
/// This is the same as `std::num::one()`.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn one<T: One>() -> T {
|
pub fn one<T: One>() -> T {
|
||||||
One::one()
|
One::one()
|
||||||
}
|
}
|
||||||
@ -304,7 +304,7 @@ pub fn one<T: One>() -> T {
|
|||||||
//
|
//
|
||||||
|
|
||||||
/// Returns the trivial origin of an affine space.
|
/// Returns the trivial origin of an affine space.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn origin<P: Origin>() -> P {
|
pub fn origin<P: Origin>() -> P {
|
||||||
Origin::origin()
|
Origin::origin()
|
||||||
}
|
}
|
||||||
@ -312,26 +312,23 @@ pub fn origin<P: Origin>() -> P {
|
|||||||
/// Returns the center of two points.
|
/// Returns the center of two points.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn center<N: BaseFloat, P: FloatPoint<N>>(a: &P, b: &P) -> P
|
pub fn center<N: BaseFloat, P: FloatPoint<N>>(a: &P, b: &P) -> P
|
||||||
where <P as PointAsVector>::Vector: Norm<N>
|
where <P as PointAsVector>::Vector: Norm<N> {
|
||||||
{
|
(*a + b.to_vector()) / ::cast(2.0)
|
||||||
let _2 = one::<N>() + one();
|
|
||||||
(*a + b.to_vector()) / _2
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FloatPoint
|
* FloatPoint
|
||||||
*/
|
*/
|
||||||
/// Returns the distance between two points.
|
/// Returns the distance between two points.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn distance<N: BaseFloat, P: FloatPoint<N>>(a: &P, b: &P) -> N where <P as PointAsVector>::Vector: Norm<N> {
|
pub fn distance<N: BaseFloat, P: FloatPoint<N>>(a: &P, b: &P) -> N where <P as PointAsVector>::Vector: Norm<N> {
|
||||||
a.distance(b)
|
a.distance(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the squared distance between two points.
|
/// Returns the squared distance between two points.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn distance_squared<N: BaseFloat, P: FloatPoint<N>>(a: &P, b: &P) -> N
|
pub fn distance_squared<N: BaseFloat, P: FloatPoint<N>>(a: &P, b: &P) -> N
|
||||||
where <P as PointAsVector>::Vector: Norm<N>
|
where <P as PointAsVector>::Vector: Norm<N> {
|
||||||
{
|
|
||||||
a.distance_squared(b)
|
a.distance_squared(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,7 +349,7 @@ pub fn distance_squared<N: BaseFloat, P: FloatPoint<N>>(a: &P, b: &P) -> N
|
|||||||
/// assert!(trans == Vector3::new(1.0, 1.0, 1.0));
|
/// assert!(trans == Vector3::new(1.0, 1.0, 1.0));
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn translation<V, M: Translation<V>>(m: &M) -> V {
|
pub fn translation<V, M: Translation<V>>(m: &M) -> V {
|
||||||
m.translation()
|
m.translation()
|
||||||
}
|
}
|
||||||
@ -370,13 +367,13 @@ pub fn translation<V, M: Translation<V>>(m: &M) -> V {
|
|||||||
/// assert!(itrans == Vector3::new(-1.0, -1.0, -1.0));
|
/// assert!(itrans == Vector3::new(-1.0, -1.0, -1.0));
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn inverse_translation<V, M: Translation<V>>(m: &M) -> V {
|
pub fn inverse_translation<V, M: Translation<V>>(m: &M) -> V {
|
||||||
m.inverse_translation()
|
m.inverse_translation()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Applies the translation `v` to a copy of `m`.
|
/// Applies the translation `v` to a copy of `m`.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn append_translation<V, M: Translation<V>>(m: &M, v: &V) -> M {
|
pub fn append_translation<V, M: Translation<V>>(m: &M, v: &V) -> M {
|
||||||
Translation::append_translation(m, v)
|
Translation::append_translation(m, v)
|
||||||
}
|
}
|
||||||
@ -400,7 +397,7 @@ pub fn append_translation<V, M: Translation<V>>(m: &M, v: &V) -> M {
|
|||||||
/// assert!(tp == Point3::new(3.0, 3.0, 3.0))
|
/// assert!(tp == Point3::new(3.0, 3.0, 3.0))
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn translate<P, M: Translate<P>>(m: &M, p: &P) -> P {
|
pub fn translate<P, M: Translate<P>>(m: &M, p: &P) -> P {
|
||||||
m.translate(p)
|
m.translate(p)
|
||||||
}
|
}
|
||||||
@ -419,7 +416,7 @@ pub fn translate<P, M: Translate<P>>(m: &M, p: &P) -> P {
|
|||||||
///
|
///
|
||||||
/// assert!(na::approx_eq(&tp, &Point3::new(1.0, 1.0, 1.0)))
|
/// assert!(na::approx_eq(&tp, &Point3::new(1.0, 1.0, 1.0)))
|
||||||
/// }
|
/// }
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn inverse_translate<P, M: Translate<P>>(m: &M, p: &P) -> P {
|
pub fn inverse_translate<P, M: Translate<P>>(m: &M, p: &P) -> P {
|
||||||
m.inverse_translate(p)
|
m.inverse_translate(p)
|
||||||
}
|
}
|
||||||
@ -440,7 +437,7 @@ pub fn inverse_translate<P, M: Translate<P>>(m: &M, p: &P) -> P {
|
|||||||
/// assert!(na::approx_eq(&na::rotation(&t), &Vector3::new(1.0, 1.0, 1.0)));
|
/// assert!(na::approx_eq(&na::rotation(&t), &Vector3::new(1.0, 1.0, 1.0)));
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn rotation<V, M: Rotation<V>>(m: &M) -> V {
|
pub fn rotation<V, M: Rotation<V>>(m: &M) -> V {
|
||||||
m.rotation()
|
m.rotation()
|
||||||
}
|
}
|
||||||
@ -458,7 +455,7 @@ pub fn rotation<V, M: Rotation<V>>(m: &M) -> V {
|
|||||||
/// assert!(na::approx_eq(&na::inverse_rotation(&t), &Vector3::new(-1.0, -1.0, -1.0)));
|
/// assert!(na::approx_eq(&na::inverse_rotation(&t), &Vector3::new(-1.0, -1.0, -1.0)));
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn inverse_rotation<V, M: Rotation<V>>(m: &M) -> V {
|
pub fn inverse_rotation<V, M: Rotation<V>>(m: &M) -> V {
|
||||||
m.inverse_rotation()
|
m.inverse_rotation()
|
||||||
}
|
}
|
||||||
@ -478,7 +475,7 @@ pub fn inverse_rotation<V, M: Rotation<V>>(m: &M) -> V {
|
|||||||
/// assert!(na::approx_eq(&na::rotation(&rt), &Vector3::new(1.0, 1.0, 1.0)))
|
/// assert!(na::approx_eq(&na::rotation(&rt), &Vector3::new(1.0, 1.0, 1.0)))
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn append_rotation<V, M: Rotation<V>>(m: &M, v: &V) -> M {
|
pub fn append_rotation<V, M: Rotation<V>>(m: &M, v: &V) -> M {
|
||||||
Rotation::append_rotation(m, v)
|
Rotation::append_rotation(m, v)
|
||||||
}
|
}
|
||||||
@ -498,7 +495,7 @@ pub fn append_rotation<V, M: Rotation<V>>(m: &M, v: &V) -> M {
|
|||||||
/// assert!(na::approx_eq(&na::rotation(&rt), &Vector3::new(1.0, 1.0, 1.0)))
|
/// assert!(na::approx_eq(&na::rotation(&rt), &Vector3::new(1.0, 1.0, 1.0)))
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn prepend_rotation<V, M: Rotation<V>>(m: &M, v: &V) -> M {
|
pub fn prepend_rotation<V, M: Rotation<V>>(m: &M, v: &V) -> M {
|
||||||
Rotation::prepend_rotation(m, v)
|
Rotation::prepend_rotation(m, v)
|
||||||
}
|
}
|
||||||
@ -522,7 +519,7 @@ pub fn prepend_rotation<V, M: Rotation<V>>(m: &M, v: &V) -> M {
|
|||||||
/// assert!(na::approx_eq(&tv, &Vector3::new(0.0, 1.0, 0.0)))
|
/// assert!(na::approx_eq(&tv, &Vector3::new(0.0, 1.0, 0.0)))
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn rotate<V, M: Rotate<V>>(m: &M, v: &V) -> V {
|
pub fn rotate<V, M: Rotate<V>>(m: &M, v: &V) -> V {
|
||||||
m.rotate(v)
|
m.rotate(v)
|
||||||
}
|
}
|
||||||
@ -543,7 +540,7 @@ pub fn rotate<V, M: Rotate<V>>(m: &M, v: &V) -> V {
|
|||||||
/// assert!(na::approx_eq(&tv, &Vector3::new(0.0, -1.0, 0.0)))
|
/// assert!(na::approx_eq(&tv, &Vector3::new(0.0, -1.0, 0.0)))
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn inverse_rotate<V, M: Rotate<V>>(m: &M, v: &V) -> V {
|
pub fn inverse_rotate<V, M: Rotate<V>>(m: &M, v: &V) -> V {
|
||||||
m.inverse_rotate(v)
|
m.inverse_rotate(v)
|
||||||
}
|
}
|
||||||
@ -553,7 +550,7 @@ pub fn inverse_rotate<V, M: Rotate<V>>(m: &M, v: &V) -> V {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/// Rotates a copy of `m` by `amount` using `center` as the pivot point.
|
/// Rotates a copy of `m` by `amount` using `center` as the pivot point.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn append_rotation_wrt_point<LV: Neg<Output = LV> + Copy,
|
pub fn append_rotation_wrt_point<LV: Neg<Output = LV> + Copy,
|
||||||
AV,
|
AV,
|
||||||
M: RotationWithTranslation<LV, AV>>(
|
M: RotationWithTranslation<LV, AV>>(
|
||||||
@ -564,7 +561,7 @@ pub fn append_rotation_wrt_point<LV: Neg<Output = LV> + Copy,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Rotates a copy of `m` by `amount` using `m.translation()` as the pivot point.
|
/// Rotates a copy of `m` by `amount` using `m.translation()` as the pivot point.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn append_rotation_wrt_center<LV: Neg<Output = LV> + Copy,
|
pub fn append_rotation_wrt_center<LV: Neg<Output = LV> + Copy,
|
||||||
AV,
|
AV,
|
||||||
M: RotationWithTranslation<LV, AV>>(
|
M: RotationWithTranslation<LV, AV>>(
|
||||||
@ -577,13 +574,13 @@ pub fn append_rotation_wrt_center<LV: Neg<Output = LV> + Copy,
|
|||||||
* RotationTo
|
* RotationTo
|
||||||
*/
|
*/
|
||||||
/// Computes the angle of the rotation needed to transfom `a` to `b`.
|
/// Computes the angle of the rotation needed to transfom `a` to `b`.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn angle_between<V: RotationTo>(a: &V, b: &V) -> V::AngleType {
|
pub fn angle_between<V: RotationTo>(a: &V, b: &V) -> V::AngleType {
|
||||||
a.angle_to(b)
|
a.angle_to(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the rotation needed to transform `a` to `b`.
|
/// Computes the rotation needed to transform `a` to `b`.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn rotation_between<V: RotationTo>(a: &V, b: &V) -> V::DeltaRotationType {
|
pub fn rotation_between<V: RotationTo>(a: &V, b: &V) -> V::DeltaRotationType {
|
||||||
a.rotation_to(b)
|
a.rotation_to(b)
|
||||||
}
|
}
|
||||||
@ -593,7 +590,7 @@ pub fn rotation_between<V: RotationTo>(a: &V, b: &V) -> V::DeltaRotationType {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/// Builds a rotation matrix from `r`.
|
/// Builds a rotation matrix from `r`.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn to_rotation_matrix<N, LV, AV, R, M>(r: &R) -> M
|
pub fn to_rotation_matrix<N, LV, AV, R, M>(r: &R) -> M
|
||||||
where R: RotationMatrix<N, LV, AV, Output = M>,
|
where R: RotationMatrix<N, LV, AV, Output = M>,
|
||||||
M: SquareMatrix<N, LV> + Rotation<AV> + Copy,
|
M: SquareMatrix<N, LV> + Rotation<AV> + Copy,
|
||||||
@ -608,7 +605,7 @@ pub fn to_rotation_matrix<N, LV, AV, R, M>(r: &R) -> M
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/// Applies a rotation using the absolute values of its components.
|
/// Applies a rotation using the absolute values of its components.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn absolute_rotate<V, M: AbsoluteRotate<V>>(m: &M, v: &V) -> V {
|
pub fn absolute_rotate<V, M: AbsoluteRotate<V>>(m: &M, v: &V) -> V {
|
||||||
m.absolute_rotate(v)
|
m.absolute_rotate(v)
|
||||||
}
|
}
|
||||||
@ -618,19 +615,19 @@ pub fn absolute_rotate<V, M: AbsoluteRotate<V>>(m: &M, v: &V) -> V {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/// Gets the transformation applicable by `m`.
|
/// Gets the transformation applicable by `m`.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn transformation<T, M: Transformation<T>>(m: &M) -> T {
|
pub fn transformation<T, M: Transformation<T>>(m: &M) -> T {
|
||||||
m.transformation()
|
m.transformation()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the inverse transformation applicable by `m`.
|
/// Gets the inverse transformation applicable by `m`.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn inverse_transformation<T, M: Transformation<T>>(m: &M) -> T {
|
pub fn inverse_transformation<T, M: Transformation<T>>(m: &M) -> T {
|
||||||
m.inverse_transformation()
|
m.inverse_transformation()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a transformed copy of `m`.
|
/// Gets a transformed copy of `m`.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn append_transformation<T, M: Transformation<T>>(m: &M, t: &T) -> M {
|
pub fn append_transformation<T, M: Transformation<T>>(m: &M, t: &T) -> M {
|
||||||
Transformation::append_transformation(m, t)
|
Transformation::append_transformation(m, t)
|
||||||
}
|
}
|
||||||
@ -640,13 +637,13 @@ pub fn append_transformation<T, M: Transformation<T>>(m: &M, t: &T) -> M {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/// Applies a transformation to a vector.
|
/// Applies a transformation to a vector.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn transform<V, M: Transform<V>>(m: &M, v: &V) -> V {
|
pub fn transform<V, M: Transform<V>>(m: &M, v: &V) -> V {
|
||||||
m.transform(v)
|
m.transform(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Applies an inverse transformation to a vector.
|
/// Applies an inverse transformation to a vector.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn inverse_transform<V, M: Transform<V>>(m: &M, v: &V) -> V {
|
pub fn inverse_transform<V, M: Transform<V>>(m: &M, v: &V) -> V {
|
||||||
m.inverse_transform(v)
|
m.inverse_transform(v)
|
||||||
}
|
}
|
||||||
@ -656,7 +653,7 @@ pub fn inverse_transform<V, M: Transform<V>>(m: &M, v: &V) -> V {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/// Computes the dot product of two vectors.
|
/// Computes the dot product of two vectors.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn dot<V: Dot<N>, N>(a: &V, b: &V) -> N {
|
pub fn dot<V: Dot<N>, N>(a: &V, b: &V) -> N {
|
||||||
Dot::dot(a, b)
|
Dot::dot(a, b)
|
||||||
}
|
}
|
||||||
@ -666,19 +663,19 @@ pub fn dot<V: Dot<N>, N>(a: &V, b: &V) -> N {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/// Computes the L2 norm of a vector.
|
/// Computes the L2 norm of a vector.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn norm<V: Norm<N>, N: BaseFloat>(v: &V) -> N {
|
pub fn norm<V: Norm<N>, N: BaseFloat>(v: &V) -> N {
|
||||||
Norm::norm(v)
|
Norm::norm(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the squared L2 norm of a vector.
|
/// Computes the squared L2 norm of a vector.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn norm_squared<V: Norm<N>, N: BaseFloat>(v: &V) -> N {
|
pub fn norm_squared<V: Norm<N>, N: BaseFloat>(v: &V) -> N {
|
||||||
Norm::norm_squared(v)
|
Norm::norm_squared(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the normalized version of a vector.
|
/// Gets the normalized version of a vector.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn normalize<V: Norm<N>, N: BaseFloat>(v: &V) -> V {
|
pub fn normalize<V: Norm<N>, N: BaseFloat>(v: &V) -> V {
|
||||||
Norm::normalize(v)
|
Norm::normalize(v)
|
||||||
}
|
}
|
||||||
@ -687,7 +684,7 @@ pub fn normalize<V: Norm<N>, N: BaseFloat>(v: &V) -> V {
|
|||||||
* Determinant<N>
|
* Determinant<N>
|
||||||
*/
|
*/
|
||||||
/// Computes the determinant of a square matrix.
|
/// Computes the determinant of a square matrix.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn determinant<M: Determinant<N>, N>(m: &M) -> N {
|
pub fn determinant<M: Determinant<N>, N>(m: &M) -> N {
|
||||||
Determinant::determinant(m)
|
Determinant::determinant(m)
|
||||||
}
|
}
|
||||||
@ -697,7 +694,7 @@ pub fn determinant<M: Determinant<N>, N>(m: &M) -> N {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/// Computes the cross product of two vectors.
|
/// Computes the cross product of two vectors.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn cross<LV: Cross>(a: &LV, b: &LV) -> LV::CrossProductType {
|
pub fn cross<LV: Cross>(a: &LV, b: &LV) -> LV::CrossProductType {
|
||||||
Cross::cross(a, b)
|
Cross::cross(a, b)
|
||||||
}
|
}
|
||||||
@ -708,7 +705,7 @@ pub fn cross<LV: Cross>(a: &LV, b: &LV) -> LV::CrossProductType {
|
|||||||
|
|
||||||
/// Given a vector, computes the matrix which, when multiplied by another vector, computes a cross
|
/// Given a vector, computes the matrix which, when multiplied by another vector, computes a cross
|
||||||
/// product.
|
/// product.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn cross_matrix<V: CrossMatrix<M>, M>(v: &V) -> M {
|
pub fn cross_matrix<V: CrossMatrix<M>, M>(v: &V) -> M {
|
||||||
CrossMatrix::cross_matrix(v)
|
CrossMatrix::cross_matrix(v)
|
||||||
}
|
}
|
||||||
@ -718,7 +715,7 @@ pub fn cross_matrix<V: CrossMatrix<M>, M>(v: &V) -> M {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/// Converts a matrix or vector to homogeneous coordinates.
|
/// Converts a matrix or vector to homogeneous coordinates.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn to_homogeneous<M: ToHomogeneous<Res>, Res>(m: &M) -> Res {
|
pub fn to_homogeneous<M: ToHomogeneous<Res>, Res>(m: &M) -> Res {
|
||||||
ToHomogeneous::to_homogeneous(m)
|
ToHomogeneous::to_homogeneous(m)
|
||||||
}
|
}
|
||||||
@ -730,7 +727,7 @@ pub fn to_homogeneous<M: ToHomogeneous<Res>, Res>(m: &M) -> Res {
|
|||||||
/// Converts a matrix or vector from homogeneous coordinates.
|
/// Converts a matrix or vector from homogeneous coordinates.
|
||||||
///
|
///
|
||||||
/// w-normalization is appied.
|
/// w-normalization is appied.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn from_homogeneous<M, Res: FromHomogeneous<M>>(m: &M) -> Res {
|
pub fn from_homogeneous<M, Res: FromHomogeneous<M>>(m: &M) -> Res {
|
||||||
FromHomogeneous::from(m)
|
FromHomogeneous::from(m)
|
||||||
}
|
}
|
||||||
@ -742,7 +739,7 @@ pub fn from_homogeneous<M, Res: FromHomogeneous<M>>(m: &M) -> Res {
|
|||||||
/// Samples the unit sphere living on the dimension as the samples types.
|
/// Samples the unit sphere living on the dimension as the samples types.
|
||||||
///
|
///
|
||||||
/// The number of sampling point is implementation-specific. It is always uniform.
|
/// The number of sampling point is implementation-specific. It is always uniform.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn sample_sphere<V: UniformSphereSample, F: FnMut(V)>(f: F) {
|
pub fn sample_sphere<V: UniformSphereSample, F: FnMut(V)>(f: F) {
|
||||||
UniformSphereSample::sample(f)
|
UniformSphereSample::sample(f)
|
||||||
}
|
}
|
||||||
@ -757,13 +754,13 @@ pub fn sample_sphere<V: UniformSphereSample, F: FnMut(V)>(f: F) {
|
|||||||
* AproxEq<N>
|
* AproxEq<N>
|
||||||
*/
|
*/
|
||||||
/// Tests approximate equality.
|
/// Tests approximate equality.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn approx_eq<T: ApproxEq<N>, N>(a: &T, b: &T) -> bool {
|
pub fn approx_eq<T: ApproxEq<N>, N>(a: &T, b: &T) -> bool {
|
||||||
ApproxEq::approx_eq(a, b)
|
ApproxEq::approx_eq(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tests approximate equality using a custom epsilon.
|
/// Tests approximate equality using a custom epsilon.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn approx_eq_eps<T: ApproxEq<N>, N>(a: &T, b: &T, eps: &N) -> bool {
|
pub fn approx_eq_eps<T: ApproxEq<N>, N>(a: &T, b: &T, eps: &N) -> bool {
|
||||||
ApproxEq::approx_eq_eps(a, b, eps)
|
ApproxEq::approx_eq_eps(a, b, eps)
|
||||||
}
|
}
|
||||||
@ -774,7 +771,7 @@ pub fn approx_eq_eps<T: ApproxEq<N>, N>(a: &T, b: &T, eps: &N) -> bool {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/// Computes a component-wise absolute value.
|
/// Computes a component-wise absolute value.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn abs<M: Absolute<Res>, Res>(m: &M) -> Res {
|
pub fn abs<M: Absolute<Res>, Res>(m: &M) -> Res {
|
||||||
Absolute::abs(m)
|
Absolute::abs(m)
|
||||||
}
|
}
|
||||||
@ -784,7 +781,7 @@ pub fn abs<M: Absolute<Res>, Res>(m: &M) -> Res {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/// Gets an inverted copy of a matrix.
|
/// Gets an inverted copy of a matrix.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn inverse<M: Inverse>(m: &M) -> Option<M> {
|
pub fn inverse<M: Inverse>(m: &M) -> Option<M> {
|
||||||
Inverse::inverse(m)
|
Inverse::inverse(m)
|
||||||
}
|
}
|
||||||
@ -794,7 +791,7 @@ pub fn inverse<M: Inverse>(m: &M) -> Option<M> {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/// Gets a transposed copy of a matrix.
|
/// Gets a transposed copy of a matrix.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn transpose<M: Transpose>(m: &M) -> M {
|
pub fn transpose<M: Transpose>(m: &M) -> M {
|
||||||
Transpose::transpose(m)
|
Transpose::transpose(m)
|
||||||
}
|
}
|
||||||
@ -804,7 +801,7 @@ pub fn transpose<M: Transpose>(m: &M) -> M {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/// Computes the outer product of two vectors.
|
/// Computes the outer product of two vectors.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn outer<V: Outer>(a: &V, b: &V) -> V::OuterProductType {
|
pub fn outer<V: Outer>(a: &V, b: &V) -> V::OuterProductType {
|
||||||
Outer::outer(a, b)
|
Outer::outer(a, b)
|
||||||
}
|
}
|
||||||
@ -814,7 +811,7 @@ pub fn outer<V: Outer>(a: &V, b: &V) -> V::OuterProductType {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/// Computes the covariance of a set of observations.
|
/// Computes the covariance of a set of observations.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn covariance<M: Covariance<Res>, Res>(observations: &M) -> Res {
|
pub fn covariance<M: Covariance<Res>, Res>(observations: &M) -> Res {
|
||||||
Covariance::covariance(observations)
|
Covariance::covariance(observations)
|
||||||
}
|
}
|
||||||
@ -824,7 +821,7 @@ pub fn covariance<M: Covariance<Res>, Res>(observations: &M) -> Res {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/// Computes the mean of a set of observations.
|
/// Computes the mean of a set of observations.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn mean<N, M: Mean<N>>(observations: &M) -> N {
|
pub fn mean<N, M: Mean<N>>(observations: &M) -> N {
|
||||||
Mean::mean(observations)
|
Mean::mean(observations)
|
||||||
}
|
}
|
||||||
@ -833,7 +830,7 @@ pub fn mean<N, M: Mean<N>>(observations: &M) -> N {
|
|||||||
* EigenQR<N, V>
|
* EigenQR<N, V>
|
||||||
*/
|
*/
|
||||||
/// Computes the eigenvalues and eigenvectors of a square matrix usin the QR algorithm.
|
/// Computes the eigenvalues and eigenvectors of a square matrix usin the QR algorithm.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn eigen_qr<N, V, M>(m: &M, eps: &N, niter: usize) -> (M, V)
|
pub fn eigen_qr<N, V, M>(m: &M, eps: &N, niter: usize) -> (M, V)
|
||||||
where V: Mul<M, Output = V>,
|
where V: Mul<M, Output = V>,
|
||||||
M: EigenQR<N, V> {
|
M: EigenQR<N, V> {
|
||||||
@ -850,7 +847,7 @@ pub fn eigen_qr<N, V, M>(m: &M, eps: &N, niter: usize) -> (M, V)
|
|||||||
* Eye
|
* Eye
|
||||||
*/
|
*/
|
||||||
/// Construct the identity matrix for a given dimension
|
/// Construct the identity matrix for a given dimension
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn new_identity<M: Eye>(dimension: usize) -> M {
|
pub fn new_identity<M: Eye>(dimension: usize) -> M {
|
||||||
Eye::new_identity(dimension)
|
Eye::new_identity(dimension)
|
||||||
}
|
}
|
||||||
@ -862,7 +859,7 @@ pub fn new_identity<M: Eye>(dimension: usize) -> M {
|
|||||||
/// Create an object by repeating a value.
|
/// Create an object by repeating a value.
|
||||||
///
|
///
|
||||||
/// Same as `Identity::new()`.
|
/// Same as `Identity::new()`.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn repeat<N, T: Repeat<N>>(val: N) -> T {
|
pub fn repeat<N, T: Repeat<N>>(val: N) -> T {
|
||||||
Repeat::repeat(val)
|
Repeat::repeat(val)
|
||||||
}
|
}
|
||||||
@ -872,13 +869,13 @@ pub fn repeat<N, T: Repeat<N>>(val: N) -> T {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/// Computes the canonical basis for a given dimension.
|
/// Computes the canonical basis for a given dimension.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn canonical_basis<V: Basis, F: FnMut(V) -> bool>(f: F) {
|
pub fn canonical_basis<V: Basis, F: FnMut(V) -> bool>(f: F) {
|
||||||
Basis::canonical_basis(f)
|
Basis::canonical_basis(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the basis of the orthonormal subspace of a given vector.
|
/// Computes the basis of the orthonormal subspace of a given vector.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn orthonormal_subspace_basis<V: Basis, F: FnMut(V) -> bool>(v: &V, f: F) {
|
pub fn orthonormal_subspace_basis<V: Basis, F: FnMut(V) -> bool>(v: &V, f: F) {
|
||||||
Basis::orthonormal_subspace_basis(v, f)
|
Basis::orthonormal_subspace_basis(v, f)
|
||||||
}
|
}
|
||||||
@ -901,7 +898,7 @@ pub fn canonical_basis_element<V: Basis>(i: usize) -> Option<V> {
|
|||||||
* Diagonal<V>
|
* Diagonal<V>
|
||||||
*/
|
*/
|
||||||
/// Gets the diagonal of a square matrix.
|
/// Gets the diagonal of a square matrix.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn diagonal<M: Diagonal<V>, V>(m: &M) -> V {
|
pub fn diagonal<M: Diagonal<V>, V>(m: &M) -> V {
|
||||||
m.diagonal()
|
m.diagonal()
|
||||||
}
|
}
|
||||||
@ -912,13 +909,13 @@ pub fn diagonal<M: Diagonal<V>, V>(m: &M) -> V {
|
|||||||
/// Gets the dimension an object lives in.
|
/// Gets the dimension an object lives in.
|
||||||
///
|
///
|
||||||
/// Same as `Dimension::dimension::(None::<V>)`.
|
/// Same as `Dimension::dimension::(None::<V>)`.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn dimension<V: Dimension>() -> usize {
|
pub fn dimension<V: Dimension>() -> usize {
|
||||||
Dimension::dimension(None::<V>)
|
Dimension::dimension(None::<V>)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the indexable range of an object.
|
/// Gets the indexable range of an object.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn shape<V: Shape<I>, I>(v: &V) -> I {
|
pub fn shape<V: Shape<I>, I>(v: &V) -> I {
|
||||||
v.shape()
|
v.shape()
|
||||||
}
|
}
|
||||||
@ -940,7 +937,7 @@ pub fn shape<V: Shape<I>, I>(v: &V) -> I {
|
|||||||
/// range of an i32 when a cast from i64 to i32 is done).
|
/// range of an i32 when a cast from i64 to i32 is done).
|
||||||
/// * A cast does not affect the dimension of an algebraic object. Note that this prevents an
|
/// * A cast does not affect the dimension of an algebraic object. Note that this prevents an
|
||||||
/// isometric transform to be cast to a raw matrix. Use `to_homogeneous` for that special purpose.
|
/// isometric transform to be cast to a raw matrix. Use `to_homogeneous` for that special purpose.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn cast<T, U: Cast<T>>(t: T) -> U {
|
pub fn cast<T, U: Cast<T>>(t: T) -> U {
|
||||||
Cast::from(t)
|
Cast::from(t)
|
||||||
}
|
}
|
||||||
|
@ -269,7 +269,7 @@ pub fn cholesky<N, V, VS, M>(m: &M) -> Result<M, &'static str>
|
|||||||
Sub<M, Output = M> + ColumnSlice<VS> +
|
Sub<M, Output = M> + ColumnSlice<VS> +
|
||||||
ApproxEq<N> + Copy {
|
ApproxEq<N> + Copy {
|
||||||
|
|
||||||
let mut out = m.clone().transpose();
|
let mut out = m.transpose();
|
||||||
|
|
||||||
if !ApproxEq::approx_eq(&out, &m) {
|
if !ApproxEq::approx_eq(&out, &m) {
|
||||||
return Err("Cholesky: Input matrix is not symmetric");
|
return Err("Cholesky: Input matrix is not symmetric");
|
||||||
@ -302,7 +302,7 @@ pub fn cholesky<N, V, VS, M>(m: &M) -> Result<M, &'static str>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(out);
|
Ok(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Hessenberg
|
/// Hessenberg
|
||||||
@ -320,7 +320,7 @@ pub fn hessenberg<N, V, M>(m: &M) -> (M, M)
|
|||||||
M: Copy + Eye + ColumnSlice<V> + Transpose + Indexable<(usize, usize), N> +
|
M: Copy + Eye + ColumnSlice<V> + Transpose + Indexable<(usize, usize), N> +
|
||||||
Mul<M, Output = M> {
|
Mul<M, Output = M> {
|
||||||
|
|
||||||
let mut h = m.clone();
|
let mut h = *m;
|
||||||
let (rows, cols) = h.shape();
|
let (rows, cols) = h.shape();
|
||||||
|
|
||||||
let mut q : M = Eye::new_identity(cols);
|
let mut q : M = Eye::new_identity(cols);
|
||||||
@ -347,5 +347,5 @@ pub fn hessenberg<N, V, M>(m: &M) -> (M, M)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (q, h);
|
(q, h)
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ impl<N: Clone + Copy> DMatrix<N> {
|
|||||||
|
|
||||||
impl<N> DMatrix<N> {
|
impl<N> DMatrix<N> {
|
||||||
/// Builds a matrix filled with the results of a function applied to each of its component coordinates.
|
/// Builds a matrix filled with the results of a function applied to each of its component coordinates.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn from_fn<F: FnMut(usize, usize) -> N>(nrows: usize, ncols: usize, mut f: F) -> DMatrix<N> {
|
pub fn from_fn<F: FnMut(usize, usize) -> N>(nrows: usize, ncols: usize, mut f: F) -> DMatrix<N> {
|
||||||
DMatrix {
|
DMatrix {
|
||||||
nrows: nrows,
|
nrows: nrows,
|
||||||
@ -133,7 +133,7 @@ dmat_impl!(DMatrix, DVector);
|
|||||||
pub struct DMatrix1<N> {
|
pub struct DMatrix1<N> {
|
||||||
nrows: usize,
|
nrows: usize,
|
||||||
ncols: usize,
|
ncols: usize,
|
||||||
mij: [N; 1 * 1],
|
mij: [N; 1],
|
||||||
}
|
}
|
||||||
|
|
||||||
small_dmat_impl!(DMatrix1, DVector1, 1, 0);
|
small_dmat_impl!(DMatrix1, DVector1, 1, 0);
|
||||||
|
@ -84,9 +84,8 @@ macro_rules! dmat_impl(
|
|||||||
fn new_identity(dimension: usize) -> $dmatrix<N> {
|
fn new_identity(dimension: usize) -> $dmatrix<N> {
|
||||||
let mut res = $dmatrix::new_zeros(dimension, dimension);
|
let mut res = $dmatrix::new_zeros(dimension, dimension);
|
||||||
|
|
||||||
for i in 0..dimension {
|
for i in 0 .. dimension {
|
||||||
let _1: N = ::one();
|
res[(i, i)] = ::one::<N>();
|
||||||
res[(i, i)] = _1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
res
|
||||||
@ -94,7 +93,7 @@ macro_rules! dmat_impl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<N> $dmatrix<N> {
|
impl<N> $dmatrix<N> {
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
fn offset(&self, i: usize, j: usize) -> usize {
|
fn offset(&self, i: usize, j: usize) -> usize {
|
||||||
i + j * self.nrows
|
i + j * self.nrows
|
||||||
}
|
}
|
||||||
@ -774,9 +773,8 @@ macro_rules! dmat_impl(
|
|||||||
// We can init from slice thanks to the matrix being column-major.
|
// We can init from slice thanks to the matrix being column-major.
|
||||||
let start = self.offset(row_start, column_id);
|
let start = self.offset(row_start, column_id);
|
||||||
let stop = self.offset(row_end, column_id);
|
let stop = self.offset(row_end, column_id);
|
||||||
let slice = $dvector::from_slice(row_end - row_start, &self.mij[start .. stop]);
|
|
||||||
|
|
||||||
slice
|
$dvector::from_slice(row_end - row_start, &self.mij[start .. stop])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -824,12 +822,12 @@ macro_rules! dmat_impl(
|
|||||||
let mut slice : $dvector<N> = unsafe {
|
let mut slice : $dvector<N> = unsafe {
|
||||||
$dvector::new_uninitialized(column_end - column_start)
|
$dvector::new_uninitialized(column_end - column_start)
|
||||||
};
|
};
|
||||||
let mut slice_idx = 0;
|
|
||||||
for column_id in column_start .. column_end {
|
for column_id in column_start .. column_end {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
let slice_idx = column_id - column_start;
|
||||||
slice.unsafe_set(slice_idx, self.unsafe_at((row_id, column_id)));
|
slice.unsafe_set(slice_idx, self.unsafe_at((row_id, column_id)));
|
||||||
}
|
}
|
||||||
slice_idx += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
slice
|
slice
|
||||||
@ -1140,7 +1138,7 @@ macro_rules! small_dmat_from_impl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Builds a matrix using an initialization function.
|
/// Builds a matrix using an initialization function.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn from_fn<F: FnMut(usize, usize) -> N>(nrows: usize, ncols: usize, mut f: F) -> $dmatrix<N> {
|
pub fn from_fn<F: FnMut(usize, usize) -> N>(nrows: usize, ncols: usize, mut f: F) -> $dmatrix<N> {
|
||||||
assert!(nrows <= $dimension);
|
assert!(nrows <= $dimension);
|
||||||
assert!(ncols <= $dimension);
|
assert!(ncols <= $dimension);
|
||||||
|
@ -56,9 +56,9 @@ impl<N: Clone> DVector<N> {
|
|||||||
|
|
||||||
impl<N> DVector<N> {
|
impl<N> DVector<N> {
|
||||||
/// Builds a vector filled with the results of a function applied to each of its component coordinates.
|
/// Builds a vector filled with the results of a function applied to each of its component coordinates.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn from_fn<F: FnMut(usize) -> N>(dimension: usize, mut f: F) -> DVector<N> {
|
pub fn from_fn<F: FnMut(usize) -> N>(dimension: usize, f: F) -> DVector<N> {
|
||||||
DVector { at: (0 .. dimension).map(|i| f(i)).collect() }
|
DVector { at: (0 .. dimension).map(f).collect() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The vector length.
|
/// The vector length.
|
||||||
|
@ -191,7 +191,7 @@ macro_rules! small_dvec_from_impl (
|
|||||||
|
|
||||||
impl<N: Zero> $dvector<N> {
|
impl<N: Zero> $dvector<N> {
|
||||||
/// Builds a vector filled with the result of a function.
|
/// Builds a vector filled with the result of a function.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn from_fn<F: FnMut(usize) -> N>(dimension: usize, mut f: F) -> $dvector<N> {
|
pub fn from_fn<F: FnMut(usize) -> N>(dimension: usize, mut f: F) -> $dvector<N> {
|
||||||
assert!(dimension <= $dimension);
|
assert!(dimension <= $dimension);
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ pub struct Isometry3<N> {
|
|||||||
pub translation: Vector3<N>
|
pub translation: Vector3<N>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone + BaseFloat> Isometry3<N> {
|
impl<N: BaseFloat> Isometry3<N> {
|
||||||
/// Creates an isometry that corresponds to the local frame of an observer standing at the
|
/// Creates an isometry that corresponds to the local frame of an observer standing at the
|
||||||
/// point `eye` and looking toward `target`.
|
/// point `eye` and looking toward `target`.
|
||||||
///
|
///
|
||||||
@ -59,7 +59,7 @@ impl<N: Clone + BaseFloat> Isometry3<N> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn new_observer_frame(eye: &Point3<N>, target: &Point3<N>, up: &Vector3<N>) -> Isometry3<N> {
|
pub fn new_observer_frame(eye: &Point3<N>, target: &Point3<N>, up: &Vector3<N>) -> Isometry3<N> {
|
||||||
let new_rotation_matrix = Rotation3::new_observer_frame(&(*target - *eye), up);
|
let new_rotation_matrix = Rotation3::new_observer_frame(&(*target - *eye), up);
|
||||||
Isometry3::new_with_rotation_matrix(eye.as_vector().clone(), new_rotation_matrix)
|
Isometry3::new_with_rotation_matrix(eye.to_vector(), new_rotation_matrix)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds a right-handed look-at view matrix.
|
/// Builds a right-handed look-at view matrix.
|
||||||
|
@ -306,9 +306,9 @@ macro_rules! iterable_impl(
|
|||||||
($t: ident, $dimension: expr) => (
|
($t: ident, $dimension: expr) => (
|
||||||
impl<N> Iterable<N> for $t<N> {
|
impl<N> Iterable<N> for $t<N> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn iter<'l>(&'l self) -> Iter<'l, N> {
|
fn iter(&self) -> Iter<N> {
|
||||||
unsafe {
|
unsafe {
|
||||||
mem::transmute::<&'l $t<N>, &'l [N; $dimension * $dimension]>(self).iter()
|
mem::transmute::<&$t<N>, &[N; $dimension * $dimension]>(self).iter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -319,9 +319,9 @@ macro_rules! iterable_mut_impl(
|
|||||||
($t: ident, $dimension: expr) => (
|
($t: ident, $dimension: expr) => (
|
||||||
impl<N> IterableMut<N> for $t<N> {
|
impl<N> IterableMut<N> for $t<N> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn iter_mut<'l>(&'l mut self) -> IterMut<'l, N> {
|
fn iter_mut(& mut self) -> IterMut<N> {
|
||||||
unsafe {
|
unsafe {
|
||||||
mem::transmute::<&'l mut $t<N>, &'l mut [N; $dimension * $dimension]>(self).iter_mut()
|
mem::transmute::<&mut $t<N>, &mut [N; $dimension * $dimension]>(self).iter_mut()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -740,8 +740,8 @@ macro_rules! transpose_impl(
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn transpose_mut(&mut self) {
|
fn transpose_mut(&mut self) {
|
||||||
for i in 1..$dimension {
|
for i in 1 .. $dimension {
|
||||||
for j in 0..i {
|
for j in 0 .. i {
|
||||||
self.swap((i, j), (j, i))
|
self.swap((i, j), (j, i))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -827,8 +827,9 @@ macro_rules! outer_impl(
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn outer(&self, other: &$t<N>) -> $m<N> {
|
fn outer(&self, other: &$t<N>) -> $m<N> {
|
||||||
let mut res: $m<N> = ::zero();
|
let mut res: $m<N> = ::zero();
|
||||||
for i in 0..Dimension::dimension(None::<$t<N>>) {
|
|
||||||
for j in 0..Dimension::dimension(None::<$t<N>>) {
|
for i in 0 .. ::dimension::<$t<N>>() {
|
||||||
|
for j in 0 .. ::dimension::<$t<N>>() {
|
||||||
res[(i, j)] = self[i] * other[j]
|
res[(i, j)] = self[i] * other[j]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,41 +71,41 @@ impl<N: Arbitrary + BaseFloat> Arbitrary for Orthographic3<N> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: BaseFloat + Clone> Orthographic3<N> {
|
impl<N: BaseFloat> Orthographic3<N> {
|
||||||
/// The smallest x-coordinate of the view cuboid.
|
/// The smallest x-coordinate of the view cuboid.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn left(&self) -> N {
|
pub fn left(&self) -> N {
|
||||||
self.left.clone()
|
self.left
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The largest x-coordinate of the view cuboid.
|
/// The largest x-coordinate of the view cuboid.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn right(&self) -> N {
|
pub fn right(&self) -> N {
|
||||||
self.right.clone()
|
self.right
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The smallest y-coordinate of the view cuboid.
|
/// The smallest y-coordinate of the view cuboid.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn bottom(&self) -> N {
|
pub fn bottom(&self) -> N {
|
||||||
self.bottom.clone()
|
self.bottom
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The largest y-coordinate of the view cuboid.
|
/// The largest y-coordinate of the view cuboid.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn top(&self) -> N {
|
pub fn top(&self) -> N {
|
||||||
self.top.clone()
|
self.top
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The near plane offset of the view cuboid.
|
/// The near plane offset of the view cuboid.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn znear(&self) -> N {
|
pub fn znear(&self) -> N {
|
||||||
self.znear.clone()
|
self.znear
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The far plane offset of the view cuboid.
|
/// The far plane offset of the view cuboid.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn zfar(&self) -> N {
|
pub fn zfar(&self) -> N {
|
||||||
self.zfar.clone()
|
self.zfar
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the smallest x-coordinate of the view cuboid.
|
/// Sets the smallest x-coordinate of the view cuboid.
|
||||||
@ -187,12 +187,11 @@ impl<N: BaseFloat> OrthographicMatrix3<N> {
|
|||||||
assert!(znear < zfar, "The far plane must be farther than the near plane.");
|
assert!(znear < zfar, "The far plane must be farther than the near plane.");
|
||||||
assert!(!::is_zero(&aspect));
|
assert!(!::is_zero(&aspect));
|
||||||
|
|
||||||
let _1: N = ::one();
|
let half: N = ::cast(0.5);
|
||||||
let _2 = _1 + _1;
|
let width = zfar * (vfov * half).tan();
|
||||||
let width = zfar * (vfov / _2).tan();
|
|
||||||
let height = width / aspect;
|
let height = width / aspect;
|
||||||
|
|
||||||
OrthographicMatrix3::new(-width / _2, width / _2, -height / _2, height / _2, znear, zfar)
|
OrthographicMatrix3::new(-width * half, width * half, -height * half, height * half, znear, zfar)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new orthographic matrix from a 4D matrix.
|
/// Creates a new orthographic matrix from a 4D matrix.
|
||||||
@ -207,7 +206,7 @@ impl<N: BaseFloat> OrthographicMatrix3<N> {
|
|||||||
|
|
||||||
/// Returns a reference to the 4D matrix (using homogeneous coordinates) of this projection.
|
/// Returns a reference to the 4D matrix (using homogeneous coordinates) of this projection.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_matrix<'a>(&'a self) -> &'a Matrix4<N> {
|
pub fn as_matrix(&self) -> &Matrix4<N> {
|
||||||
&self.matrix
|
&self.matrix
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,11 +333,11 @@ impl<N: BaseFloat> OrthographicMatrix3<N> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: BaseFloat + Clone> OrthographicMatrix3<N> {
|
impl<N: BaseFloat> OrthographicMatrix3<N> {
|
||||||
/// Returns the 4D matrix (using homogeneous coordinates) of this projection.
|
/// Returns the 4D matrix (using homogeneous coordinates) of this projection.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_matrix<'a>(&'a self) -> Matrix4<N> {
|
pub fn to_matrix(&self) -> Matrix4<N> {
|
||||||
self.matrix.clone()
|
self.matrix
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -351,7 +350,7 @@ impl<N: Arbitrary + BaseFloat> Arbitrary for OrthographicMatrix3<N> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Similarityple helper function for rejection sampling
|
/// Simple helper function for rejection sampling
|
||||||
#[cfg(feature="arbitrary")]
|
#[cfg(feature="arbitrary")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn reject<G: Gen, F: FnMut(&T) -> bool, T: Arbitrary>(g: &mut G, f: F) -> T {
|
pub fn reject<G: Gen, F: FnMut(&T) -> bool, T: Arbitrary>(g: &mut G, f: F) -> T {
|
||||||
|
@ -63,29 +63,29 @@ impl<N: Arbitrary + BaseFloat> Arbitrary for Perspective3<N> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: BaseFloat + Clone> Perspective3<N> {
|
impl<N: BaseFloat> Perspective3<N> {
|
||||||
/// Gets the `width / height` aspect ratio.
|
/// Gets the `width / height` aspect ratio.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn aspect(&self) -> N {
|
pub fn aspect(&self) -> N {
|
||||||
self.aspect.clone()
|
self.aspect
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the y field of view of the view frustrum.
|
/// Gets the y field of view of the view frustrum.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn fovy(&self) -> N {
|
pub fn fovy(&self) -> N {
|
||||||
self.fovy.clone()
|
self.fovy
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the near plane offset of the view frustrum.
|
/// Gets the near plane offset of the view frustrum.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn znear(&self) -> N {
|
pub fn znear(&self) -> N {
|
||||||
self.znear.clone()
|
self.znear
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the far plane offset of the view frustrum.
|
/// Gets the far plane offset of the view frustrum.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn zfar(&self) -> N {
|
pub fn zfar(&self) -> N {
|
||||||
self.zfar.clone()
|
self.zfar
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the `width / height` aspect ratio of the view frustrum.
|
/// Sets the `width / height` aspect ratio of the view frustrum.
|
||||||
@ -165,7 +165,7 @@ impl<N: BaseFloat> PerspectiveMatrix3<N> {
|
|||||||
|
|
||||||
/// Returns a reference to the 4D matrix (using homogeneous coordinates) of this projection.
|
/// Returns a reference to the 4D matrix (using homogeneous coordinates) of this projection.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_matrix<'a>(&'a self) -> &'a Matrix4<N> {
|
pub fn as_matrix(&self) -> &Matrix4<N> {
|
||||||
&self.matrix
|
&self.matrix
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,30 +178,23 @@ impl<N: BaseFloat> PerspectiveMatrix3<N> {
|
|||||||
/// Gets the y field of view of the view frustrum.
|
/// Gets the y field of view of the view frustrum.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn fovy(&self) -> N {
|
pub fn fovy(&self) -> N {
|
||||||
let _1: N = ::one();
|
(::one::<N>() / self.matrix.m22).atan() * ::cast(2.0)
|
||||||
let _2 = _1 + _1;
|
|
||||||
|
|
||||||
(_1 / self.matrix.m22).atan() * _2
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the near plane offset of the view frustrum.
|
/// Gets the near plane offset of the view frustrum.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn znear(&self) -> N {
|
pub fn znear(&self) -> N {
|
||||||
let _1: N = ::one();
|
let ratio = (-self.matrix.m33 + ::one::<N>()) / (-self.matrix.m33 - ::one::<N>());
|
||||||
let _2 = _1 + _1;
|
|
||||||
let ratio = (-self.matrix.m33 + _1) / (-self.matrix.m33 - _1);
|
|
||||||
|
|
||||||
self.matrix.m34 / (_2 * ratio) - self.matrix.m34 / _2
|
self.matrix.m34 / (ratio * ::cast(2.0)) - self.matrix.m34 / ::cast(2.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the far plane offset of the view frustrum.
|
/// Gets the far plane offset of the view frustrum.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn zfar(&self) -> N {
|
pub fn zfar(&self) -> N {
|
||||||
let _1: N = ::one();
|
let ratio = (-self.matrix.m33 + ::one()) / (-self.matrix.m33 - ::one());
|
||||||
let _2 = _1 + _1;
|
|
||||||
let ratio = (-self.matrix.m33 + _1) / (-self.matrix.m33 - _1);
|
|
||||||
|
|
||||||
(self.matrix.m34 - ratio * self.matrix.m34) / _2
|
(self.matrix.m34 - ratio * self.matrix.m34) / ::cast(2.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: add a method to retrieve znear and zfar simultaneously?
|
// FIXME: add a method to retrieve znear and zfar simultaneously?
|
||||||
@ -217,11 +210,8 @@ impl<N: BaseFloat> PerspectiveMatrix3<N> {
|
|||||||
/// Updates this projection with a new y field of view of the view frustrum.
|
/// Updates this projection with a new y field of view of the view frustrum.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_fovy(&mut self, fovy: N) {
|
pub fn set_fovy(&mut self, fovy: N) {
|
||||||
let _1: N = ::one();
|
let old_m22 = self.matrix.m22;
|
||||||
let _2 = _1 + _1;
|
self.matrix.m22 = ::one::<N>() / (fovy / ::cast(2.0)).tan();
|
||||||
|
|
||||||
let old_m22 = self.matrix.m22.clone();
|
|
||||||
self.matrix.m22 = _1 / (fovy / _2).tan();
|
|
||||||
self.matrix.m11 = self.matrix.m11 * (self.matrix.m22 / old_m22);
|
self.matrix.m11 = self.matrix.m11 * (self.matrix.m22 / old_m22);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,18 +232,15 @@ impl<N: BaseFloat> PerspectiveMatrix3<N> {
|
|||||||
/// Updates this projection matrix with new near and far plane offsets of the view frustrum.
|
/// Updates this projection matrix with new near and far plane offsets of the view frustrum.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_znear_and_zfar(&mut self, znear: N, zfar: N) {
|
pub fn set_znear_and_zfar(&mut self, znear: N, zfar: N) {
|
||||||
let _1: N = ::one();
|
|
||||||
let _2 = _1 + _1;
|
|
||||||
|
|
||||||
self.matrix.m33 = (zfar + znear) / (znear - zfar);
|
self.matrix.m33 = (zfar + znear) / (znear - zfar);
|
||||||
self.matrix.m34 = zfar * znear * _2 / (znear - zfar);
|
self.matrix.m34 = zfar * znear * ::cast(2.0) / (znear - zfar);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Projects a point.
|
/// Projects a point.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn project_point(&self, p: &Point3<N>) -> Point3<N> {
|
pub fn project_point(&self, p: &Point3<N>) -> Point3<N> {
|
||||||
let _1: N = ::one();
|
let inverse_denom = -::one::<N>() / p.z;
|
||||||
let inverse_denom = -_1 / p.z;
|
|
||||||
Point3::new(
|
Point3::new(
|
||||||
self.matrix.m11 * p.x * inverse_denom,
|
self.matrix.m11 * p.x * inverse_denom,
|
||||||
self.matrix.m22 * p.y * inverse_denom,
|
self.matrix.m22 * p.y * inverse_denom,
|
||||||
@ -264,8 +251,8 @@ impl<N: BaseFloat> PerspectiveMatrix3<N> {
|
|||||||
/// Projects a vector.
|
/// Projects a vector.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn project_vector(&self, p: &Vector3<N>) -> Vector3<N> {
|
pub fn project_vector(&self, p: &Vector3<N>) -> Vector3<N> {
|
||||||
let _1: N = ::one();
|
let inverse_denom = -::one::<N>() / p.z;
|
||||||
let inverse_denom = -_1 / p.z;
|
|
||||||
Vector3::new(
|
Vector3::new(
|
||||||
self.matrix.m11 * p.x * inverse_denom,
|
self.matrix.m11 * p.x * inverse_denom,
|
||||||
self.matrix.m22 * p.y * inverse_denom,
|
self.matrix.m22 * p.y * inverse_denom,
|
||||||
@ -274,11 +261,11 @@ impl<N: BaseFloat> PerspectiveMatrix3<N> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: BaseFloat + Clone> PerspectiveMatrix3<N> {
|
impl<N: BaseFloat> PerspectiveMatrix3<N> {
|
||||||
/// Returns the 4D matrix (using homogeneous coordinates) of this projection.
|
/// Returns the 4D matrix (using homogeneous coordinates) of this projection.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_matrix<'a>(&'a self) -> Matrix4<N> {
|
pub fn to_matrix(&self) -> Matrix4<N> {
|
||||||
self.matrix.clone()
|
self.matrix
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ macro_rules! point_as_vec_impl(
|
|||||||
|
|
||||||
/// Converts a reference to this point to a reference to its associated vector.
|
/// Converts a reference to this point to a reference to its associated vector.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_vector<'a>(&'a self) -> &'a $tv<N> {
|
pub fn as_vector(&self) -> &$tv<N> {
|
||||||
unsafe {
|
unsafe {
|
||||||
mem::transmute(self)
|
mem::transmute(self)
|
||||||
}
|
}
|
||||||
@ -105,7 +105,7 @@ macro_rules! point_as_vec_impl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn as_vector<'a>(&'a self) -> &'a $tv<N> {
|
fn as_vector(&self) -> &$tv<N> {
|
||||||
self.as_vector()
|
self.as_vector()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ impl<N> Quaternion<N> {
|
|||||||
|
|
||||||
/// The vector part `(i, j, k)` of this quaternion.
|
/// The vector part `(i, j, k)` of this quaternion.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn vector<'a>(&'a self) -> &'a Vector3<N> {
|
pub fn vector(&self) -> &Vector3<N> {
|
||||||
// FIXME: do this require a `repr(C)` ?
|
// FIXME: do this require a `repr(C)` ?
|
||||||
unsafe {
|
unsafe {
|
||||||
mem::transmute(&self.i)
|
mem::transmute(&self.i)
|
||||||
@ -54,7 +54,7 @@ impl<N> Quaternion<N> {
|
|||||||
|
|
||||||
/// The scalar part `w` of this quaternion.
|
/// The scalar part `w` of this quaternion.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn scalar<'a>(&'a self) -> &'a N {
|
pub fn scalar(&self) -> &N {
|
||||||
&self.w
|
&self.w
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -226,10 +226,9 @@ impl<N: BaseFloat> UnitQuaternion<N> {
|
|||||||
/// The primitive rotations are applied in order: 1 roll − 2 pitch − 3 yaw.
|
/// The primitive rotations are applied in order: 1 roll − 2 pitch − 3 yaw.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new_with_euler_angles(roll: N, pitch: N, yaw: N) -> UnitQuaternion<N> {
|
pub fn new_with_euler_angles(roll: N, pitch: N, yaw: N) -> UnitQuaternion<N> {
|
||||||
let _0_5: N = Cast::from(0.5);
|
let (sr, cr) = (roll * ::cast(0.5)).sin_cos();
|
||||||
let (sr, cr) = (roll * _0_5).sin_cos();
|
let (sp, cp) = (pitch * ::cast(0.5)).sin_cos();
|
||||||
let (sp, cp) = (pitch * _0_5).sin_cos();
|
let (sy, cy) = (yaw * ::cast(0.5)).sin_cos();
|
||||||
let (sy, cy) = (yaw * _0_5).sin_cos();
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
UnitQuaternion::new_with_unit_quaternion(
|
UnitQuaternion::new_with_unit_quaternion(
|
||||||
@ -244,17 +243,16 @@ impl<N: BaseFloat> UnitQuaternion<N> {
|
|||||||
|
|
||||||
/// Builds a rotation matrix from this quaternion.
|
/// Builds a rotation matrix from this quaternion.
|
||||||
pub fn to_rotation_matrix(&self) -> Rotation3<N> {
|
pub fn to_rotation_matrix(&self) -> Rotation3<N> {
|
||||||
let _2: N = Cast::from(2.0);
|
|
||||||
let ww = self.q.w * self.q.w;
|
let ww = self.q.w * self.q.w;
|
||||||
let ii = self.q.i * self.q.i;
|
let ii = self.q.i * self.q.i;
|
||||||
let jj = self.q.j * self.q.j;
|
let jj = self.q.j * self.q.j;
|
||||||
let kk = self.q.k * self.q.k;
|
let kk = self.q.k * self.q.k;
|
||||||
let ij = _2 * self.q.i * self.q.j;
|
let ij = self.q.i * self.q.j * ::cast(2.0);
|
||||||
let wk = _2 * self.q.w * self.q.k;
|
let wk = self.q.w * self.q.k * ::cast(2.0);
|
||||||
let wj = _2 * self.q.w * self.q.j;
|
let wj = self.q.w * self.q.j * ::cast(2.0);
|
||||||
let ik = _2 * self.q.i * self.q.k;
|
let ik = self.q.i * self.q.k * ::cast(2.0);
|
||||||
let jk = _2 * self.q.j * self.q.k;
|
let jk = self.q.j * self.q.k * ::cast(2.0);
|
||||||
let wi = _2 * self.q.w * self.q.i;
|
let wi = self.q.w * self.q.i * ::cast(2.0);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
Rotation3::new_with_matrix(
|
Rotation3::new_with_matrix(
|
||||||
@ -282,7 +280,7 @@ impl<N> UnitQuaternion<N> {
|
|||||||
|
|
||||||
/// The `Quaternion` representation of this unit quaternion.
|
/// The `Quaternion` representation of this unit quaternion.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn quaternion<'a>(&'a self) -> &'a Quaternion<N> {
|
pub fn quaternion(&self) -> &Quaternion<N> {
|
||||||
&self.q
|
&self.q
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -379,11 +377,11 @@ impl<N: BaseNum> Mul<Vector3<N>> for UnitQuaternion<N> {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mul(self, right: Vector3<N>) -> Vector3<N> {
|
fn mul(self, right: Vector3<N>) -> Vector3<N> {
|
||||||
let _2: N = ::one::<N>() + ::one();
|
let two: N = ::one::<N>() + ::one();
|
||||||
let mut t = ::cross(self.q.vector(), &right);
|
let mut t = ::cross(self.q.vector(), &right);
|
||||||
t.x = t.x * _2;
|
t.x = t.x * two;
|
||||||
t.y = t.y * _2;
|
t.y = t.y * two;
|
||||||
t.z = t.z * _2;
|
t.z = t.z * two;
|
||||||
|
|
||||||
Vector3::new(t.x * self.q.w, t.y * self.q.w, t.z * self.q.w) + ::cross(self.q.vector(), &t) + right
|
Vector3::new(t.x * self.q.w, t.y * self.q.w, t.z * self.q.w) + ::cross(self.q.vector(), &t) + right
|
||||||
}
|
}
|
||||||
@ -437,9 +435,8 @@ impl<N: BaseNum + Neg<Output = N>> MulAssign<UnitQuaternion<N>> for Point3<N> {
|
|||||||
impl<N: BaseFloat> Rotation<Vector3<N>> for UnitQuaternion<N> {
|
impl<N: BaseFloat> Rotation<Vector3<N>> for UnitQuaternion<N> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rotation(&self) -> Vector3<N> {
|
fn rotation(&self) -> Vector3<N> {
|
||||||
let _2 = ::one::<N>() + ::one();
|
|
||||||
let mut v = *self.q.vector();
|
let mut v = *self.q.vector();
|
||||||
let ang = _2 * v.normalize_mut().atan2(self.q.w);
|
let ang = v.normalize_mut().atan2(self.q.w) * ::cast(2.0);
|
||||||
|
|
||||||
if ::is_zero(&ang) {
|
if ::is_zero(&ang) {
|
||||||
::zero()
|
::zero()
|
||||||
@ -520,9 +517,8 @@ impl<N: BaseFloat + ApproxEq<N>> RotationTo for UnitQuaternion<N> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn angle_to(&self, other: &Self) -> N {
|
fn angle_to(&self, other: &Self) -> N {
|
||||||
let delta = self.rotation_to(other);
|
let delta = self.rotation_to(other);
|
||||||
let _2 = ::one::<N>() + ::one();
|
|
||||||
|
|
||||||
_2 * delta.q.vector().norm().atan2(delta.q.w)
|
delta.q.vector().norm().atan2(delta.q.w) * ::cast(2.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! Rotations matrices.
|
//! Rotations matrices.
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops::{Mul, Neg, MulAssign, Index};
|
use std::ops::{Mul, MulAssign, Index};
|
||||||
use rand::{Rand, Rng};
|
use rand::{Rand, Rng};
|
||||||
use num::{Zero, One};
|
use num::{Zero, One};
|
||||||
use traits::geometry::{Rotate, Rotation, AbsoluteRotate, RotationMatrix, RotationTo, Transform,
|
use traits::geometry::{Rotate, Rotation, AbsoluteRotate, RotationMatrix, RotationTo, Transform,
|
||||||
@ -22,21 +22,21 @@ pub struct Rotation2<N> {
|
|||||||
submatrix: Matrix2<N>
|
submatrix: Matrix2<N>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone + BaseFloat + Neg<Output = N>> Rotation2<N> {
|
impl<N: BaseFloat> Rotation2<N> {
|
||||||
/// Builds a 2 dimensional rotation matrix from an angle in radian.
|
/// Builds a 2 dimensional rotation matrix from an angle in radian.
|
||||||
pub fn new(angle: Vector1<N>) -> Rotation2<N> {
|
pub fn new(angle: Vector1<N>) -> Rotation2<N> {
|
||||||
let (sia, coa) = angle.x.sin_cos();
|
let (sia, coa) = angle.x.sin_cos();
|
||||||
|
|
||||||
Rotation2 {
|
Rotation2 {
|
||||||
submatrix: Matrix2::new(coa.clone(), -sia, sia, coa)
|
submatrix: Matrix2::new(coa, -sia, sia, coa)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: BaseFloat + Clone> Rotation<Vector1<N>> for Rotation2<N> {
|
impl<N: BaseFloat> Rotation<Vector1<N>> for Rotation2<N> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rotation(&self) -> Vector1<N> {
|
fn rotation(&self) -> Vector1<N> {
|
||||||
Vector1::new((-self.submatrix.m12).atan2(self.submatrix.m11.clone()))
|
Vector1::new((-self.submatrix.m12).atan2(self.submatrix.m11))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -51,7 +51,7 @@ impl<N: BaseFloat + Clone> Rotation<Vector1<N>> for Rotation2<N> {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn append_rotation(&self, rotation: &Vector1<N>) -> Rotation2<N> {
|
fn append_rotation(&self, rotation: &Vector1<N>) -> Rotation2<N> {
|
||||||
Rotation2::new(rotation.clone()) * *self
|
Rotation2::new(*rotation) * *self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -61,7 +61,7 @@ impl<N: BaseFloat + Clone> Rotation<Vector1<N>> for Rotation2<N> {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn prepend_rotation(&self, rotation: &Vector1<N>) -> Rotation2<N> {
|
fn prepend_rotation(&self, rotation: &Vector1<N>) -> Rotation2<N> {
|
||||||
*self * Rotation2::new(rotation.clone())
|
*self * Rotation2::new(*rotation)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -106,7 +106,7 @@ impl<N: BaseFloat> AbsoluteRotate<Vector2<N>> for Rotation2<N> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature="arbitrary")]
|
#[cfg(feature="arbitrary")]
|
||||||
impl<N: Arbitrary + Clone + BaseFloat + Neg<Output = N>> Arbitrary for Rotation2<N> {
|
impl<N: Arbitrary + BaseFloat> Arbitrary for Rotation2<N> {
|
||||||
fn arbitrary<G: Gen>(g: &mut G) -> Rotation2<N> {
|
fn arbitrary<G: Gen>(g: &mut G) -> Rotation2<N> {
|
||||||
Rotation2::new(Arbitrary::arbitrary(g))
|
Rotation2::new(Arbitrary::arbitrary(g))
|
||||||
}
|
}
|
||||||
@ -124,7 +124,7 @@ pub struct Rotation3<N> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<N: Clone + BaseFloat> Rotation3<N> {
|
impl<N: BaseFloat> Rotation3<N> {
|
||||||
/// Builds a 3 dimensional rotation matrix from an axis and an angle.
|
/// Builds a 3 dimensional rotation matrix from an axis and an angle.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
@ -137,29 +137,28 @@ impl<N: Clone + BaseFloat> Rotation3<N> {
|
|||||||
else {
|
else {
|
||||||
let mut axis = axisangle;
|
let mut axis = axisangle;
|
||||||
let angle = axis.normalize_mut();
|
let angle = axis.normalize_mut();
|
||||||
let _1: N = ::one();
|
let ux = axis.x;
|
||||||
let ux = axis.x.clone();
|
let uy = axis.y;
|
||||||
let uy = axis.y.clone();
|
let uz = axis.z;
|
||||||
let uz = axis.z.clone();
|
|
||||||
let sqx = ux * ux;
|
let sqx = ux * ux;
|
||||||
let sqy = uy * uy;
|
let sqy = uy * uy;
|
||||||
let sqz = uz * uz;
|
let sqz = uz * uz;
|
||||||
let (sin, cos) = angle.sin_cos();
|
let (sin, cos) = angle.sin_cos();
|
||||||
let one_m_cos = _1 - cos;
|
let one_m_cos = ::one::<N>() - cos;
|
||||||
|
|
||||||
Rotation3 {
|
Rotation3 {
|
||||||
submatrix: Matrix3::new(
|
submatrix: Matrix3::new(
|
||||||
(sqx + (_1 - sqx) * cos),
|
(sqx + (::one::<N>() - sqx) * cos),
|
||||||
(ux * uy * one_m_cos - uz * sin),
|
(ux * uy * one_m_cos - uz * sin),
|
||||||
(ux * uz * one_m_cos + uy * sin),
|
(ux * uz * one_m_cos + uy * sin),
|
||||||
|
|
||||||
(ux * uy * one_m_cos + uz * sin),
|
(ux * uy * one_m_cos + uz * sin),
|
||||||
(sqy + (_1 - sqy) * cos),
|
(sqy + (::one::<N>() - sqy) * cos),
|
||||||
(uy * uz * one_m_cos - ux * sin),
|
(uy * uz * one_m_cos - ux * sin),
|
||||||
|
|
||||||
(ux * uz * one_m_cos - uy * sin),
|
(ux * uz * one_m_cos - uy * sin),
|
||||||
(uy * uz * one_m_cos + ux * sin),
|
(uy * uz * one_m_cos + ux * sin),
|
||||||
(sqz + (_1 - sqz) * cos))
|
(sqz + (::one::<N>() - sqz) * cos))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -193,7 +192,7 @@ impl<N: Clone + BaseFloat> Rotation3<N> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone + BaseFloat> Rotation3<N> {
|
impl<N: BaseFloat> Rotation3<N> {
|
||||||
/// Creates a rotation that corresponds to the local frame of an observer standing at the
|
/// Creates a rotation that corresponds to the local frame of an observer standing at the
|
||||||
/// origin and looking toward `dir`.
|
/// origin and looking toward `dir`.
|
||||||
///
|
///
|
||||||
@ -212,9 +211,9 @@ impl<N: Clone + BaseFloat> Rotation3<N> {
|
|||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
Rotation3::new_with_matrix(Matrix3::new(
|
Rotation3::new_with_matrix(Matrix3::new(
|
||||||
xaxis.x.clone(), yaxis.x.clone(), zaxis.x.clone(),
|
xaxis.x, yaxis.x, zaxis.x,
|
||||||
xaxis.y.clone(), yaxis.y.clone(), zaxis.y.clone(),
|
xaxis.y, yaxis.y, zaxis.y,
|
||||||
xaxis.z , yaxis.z , zaxis.z))
|
xaxis.z, yaxis.z, zaxis.z))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,17 +249,13 @@ impl<N: Clone + BaseFloat> Rotation3<N> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone + BaseFloat + Cast<f64>>
|
impl<N: BaseFloat> Rotation<Vector3<N>> for Rotation3<N> {
|
||||||
Rotation<Vector3<N>> for Rotation3<N> {
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rotation(&self) -> Vector3<N> {
|
fn rotation(&self) -> Vector3<N> {
|
||||||
let angle = ((self.submatrix.m11 + self.submatrix.m22 + self.submatrix.m33 - ::one()) / Cast::from(2.0)).acos();
|
let angle = ((self.submatrix.m11 + self.submatrix.m22 + self.submatrix.m33 - ::one()) / Cast::from(2.0)).acos();
|
||||||
|
|
||||||
if angle != angle {
|
if !angle.is_finite() || ::is_zero(&angle) {
|
||||||
// FIXME: handle that correctly
|
// FIXME: handle the non-finite case robustly.
|
||||||
::zero()
|
|
||||||
}
|
|
||||||
else if ::is_zero(&angle) {
|
|
||||||
::zero()
|
::zero()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -296,7 +291,7 @@ Rotation<Vector3<N>> for Rotation3<N> {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn append_rotation(&self, axisangle: &Vector3<N>) -> Rotation3<N> {
|
fn append_rotation(&self, axisangle: &Vector3<N>) -> Rotation3<N> {
|
||||||
Rotation3::new(axisangle.clone()) * *self
|
Rotation3::new(*axisangle) * *self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -306,7 +301,7 @@ Rotation<Vector3<N>> for Rotation3<N> {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn prepend_rotation(&self, axisangle: &Vector3<N>) -> Rotation3<N> {
|
fn prepend_rotation(&self, axisangle: &Vector3<N>) -> Rotation3<N> {
|
||||||
*self * Rotation3::new(axisangle.clone())
|
*self * Rotation3::new(*axisangle)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -331,7 +326,7 @@ impl<N: BaseFloat> RotationTo for Rotation3<N> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone + Rand + BaseFloat> Rand for Rotation3<N> {
|
impl<N: Rand + BaseFloat> Rand for Rotation3<N> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rand<R: Rng>(rng: &mut R) -> Rotation3<N> {
|
fn rand<R: Rng>(rng: &mut R) -> Rotation3<N> {
|
||||||
Rotation3::new(rng.gen())
|
Rotation3::new(rng.gen())
|
||||||
@ -349,7 +344,7 @@ impl<N: BaseFloat> AbsoluteRotate<Vector3<N>> for Rotation3<N> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature="arbitrary")]
|
#[cfg(feature="arbitrary")]
|
||||||
impl<N: Arbitrary + Clone + BaseFloat> Arbitrary for Rotation3<N> {
|
impl<N: Arbitrary + BaseFloat> Arbitrary for Rotation3<N> {
|
||||||
fn arbitrary<G: Gen>(g: &mut G) -> Rotation3<N> {
|
fn arbitrary<G: Gen>(g: &mut G) -> Rotation3<N> {
|
||||||
Rotation3::new(Arbitrary::arbitrary(g))
|
Rotation3::new(Arbitrary::arbitrary(g))
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ macro_rules! submat_impl(
|
|||||||
impl<N> $t<N> {
|
impl<N> $t<N> {
|
||||||
/// This rotation's underlying matrix.
|
/// This rotation's underlying matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn submatrix<'r>(&'r self) -> &'r $submatrix<N> {
|
pub fn submatrix(&self) -> &$submatrix<N> {
|
||||||
&self.submatrix
|
&self.submatrix
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,9 +24,8 @@ impl<N: BaseNum + ApproxEq<N>> Inverse for Matrix1<N> {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let _1: N = ::one();
|
self.m11 = ::one::<N>() / Determinant::determinant(self);
|
||||||
|
|
||||||
self.m11 = _1 / Determinant::determinant(self);
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -234,7 +233,7 @@ impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix3<N>> for Matr
|
|||||||
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix2<N>> for Matrix2<N> {
|
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix2<N>> for Matrix2<N> {
|
||||||
type Output = Matrix2<N>;
|
type Output = Matrix2<N>;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
fn mul(self, right: Matrix2<N>) -> Matrix2<N> {
|
fn mul(self, right: Matrix2<N>) -> Matrix2<N> {
|
||||||
Matrix2::new(
|
Matrix2::new(
|
||||||
self.m11 * right.m11 + self.m12 * right.m21,
|
self.m11 * right.m11 + self.m12 * right.m21,
|
||||||
@ -249,7 +248,7 @@ impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix2<N>> for Matr
|
|||||||
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Vector3<N>> for Matrix3<N> {
|
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Vector3<N>> for Matrix3<N> {
|
||||||
type Output = Vector3<N>;
|
type Output = Vector3<N>;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
fn mul(self, right: Vector3<N>) -> Vector3<N> {
|
fn mul(self, right: Vector3<N>) -> Vector3<N> {
|
||||||
Vector3::new(
|
Vector3::new(
|
||||||
self.m11 * right.x + self.m12 * right.y + self.m13 * right.z,
|
self.m11 * right.x + self.m12 * right.y + self.m13 * right.z,
|
||||||
@ -262,7 +261,7 @@ impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Vector3<N>> for Matr
|
|||||||
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix3<N>> for Vector3<N> {
|
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix3<N>> for Vector3<N> {
|
||||||
type Output = Vector3<N>;
|
type Output = Vector3<N>;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
fn mul(self, right: Matrix3<N>) -> Vector3<N> {
|
fn mul(self, right: Matrix3<N>) -> Vector3<N> {
|
||||||
Vector3::new(
|
Vector3::new(
|
||||||
self.x * right.m11 + self.y * right.m21 + self.z * right.m31,
|
self.x * right.m11 + self.y * right.m21 + self.z * right.m31,
|
||||||
@ -275,7 +274,7 @@ impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix3<N>> for Vect
|
|||||||
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix2<N>> for Vector2<N> {
|
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix2<N>> for Vector2<N> {
|
||||||
type Output = Vector2<N>;
|
type Output = Vector2<N>;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
fn mul(self, right: Matrix2<N>) -> Vector2<N> {
|
fn mul(self, right: Matrix2<N>) -> Vector2<N> {
|
||||||
Vector2::new(
|
Vector2::new(
|
||||||
self.x * right.m11 + self.y * right.m21,
|
self.x * right.m11 + self.y * right.m21,
|
||||||
@ -287,7 +286,7 @@ impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix2<N>> for Vect
|
|||||||
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Vector2<N>> for Matrix2<N> {
|
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Vector2<N>> for Matrix2<N> {
|
||||||
type Output = Vector2<N>;
|
type Output = Vector2<N>;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
fn mul(self, right: Vector2<N>) -> Vector2<N> {
|
fn mul(self, right: Vector2<N>) -> Vector2<N> {
|
||||||
Vector2::new(
|
Vector2::new(
|
||||||
self.m11 * right.x + self.m12 * right.y,
|
self.m11 * right.x + self.m12 * right.y,
|
||||||
@ -299,7 +298,7 @@ impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Vector2<N>> for Matr
|
|||||||
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Point3<N>> for Matrix3<N> {
|
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Point3<N>> for Matrix3<N> {
|
||||||
type Output = Point3<N>;
|
type Output = Point3<N>;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
fn mul(self, right: Point3<N>) -> Point3<N> {
|
fn mul(self, right: Point3<N>) -> Point3<N> {
|
||||||
Point3::new(
|
Point3::new(
|
||||||
self.m11 * right.x + self.m12 * right.y + self.m13 * right.z,
|
self.m11 * right.x + self.m12 * right.y + self.m13 * right.z,
|
||||||
@ -312,7 +311,7 @@ impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Point3<N>> for Matri
|
|||||||
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix3<N>> for Point3<N> {
|
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix3<N>> for Point3<N> {
|
||||||
type Output = Point3<N>;
|
type Output = Point3<N>;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
fn mul(self, right: Matrix3<N>) -> Point3<N> {
|
fn mul(self, right: Matrix3<N>) -> Point3<N> {
|
||||||
Point3::new(
|
Point3::new(
|
||||||
self.x * right.m11 + self.y * right.m21 + self.z * right.m31,
|
self.x * right.m11 + self.y * right.m21 + self.z * right.m31,
|
||||||
@ -325,7 +324,7 @@ impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix3<N>> for Poin
|
|||||||
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix2<N>> for Point2<N> {
|
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix2<N>> for Point2<N> {
|
||||||
type Output = Point2<N>;
|
type Output = Point2<N>;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
fn mul(self, right: Matrix2<N>) -> Point2<N> {
|
fn mul(self, right: Matrix2<N>) -> Point2<N> {
|
||||||
Point2::new(
|
Point2::new(
|
||||||
self.x * right.m11 + self.y * right.m21,
|
self.x * right.m11 + self.y * right.m21,
|
||||||
@ -337,7 +336,7 @@ impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Matrix2<N>> for Poin
|
|||||||
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Point2<N>> for Matrix2<N> {
|
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Point2<N>> for Matrix2<N> {
|
||||||
type Output = Point2<N>;
|
type Output = Point2<N>;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
fn mul(self, right: Point2<N>) -> Point2<N> {
|
fn mul(self, right: Point2<N>) -> Point2<N> {
|
||||||
Point2::new(
|
Point2::new(
|
||||||
self.m11 * right.x + self.m12 * right.y,
|
self.m11 * right.x + self.m12 * right.y,
|
||||||
@ -350,7 +349,7 @@ impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Point2<N>> for Matri
|
|||||||
macro_rules! impl_mul_assign_from_mul(
|
macro_rules! impl_mul_assign_from_mul(
|
||||||
($tleft: ident, $tright: ident) => (
|
($tleft: ident, $tright: ident) => (
|
||||||
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> MulAssign<$tright<N>> for $tleft<N> {
|
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> MulAssign<$tright<N>> for $tleft<N> {
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
fn mul_assign(&mut self, right: $tright<N>) {
|
fn mul_assign(&mut self, right: $tright<N>) {
|
||||||
// NOTE: there is probably no interesting optimization compared to the not-inplace
|
// NOTE: there is probably no interesting optimization compared to the not-inplace
|
||||||
// operation.
|
// operation.
|
||||||
|
@ -5,7 +5,7 @@ use traits::structure::Cast;
|
|||||||
macro_rules! primitive_cast_impl(
|
macro_rules! primitive_cast_impl(
|
||||||
($from: ty, $to: ty) => (
|
($from: ty, $to: ty) => (
|
||||||
impl Cast<$from> for $to {
|
impl Cast<$from> for $to {
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
fn from(t: $from) -> $to {
|
fn from(t: $from) -> $to {
|
||||||
t as $to
|
t as $to
|
||||||
}
|
}
|
||||||
|
@ -115,12 +115,12 @@ impl<N: Copy> Row<Vector1<N>> for Vector2<N> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<N: One> Basis for Vector1<N> {
|
impl<N: One> Basis for Vector1<N> {
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
fn canonical_basis<F: FnMut(Vector1<N>) -> bool>(mut f: F) {
|
fn canonical_basis<F: FnMut(Vector1<N>) -> bool>(mut f: F) {
|
||||||
f(Vector1::new(::one()));
|
f(Vector1::new(::one()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
fn orthonormal_subspace_basis<F: FnMut(Vector1<N>) -> bool>(_: &Vector1<N>, _: F) { }
|
fn orthonormal_subspace_basis<F: FnMut(Vector1<N>) -> bool>(_: &Vector1<N>, _: F) { }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -135,7 +135,7 @@ impl<N: One> Basis for Vector1<N> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Copy + One + Zero + Neg<Output = N>> Basis for Vector2<N> {
|
impl<N: Copy + One + Zero + Neg<Output = N>> Basis for Vector2<N> {
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
fn canonical_basis<F: FnMut(Vector2<N>) -> bool>(mut f: F) {
|
fn canonical_basis<F: FnMut(Vector2<N>) -> bool>(mut f: F) {
|
||||||
if !f(Vector2::new(::one(), ::zero())) { return };
|
if !f(Vector2::new(::one(), ::zero())) { return };
|
||||||
f(Vector2::new(::zero(), ::one()));
|
f(Vector2::new(::zero(), ::one()));
|
||||||
@ -161,14 +161,14 @@ impl<N: Copy + One + Zero + Neg<Output = N>> Basis for Vector2<N> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<N: BaseFloat> Basis for Vector3<N> {
|
impl<N: BaseFloat> Basis for Vector3<N> {
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
fn canonical_basis<F: FnMut(Vector3<N>) -> bool>(mut f: F) {
|
fn canonical_basis<F: FnMut(Vector3<N>) -> bool>(mut f: F) {
|
||||||
if !f(Vector3::new(::one(), ::zero(), ::zero())) { return };
|
if !f(Vector3::new(::one(), ::zero(), ::zero())) { return };
|
||||||
if !f(Vector3::new(::zero(), ::one(), ::zero())) { return };
|
if !f(Vector3::new(::zero(), ::one(), ::zero())) { return };
|
||||||
f(Vector3::new(::zero(), ::zero(), ::one()));
|
f(Vector3::new(::zero(), ::zero(), ::one()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
fn orthonormal_subspace_basis<F: FnMut(Vector3<N>) -> bool>(n: &Vector3<N>, mut f: F) {
|
fn orthonormal_subspace_basis<F: FnMut(Vector3<N>) -> bool>(n: &Vector3<N>, mut f: F) {
|
||||||
let a =
|
let a =
|
||||||
if n.x.abs() > n.y.abs() {
|
if n.x.abs() > n.y.abs() {
|
||||||
@ -272,14 +272,14 @@ static SAMPLES_3_F64: [Vector3<f64>; 42] = [
|
|||||||
|
|
||||||
impl<N> UniformSphereSample for Vector1<N>
|
impl<N> UniformSphereSample for Vector1<N>
|
||||||
where Vector1<N>: One {
|
where Vector1<N>: One {
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
fn sample<F: FnMut(Vector1<N>)>(mut f: F) {
|
fn sample<F: FnMut(Vector1<N>)>(mut f: F) {
|
||||||
f(::one())
|
f(::one())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Cast<f64> + Copy> UniformSphereSample for Vector2<N> {
|
impl<N: Cast<f64> + Copy> UniformSphereSample for Vector2<N> {
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
fn sample<F: FnMut(Vector2<N>)>(mut f: F) {
|
fn sample<F: FnMut(Vector2<N>)>(mut f: F) {
|
||||||
for sample in SAMPLES_2_F64.iter() {
|
for sample in SAMPLES_2_F64.iter() {
|
||||||
f(Cast::from(*sample))
|
f(Cast::from(*sample))
|
||||||
@ -288,7 +288,7 @@ impl<N: Cast<f64> + Copy> UniformSphereSample for Vector2<N> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Cast<f64> + Copy> UniformSphereSample for Vector3<N> {
|
impl<N: Cast<f64> + Copy> UniformSphereSample for Vector3<N> {
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
fn sample<F: FnMut(Vector3<N>)>(mut f: F) {
|
fn sample<F: FnMut(Vector3<N>)>(mut f: F) {
|
||||||
for sample in SAMPLES_3_F64.iter() {
|
for sample in SAMPLES_3_F64.iter() {
|
||||||
f(Cast::from(*sample))
|
f(Cast::from(*sample))
|
||||||
@ -297,7 +297,7 @@ impl<N: Cast<f64> + Copy> UniformSphereSample for Vector3<N> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Cast<f64> + Copy> UniformSphereSample for Vector4<N> {
|
impl<N: Cast<f64> + Copy> UniformSphereSample for Vector4<N> {
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
fn sample<F: FnMut(Vector4<N>)>(_: F) {
|
fn sample<F: FnMut(Vector4<N>)>(_: F) {
|
||||||
panic!("UniformSphereSample::<Vector4<N>>::sample : Not yet implemented.")
|
panic!("UniformSphereSample::<Vector4<N>>::sample : Not yet implemented.")
|
||||||
// for sample in SAMPLES_3_F32.iter() {
|
// for sample in SAMPLES_3_F32.iter() {
|
||||||
|
@ -250,9 +250,9 @@ macro_rules! iterable_impl(
|
|||||||
($t: ident, $dimension: expr) => (
|
($t: ident, $dimension: expr) => (
|
||||||
impl<N> Iterable<N> for $t<N> {
|
impl<N> Iterable<N> for $t<N> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn iter<'l>(&'l self) -> Iter<'l, N> {
|
fn iter(&self) -> Iter<N> {
|
||||||
unsafe {
|
unsafe {
|
||||||
mem::transmute::<&'l $t<N>, &'l [N; $dimension]>(self).iter()
|
mem::transmute::<&$t<N>, &[N; $dimension]>(self).iter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -263,9 +263,9 @@ macro_rules! iterable_mut_impl(
|
|||||||
($t: ident, $dimension: expr) => (
|
($t: ident, $dimension: expr) => (
|
||||||
impl<N> IterableMut<N> for $t<N> {
|
impl<N> IterableMut<N> for $t<N> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn iter_mut<'l>(&'l mut self) -> IterMut<'l, N> {
|
fn iter_mut(&mut self) -> IterMut<N> {
|
||||||
unsafe {
|
unsafe {
|
||||||
mem::transmute::<&'l mut $t<N>, &'l mut [N; $dimension]>(self).iter_mut()
|
mem::transmute::<&mut $t<N>, &mut [N; $dimension]>(self).iter_mut()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,14 +93,14 @@ macro_rules! vecn_dvec_common_impl(
|
|||||||
*/
|
*/
|
||||||
impl<N $(, $param : ArrayLength<N>)*> Iterable<N> for $vecn<N $(, $param)*> {
|
impl<N $(, $param : ArrayLength<N>)*> Iterable<N> for $vecn<N $(, $param)*> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn iter<'l>(&'l self) -> Iter<'l, N> {
|
fn iter(&self) -> Iter<N> {
|
||||||
self.as_ref().iter()
|
self.as_ref().iter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N $(, $param : ArrayLength<N>)*> IterableMut<N> for $vecn<N $(, $param)*> {
|
impl<N $(, $param : ArrayLength<N>)*> IterableMut<N> for $vecn<N $(, $param)*> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn iter_mut<'l>(&'l mut self) -> IterMut<'l, N> {
|
fn iter_mut(&mut self) -> IterMut<N> {
|
||||||
self.as_mut().iter_mut()
|
self.as_mut().iter_mut()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
//! Low level operations on vectors and matrices.
|
//! Low level operations on vectors and matrices.
|
||||||
|
|
||||||
|
use std::mem;
|
||||||
use num::{Float, Signed};
|
use num::{Float, Signed};
|
||||||
use std::ops::Mul;
|
use std::ops::Mul;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
@ -136,16 +137,14 @@ pub trait PartialOrder {
|
|||||||
if v_min.is_not_comparable() || v_max.is_not_comparable() {
|
if v_min.is_not_comparable() || v_max.is_not_comparable() {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
else if v_min.is_lt() {
|
||||||
|
Some(min)
|
||||||
|
}
|
||||||
|
else if v_max.is_gt() {
|
||||||
|
Some(max)
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
if v_min.is_lt() {
|
Some(self)
|
||||||
Some(min)
|
|
||||||
}
|
|
||||||
else if v_max.is_gt() {
|
|
||||||
Some(max)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Some(self)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -195,8 +194,8 @@ impl ApproxEq<f32> for f32 {
|
|||||||
|
|
||||||
// IEEE754 floats are in the same order as 2s complement isizes
|
// IEEE754 floats are in the same order as 2s complement isizes
|
||||||
// so this trick (subtracting the isizes) works.
|
// so this trick (subtracting the isizes) works.
|
||||||
let iself: i32 = unsafe { ::std::mem::transmute(*self) };
|
let iself: i32 = unsafe { mem::transmute(*self) };
|
||||||
let iother: i32 = unsafe { ::std::mem::transmute(*other) };
|
let iother: i32 = unsafe { mem::transmute(*other) };
|
||||||
|
|
||||||
(iself - iother).abs() < ulps as i32
|
(iself - iother).abs() < ulps as i32
|
||||||
}
|
}
|
||||||
@ -224,8 +223,8 @@ impl ApproxEq<f64> for f64 {
|
|||||||
// Otherwise, differing signs should be not-equal, even if within ulps
|
// Otherwise, differing signs should be not-equal, even if within ulps
|
||||||
if self.signum() != other.signum() { return false; }
|
if self.signum() != other.signum() { return false; }
|
||||||
|
|
||||||
let iself: i64 = unsafe { ::std::mem::transmute(*self) };
|
let iself: i64 = unsafe { mem::transmute(*self) };
|
||||||
let iother: i64 = unsafe { ::std::mem::transmute(*other) };
|
let iother: i64 = unsafe { mem::transmute(*other) };
|
||||||
|
|
||||||
(iself - iother).abs() < ulps as i64
|
(iself - iother).abs() < ulps as i64
|
||||||
}
|
}
|
||||||
|
@ -211,7 +211,7 @@ pub trait Indexable<I, N>: Shape<I> + IndexMut<I, Output = N> {
|
|||||||
/// Traits of objects which can be iterated through like a vector.
|
/// Traits of objects which can be iterated through like a vector.
|
||||||
pub trait Iterable<N> {
|
pub trait Iterable<N> {
|
||||||
/// Gets a vector-like read-only iterator.
|
/// Gets a vector-like read-only iterator.
|
||||||
fn iter<'l>(&'l self) -> Iter<'l, N>;
|
fn iter(&self) -> Iter<N>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is a workaround of current Rust limitations.
|
/// This is a workaround of current Rust limitations.
|
||||||
@ -219,7 +219,7 @@ pub trait Iterable<N> {
|
|||||||
/// Traits of mutable objects which can be iterated through like a vector.
|
/// Traits of mutable objects which can be iterated through like a vector.
|
||||||
pub trait IterableMut<N> {
|
pub trait IterableMut<N> {
|
||||||
/// Gets a vector-like read-write iterator.
|
/// Gets a vector-like read-write iterator.
|
||||||
fn iter_mut<'l>(&'l mut self) -> IterMut<'l, N>;
|
fn iter_mut(&mut self) -> IterMut<N>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -258,7 +258,7 @@ pub trait PointAsVector {
|
|||||||
fn to_vector(self) -> Self::Vector;
|
fn to_vector(self) -> Self::Vector;
|
||||||
|
|
||||||
/// Converts a reference to this point to a reference to its associated vector.
|
/// Converts a reference to this point to a reference to its associated vector.
|
||||||
fn as_vector<'a>(&'a self) -> &'a Self::Vector;
|
fn as_vector(&self) -> &Self::Vector;
|
||||||
|
|
||||||
// NOTE: this is used in some places to overcome some limitations untill the trait reform is
|
// NOTE: this is used in some places to overcome some limitations untill the trait reform is
|
||||||
// done on rustc.
|
// done on rustc.
|
||||||
|
Loading…
Reference in New Issue
Block a user