forked from M-Labs/nalgebra
commit
27f788fbd8
@ -238,7 +238,7 @@ where
|
||||
SB: Storage<N, R>,
|
||||
{
|
||||
assert!(!columns.is_empty(), "At least one column must be given.");
|
||||
let ncols = C::try_to_usize().unwrap_or(columns.len());
|
||||
let ncols = C::try_to_usize().unwrap_or_else(|| columns.len());
|
||||
let nrows = columns[0].len();
|
||||
assert!(
|
||||
columns.len() == ncols,
|
||||
|
@ -81,7 +81,7 @@ impl<N: RealField, D: Dim, S: Storage<N, D>> Unit<Vector<N, D, S>> {
|
||||
{
|
||||
// TODO: the result is wrong when self and rhs are collinear with opposite direction.
|
||||
self.try_slerp(rhs, t, N::default_epsilon())
|
||||
.unwrap_or(Unit::new_unchecked(self.clone_owned()))
|
||||
.unwrap_or_else(|| Unit::new_unchecked(self.clone_owned()))
|
||||
}
|
||||
|
||||
/// Computes the spherical linear interpolation between two unit vectors.
|
||||
|
@ -298,20 +298,6 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||
unsafe { Self::from_data_statically_unchecked(data) }
|
||||
}
|
||||
|
||||
/// The total number of elements of this matrix.
|
||||
///
|
||||
/// # Examples:
|
||||
///
|
||||
/// ```
|
||||
/// # use nalgebra::Matrix3x4;
|
||||
/// let mat = Matrix3x4::<f32>::zeros();
|
||||
/// assert_eq!(mat.len(), 12);
|
||||
#[inline]
|
||||
pub fn len(&self) -> usize {
|
||||
let (nrows, ncols) = self.shape();
|
||||
nrows * ncols
|
||||
}
|
||||
|
||||
/// The shape of this matrix returned as the tuple (number of rows, number of columns).
|
||||
///
|
||||
/// # Examples:
|
||||
|
@ -57,7 +57,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||
N: SimdPartialOrd + Zero,
|
||||
{
|
||||
self.fold_with(
|
||||
|e| e.map(|e| e.inlined_clone()).unwrap_or(N::zero()),
|
||||
|e| e.map(|e| e.inlined_clone()).unwrap_or_else(N::zero),
|
||||
|a, b| a.simd_max(b.inlined_clone()),
|
||||
)
|
||||
}
|
||||
@ -75,7 +75,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||
N: Zero + SimdPartialOrd + SimdSigned,
|
||||
{
|
||||
self.fold_with(
|
||||
|e| e.map(|e| e.simd_abs()).unwrap_or(N::zero()),
|
||||
|e| e.map(|e| e.simd_abs()).unwrap_or_else(N::zero),
|
||||
|a, b| a.simd_min(b.simd_abs()),
|
||||
)
|
||||
}
|
||||
@ -97,7 +97,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||
self.fold_with(
|
||||
|e| {
|
||||
e.map(|e| e.simd_norm1())
|
||||
.unwrap_or(N::SimdRealField::zero())
|
||||
.unwrap_or_else(N::SimdRealField::zero)
|
||||
},
|
||||
|a, b| a.simd_min(b.simd_norm1()),
|
||||
)
|
||||
@ -117,7 +117,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||
N: SimdPartialOrd + Zero,
|
||||
{
|
||||
self.fold_with(
|
||||
|e| e.map(|e| e.inlined_clone()).unwrap_or(N::zero()),
|
||||
|e| e.map(|e| e.inlined_clone()).unwrap_or_else(N::zero),
|
||||
|a, b| a.simd_min(b.inlined_clone()),
|
||||
)
|
||||
}
|
||||
|
@ -10,11 +10,33 @@ use crate::base::storage::Storage;
|
||||
use crate::base::{DefaultAllocator, Matrix, Scalar, SquareMatrix};
|
||||
|
||||
impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||
/// Indicates if this is an empty matrix.
|
||||
/// The total number of elements of this matrix.
|
||||
///
|
||||
/// # Examples:
|
||||
///
|
||||
/// ```
|
||||
/// # use nalgebra::Matrix3x4;
|
||||
/// let mat = Matrix3x4::<f32>::zeros();
|
||||
/// assert_eq!(mat.len(), 12);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn len(&self) -> usize {
|
||||
let (nrows, ncols) = self.shape();
|
||||
nrows * ncols
|
||||
}
|
||||
|
||||
/// Returns true if the matrix contains no elements.
|
||||
///
|
||||
/// # Examples:
|
||||
///
|
||||
/// ```
|
||||
/// # use nalgebra::Matrix3x4;
|
||||
/// let mat = Matrix3x4::<f32>::zeros();
|
||||
/// assert!(!mat.is_empty());
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
let (nrows, ncols) = self.shape();
|
||||
nrows == 0 || ncols == 0
|
||||
self.len() == 0
|
||||
}
|
||||
|
||||
/// Indicates if this is a square matrix.
|
||||
|
@ -72,7 +72,7 @@ pub unsafe trait Storage<N: Scalar, R: Dim, C: Dim = U1>: Debug + Sized {
|
||||
/// Gets the address of the i-th matrix component without performing bound-checking.
|
||||
#[inline]
|
||||
unsafe fn get_address_unchecked_linear(&self, i: usize) -> *const N {
|
||||
self.ptr().wrapping_offset(i as isize)
|
||||
self.ptr().wrapping_add(i)
|
||||
}
|
||||
|
||||
/// Gets the address of the i-th matrix component without performing bound-checking.
|
||||
@ -124,7 +124,7 @@ pub unsafe trait StorageMut<N: Scalar, R: Dim, C: Dim = U1>: Storage<N, R, C> {
|
||||
/// Gets the mutable address of the i-th matrix component without performing bound-checking.
|
||||
#[inline]
|
||||
unsafe fn get_address_unchecked_linear_mut(&mut self, i: usize) -> *mut N {
|
||||
self.ptr_mut().wrapping_offset(i as isize)
|
||||
self.ptr_mut().wrapping_add(i)
|
||||
}
|
||||
|
||||
/// Gets the mutable address of the i-th matrix component without performing bound-checking.
|
||||
|
@ -85,6 +85,12 @@ impl<N, R: Dim, C: Dim> VecStorage<N, R, C> {
|
||||
pub fn len(&self) -> usize {
|
||||
self.data.len()
|
||||
}
|
||||
|
||||
/// Returns true if the underlying vector contains no elements.
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
}
|
||||
|
||||
impl<N, R: Dim, C: Dim> Into<Vec<N>> for VecStorage<N, R, C> {
|
||||
|
@ -187,7 +187,7 @@ where
|
||||
#[inline]
|
||||
fn from(arr: [Isometry<N::Element, D, R::Element>; 2]) -> Self {
|
||||
let tra = Translation::from([arr[0].translation.clone(), arr[1].translation.clone()]);
|
||||
let rot = R::from([arr[0].rotation.clone(), arr[0].rotation.clone()]);
|
||||
let rot = R::from([arr[0].rotation, arr[0].rotation]);
|
||||
|
||||
Self::from_parts(tra, rot)
|
||||
}
|
||||
@ -212,10 +212,10 @@ where
|
||||
arr[3].translation.clone(),
|
||||
]);
|
||||
let rot = R::from([
|
||||
arr[0].rotation.clone(),
|
||||
arr[1].rotation.clone(),
|
||||
arr[2].rotation.clone(),
|
||||
arr[3].rotation.clone(),
|
||||
arr[0].rotation,
|
||||
arr[1].rotation,
|
||||
arr[2].rotation,
|
||||
arr[3].rotation,
|
||||
]);
|
||||
|
||||
Self::from_parts(tra, rot)
|
||||
@ -245,14 +245,14 @@ where
|
||||
arr[7].translation.clone(),
|
||||
]);
|
||||
let rot = R::from([
|
||||
arr[0].rotation.clone(),
|
||||
arr[1].rotation.clone(),
|
||||
arr[2].rotation.clone(),
|
||||
arr[3].rotation.clone(),
|
||||
arr[4].rotation.clone(),
|
||||
arr[5].rotation.clone(),
|
||||
arr[6].rotation.clone(),
|
||||
arr[7].rotation.clone(),
|
||||
arr[0].rotation,
|
||||
arr[1].rotation,
|
||||
arr[2].rotation,
|
||||
arr[3].rotation,
|
||||
arr[4].rotation,
|
||||
arr[5].rotation,
|
||||
arr[6].rotation,
|
||||
arr[7].rotation,
|
||||
]);
|
||||
|
||||
Self::from_parts(tra, rot)
|
||||
@ -290,22 +290,22 @@ where
|
||||
arr[15].translation.clone(),
|
||||
]);
|
||||
let rot = R::from([
|
||||
arr[0].rotation.clone(),
|
||||
arr[1].rotation.clone(),
|
||||
arr[2].rotation.clone(),
|
||||
arr[3].rotation.clone(),
|
||||
arr[4].rotation.clone(),
|
||||
arr[5].rotation.clone(),
|
||||
arr[6].rotation.clone(),
|
||||
arr[7].rotation.clone(),
|
||||
arr[8].rotation.clone(),
|
||||
arr[9].rotation.clone(),
|
||||
arr[10].rotation.clone(),
|
||||
arr[11].rotation.clone(),
|
||||
arr[12].rotation.clone(),
|
||||
arr[13].rotation.clone(),
|
||||
arr[14].rotation.clone(),
|
||||
arr[15].rotation.clone(),
|
||||
arr[0].rotation,
|
||||
arr[1].rotation,
|
||||
arr[2].rotation,
|
||||
arr[3].rotation,
|
||||
arr[4].rotation,
|
||||
arr[5].rotation,
|
||||
arr[6].rotation,
|
||||
arr[7].rotation,
|
||||
arr[8].rotation,
|
||||
arr[9].rotation,
|
||||
arr[10].rotation,
|
||||
arr[11].rotation,
|
||||
arr[12].rotation,
|
||||
arr[13].rotation,
|
||||
arr[14].rotation,
|
||||
arr[15].rotation,
|
||||
]);
|
||||
|
||||
Self::from_parts(tra, rot)
|
||||
|
@ -219,7 +219,7 @@ md_assign_impl_all!(
|
||||
(U3, U3), (U3, U3) for;
|
||||
self: Isometry<N, U3, UnitQuaternion<N>>, rhs: UnitQuaternion<N>;
|
||||
[val] => self.rotation *= rhs;
|
||||
[ref] => self.rotation *= rhs.clone();
|
||||
[ref] => self.rotation *= *rhs;
|
||||
);
|
||||
|
||||
md_assign_impl_all!(
|
||||
@ -236,7 +236,7 @@ md_assign_impl_all!(
|
||||
(U2, U2), (U2, U2) for;
|
||||
self: Isometry<N, U2, UnitComplex<N>>, rhs: UnitComplex<N>;
|
||||
[val] => self.rotation *= rhs;
|
||||
[ref] => self.rotation *= rhs.clone();
|
||||
[ref] => self.rotation *= *rhs;
|
||||
);
|
||||
|
||||
md_assign_impl_all!(
|
||||
@ -378,9 +378,9 @@ isometry_from_composition_impl_all!(
|
||||
self: UnitQuaternion<N>, right: Translation<N, U3>,
|
||||
Output = Isometry<N, U3, UnitQuaternion<N>>;
|
||||
[val val] => Isometry::from_parts(Translation::from(&self * right.vector), self);
|
||||
[ref val] => Isometry::from_parts(Translation::from( self * right.vector), self.clone());
|
||||
[ref val] => Isometry::from_parts(Translation::from( self * right.vector), *self);
|
||||
[val ref] => Isometry::from_parts(Translation::from(&self * &right.vector), self);
|
||||
[ref ref] => Isometry::from_parts(Translation::from( self * &right.vector), self.clone());
|
||||
[ref ref] => Isometry::from_parts(Translation::from( self * &right.vector), *self);
|
||||
);
|
||||
|
||||
// Isometry × Rotation
|
||||
@ -442,9 +442,9 @@ isometry_from_composition_impl_all!(
|
||||
self: Isometry<N, U3, UnitQuaternion<N>>, rhs: UnitQuaternion<N>,
|
||||
Output = Isometry<N, U3, UnitQuaternion<N>>;
|
||||
[val val] => Isometry::from_parts(self.translation, self.rotation * rhs);
|
||||
[ref val] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() * rhs); // TODO: do not clone.
|
||||
[val ref] => Isometry::from_parts(self.translation, self.rotation * rhs.clone());
|
||||
[ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() * rhs.clone());
|
||||
[ref val] => Isometry::from_parts(self.translation.clone(), self.rotation * rhs); // TODO: do not clone.
|
||||
[val ref] => Isometry::from_parts(self.translation, self.rotation * *rhs);
|
||||
[ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation * *rhs);
|
||||
);
|
||||
|
||||
// UnitQuaternion × Isometry
|
||||
@ -469,9 +469,9 @@ isometry_from_composition_impl_all!(
|
||||
self: Isometry<N, U3, UnitQuaternion<N>>, rhs: UnitQuaternion<N>,
|
||||
Output = Isometry<N, U3, UnitQuaternion<N>>;
|
||||
[val val] => Isometry::from_parts(self.translation, self.rotation / rhs);
|
||||
[ref val] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() / rhs); // TODO: do not clone.
|
||||
[val ref] => Isometry::from_parts(self.translation, self.rotation / rhs.clone());
|
||||
[ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() / rhs.clone());
|
||||
[ref val] => Isometry::from_parts(self.translation.clone(), self.rotation / rhs); // TODO: do not clone.
|
||||
[val ref] => Isometry::from_parts(self.translation, self.rotation / *rhs);
|
||||
[ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation / *rhs);
|
||||
);
|
||||
|
||||
// UnitQuaternion ÷ Isometry
|
||||
@ -505,8 +505,8 @@ isometry_from_composition_impl_all!(
|
||||
self: Translation<N, U3>, right: UnitQuaternion<N>, Output = Isometry<N, U3, UnitQuaternion<N>>;
|
||||
[val val] => Isometry::from_parts(self, right);
|
||||
[ref val] => Isometry::from_parts(self.clone(), right);
|
||||
[val ref] => Isometry::from_parts(self, right.clone());
|
||||
[ref ref] => Isometry::from_parts(self.clone(), right.clone());
|
||||
[val ref] => Isometry::from_parts(self, *right);
|
||||
[ref ref] => Isometry::from_parts(self.clone(), *right);
|
||||
);
|
||||
|
||||
// Isometry × UnitComplex
|
||||
@ -516,9 +516,9 @@ isometry_from_composition_impl_all!(
|
||||
self: Isometry<N, U2, UnitComplex<N>>, rhs: UnitComplex<N>,
|
||||
Output = Isometry<N, U2, UnitComplex<N>>;
|
||||
[val val] => Isometry::from_parts(self.translation, self.rotation * rhs);
|
||||
[ref val] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() * rhs); // TODO: do not clone.
|
||||
[val ref] => Isometry::from_parts(self.translation, self.rotation * rhs.clone());
|
||||
[ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() * rhs.clone());
|
||||
[ref val] => Isometry::from_parts(self.translation.clone(), self.rotation * rhs); // TODO: do not clone.
|
||||
[val ref] => Isometry::from_parts(self.translation, self.rotation * *rhs);
|
||||
[ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation * *rhs);
|
||||
);
|
||||
|
||||
// Isometry ÷ UnitComplex
|
||||
@ -528,7 +528,7 @@ isometry_from_composition_impl_all!(
|
||||
self: Isometry<N, U2, UnitComplex<N>>, rhs: UnitComplex<N>,
|
||||
Output = Isometry<N, U2, UnitComplex<N>>;
|
||||
[val val] => Isometry::from_parts(self.translation, self.rotation / rhs);
|
||||
[ref val] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() / rhs); // TODO: do not clone.
|
||||
[val ref] => Isometry::from_parts(self.translation, self.rotation / rhs.clone());
|
||||
[ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() / rhs.clone());
|
||||
[ref val] => Isometry::from_parts(self.translation.clone(), self.rotation / rhs); // TODO: do not clone.
|
||||
[val ref] => Isometry::from_parts(self.translation, self.rotation / *rhs);
|
||||
[ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation / *rhs);
|
||||
);
|
||||
|
@ -26,7 +26,7 @@ impl<N: RealField> Copy for Orthographic3<N> {}
|
||||
impl<N: RealField> Clone for Orthographic3<N> {
|
||||
#[inline]
|
||||
fn clone(&self) -> Self {
|
||||
Self::from_matrix_unchecked(self.matrix.clone())
|
||||
Self::from_matrix_unchecked(self.matrix)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ impl<N: RealField> Copy for Perspective3<N> {}
|
||||
impl<N: RealField> Clone for Perspective3<N> {
|
||||
#[inline]
|
||||
fn clone(&self) -> Self {
|
||||
Self::from_matrix_unchecked(self.matrix.clone())
|
||||
Self::from_matrix_unchecked(self.matrix)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,6 +194,19 @@ where
|
||||
self.coords.len()
|
||||
}
|
||||
|
||||
/// Returns true if the point contains no elements.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # use nalgebra::{Point2, Point3};
|
||||
/// let p = Point2::new(1.0, 2.0);
|
||||
/// assert!(!p.is_empty());
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
|
||||
/// The stride of this point. This is the number of buffer element separating each component of
|
||||
/// this point.
|
||||
#[inline]
|
||||
|
@ -335,7 +335,7 @@ where
|
||||
where
|
||||
N: RealField,
|
||||
{
|
||||
let mut res = self.clone();
|
||||
let mut res = *self;
|
||||
|
||||
if res.try_inverse_mut() {
|
||||
Some(res)
|
||||
@ -520,16 +520,13 @@ where
|
||||
let v = self.vector();
|
||||
let nn = v.norm_squared();
|
||||
let le = nn.simd_le(eps * eps);
|
||||
le.if_else(
|
||||
|| Self::identity(),
|
||||
|| {
|
||||
let w_exp = self.scalar().simd_exp();
|
||||
let n = nn.simd_sqrt();
|
||||
let nv = v * (w_exp * n.simd_sin() / n);
|
||||
le.if_else(Self::identity, || {
|
||||
let w_exp = self.scalar().simd_exp();
|
||||
let n = nn.simd_sqrt();
|
||||
let nv = v * (w_exp * n.simd_sin() / n);
|
||||
|
||||
Self::from_parts(w_exp * n.simd_cos(), nv)
|
||||
},
|
||||
)
|
||||
Self::from_parts(w_exp * n.simd_cos(), nv)
|
||||
})
|
||||
}
|
||||
|
||||
/// Raise the quaternion to a given floating power.
|
||||
|
@ -453,7 +453,7 @@ where
|
||||
sqz + (N::one() - sqz) * cos,
|
||||
))
|
||||
},
|
||||
|| Self::identity(),
|
||||
Self::identity,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -240,7 +240,7 @@ md_assign_impl_all!(
|
||||
(U3, U3), (U3, U3) for;
|
||||
self: Similarity<N, U3, UnitQuaternion<N>>, rhs: UnitQuaternion<N>;
|
||||
[val] => self.isometry.rotation *= rhs;
|
||||
[ref] => self.isometry.rotation *= rhs.clone();
|
||||
[ref] => self.isometry.rotation *= *rhs;
|
||||
);
|
||||
|
||||
md_assign_impl_all!(
|
||||
@ -257,7 +257,7 @@ md_assign_impl_all!(
|
||||
(U2, U2), (U2, U2) for;
|
||||
self: Similarity<N, U2, UnitComplex<N>>, rhs: UnitComplex<N>;
|
||||
[val] => self.isometry.rotation *= rhs;
|
||||
[ref] => self.isometry.rotation *= rhs.clone();
|
||||
[ref] => self.isometry.rotation *= *rhs;
|
||||
);
|
||||
|
||||
md_assign_impl_all!(
|
||||
|
@ -306,9 +306,9 @@ complex_op_impl_all!(
|
||||
self: UnitComplex<N>, rhs: Translation<N, U2>,
|
||||
Output = Isometry<N, U2, UnitComplex<N>>;
|
||||
[val val] => Isometry::from_parts(Translation::from(&self * rhs.vector), self);
|
||||
[ref val] => Isometry::from_parts(Translation::from( self * rhs.vector), self.clone());
|
||||
[ref val] => Isometry::from_parts(Translation::from( self * rhs.vector), *self);
|
||||
[val ref] => Isometry::from_parts(Translation::from(&self * &rhs.vector), self);
|
||||
[ref ref] => Isometry::from_parts(Translation::from( self * &rhs.vector), self.clone());
|
||||
[ref ref] => Isometry::from_parts(Translation::from( self * &rhs.vector), *self);
|
||||
);
|
||||
|
||||
// Translation × UnitComplex
|
||||
@ -319,8 +319,8 @@ complex_op_impl_all!(
|
||||
Output = Isometry<N, U2, UnitComplex<N>>;
|
||||
[val val] => Isometry::from_parts(self, right);
|
||||
[ref val] => Isometry::from_parts(self.clone(), right);
|
||||
[val ref] => Isometry::from_parts(self, right.clone());
|
||||
[ref ref] => Isometry::from_parts(self.clone(), right.clone());
|
||||
[val ref] => Isometry::from_parts(self, *right);
|
||||
[ref ref] => Isometry::from_parts(self.clone(), *right);
|
||||
);
|
||||
|
||||
// UnitComplex ×= UnitComplex
|
||||
|
@ -40,7 +40,7 @@ impl<N: ComplexField, D: Dim, S: StorageMut<N, D, D>> SquareMatrix<N, D, S> {
|
||||
match dim {
|
||||
0 => true,
|
||||
1 => {
|
||||
let determinant = self.get_unchecked((0, 0)).clone();
|
||||
let determinant = *self.get_unchecked((0, 0));
|
||||
if determinant.is_zero() {
|
||||
false
|
||||
} else {
|
||||
|
@ -144,6 +144,11 @@ where
|
||||
self.len
|
||||
}
|
||||
|
||||
/// Returns true if the permutation sequence contains no elements.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
|
||||
/// The determinant of the matrix corresponding to this permutation.
|
||||
#[inline]
|
||||
pub fn determinant<N: One + ClosedNeg>(&self) -> N {
|
||||
|
Loading…
Reference in New Issue
Block a user