Add is_finite method to vectors and matrices.

This method is useful in debug to error early when some kind of
singularity is encountered.
This commit is contained in:
Richard Dodd 2018-04-28 11:34:45 +01:00
parent 4eb6a53e23
commit 4fede94df5
2 changed files with 46 additions and 0 deletions

View file

@ -106,6 +106,11 @@ impl<S: BaseFloat> Matrix2<S> {
Matrix2::new(c, s, -s, c) Matrix2::new(c, s, -s, c)
} }
/// Are all entries in the matrix finite.
pub fn is_finite(&self) -> bool {
self.x.is_finite() && self.y.is_finite()
}
} }
impl<S: BaseFloat> Matrix3<S> { impl<S: BaseFloat> Matrix3<S> {
@ -205,6 +210,11 @@ impl<S: BaseFloat> Matrix3<S> {
_1subc * axis.z * axis.z + c, _1subc * axis.z * axis.z + c,
) )
} }
/// Are all entries in the matrix finite.
pub fn is_finite(&self) -> bool {
self.x.is_finite() && self.y.is_finite() && self.z.is_finite()
}
} }
impl<S: BaseFloat> Matrix4<S> { impl<S: BaseFloat> Matrix4<S> {
@ -357,6 +367,11 @@ impl<S: BaseFloat> Matrix4<S> {
S::zero(), S::zero(), S::zero(), S::one(), S::zero(), S::zero(), S::zero(), S::one(),
) )
} }
/// Are all entries in the matrix finite.
pub fn is_finite(&self) -> bool {
self.w.is_finite() && self.x.is_finite() && self.y.is_finite() && self.z.is_finite()
}
} }
impl<S: BaseFloat> Zero for Matrix2<S> { impl<S: BaseFloat> Zero for Matrix2<S> {

View file

@ -118,6 +118,13 @@ macro_rules! impl_vector {
$VectorN::new($($field),+) $VectorN::new($($field),+)
} }
impl<S: BaseFloat> $VectorN<S> {
/// True if all entries in the vector are finite
pub fn is_finite(&self) -> bool {
$(self.$field.is_finite())&&+
}
}
impl<S: NumCast + Copy> $VectorN<S> { impl<S: NumCast + Copy> $VectorN<S> {
/// Component-wise casting to another type. /// Component-wise casting to another type.
#[inline] #[inline]
@ -1323,6 +1330,14 @@ mod tests {
assert_eq!(v, &VECTOR2); assert_eq!(v, &VECTOR2);
} }
} }
#[test]
fn test_is_finite() {
use num_traits::Float;
assert!(!Vector2::from([Float::nan(), 1.0]).is_finite());
assert!(!Vector2::from([1.0, Float::infinity()]).is_finite());
assert!(Vector2::from([-1.0, 1.0]).is_finite());
}
} }
mod vector3 { mod vector3 {
@ -1428,6 +1443,14 @@ mod tests {
assert_eq!(v, &VECTOR3); assert_eq!(v, &VECTOR3);
} }
} }
#[test]
fn test_is_finite() {
use num_traits::Float;
assert!(!Vector3::from([Float::nan(), 1.0, 1.0]).is_finite());
assert!(!Vector3::from([1.0, 1.0, Float::infinity()]).is_finite());
assert!(Vector3::from([-1.0, 1.0, 1.0]).is_finite());
}
} }
mod vector4 { mod vector4 {
@ -1539,5 +1562,13 @@ mod tests {
assert_eq!(v, &VECTOR4); assert_eq!(v, &VECTOR4);
} }
} }
#[test]
fn test_is_finite() {
use num_traits::Float;
assert!(!Vector4::from([0.0, Float::nan(), 1.0, 1.0]).is_finite());
assert!(!Vector4::from([1.0, 1.0, Float::neg_infinity(), 0.0]).is_finite());
assert!(Vector4::from([-1.0, 0.0, 1.0, 1.0]).is_finite());
}
} }
} }