Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions nalgebra-glm/src/gtx/rotate_vector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@ use crate::RealNumber;

/// Build the rotation matrix needed to align `normal` and `up`.
pub fn orientation<T: RealNumber>(normal: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> {
if let Some(r) = Rotation3::rotation_between(normal, up) {
r.to_homogeneous()
} else {
TMat4::identity()
}
Rotation3::rotation_between(normal, up)
.map(|x| r.homogenous())
.unwrap_or(|| TMat4::identity())
}

/// Rotate a two dimensional vector.
Expand Down
42 changes: 20 additions & 22 deletions nalgebra-sparse/src/ops/serial/csc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,31 +212,29 @@ fn spsolve_csc_lower_triangular_no_transpose<T: RealField>(
// and the matrix might actually *be* lower triangular, which would induce
// a severe penalty)
let diag_csc_index = l_col_k.row_indices().iter().position(|&i| i == k);
if let Some(diag_csc_index) = diag_csc_index {
let l_kk = l_col_k.values()[diag_csc_index].clone();

if l_kk != T::zero() {
// Update entry associated with diagonal
x_col_j[k] /= l_kk;
// Copy value after updating (so we don't run into the borrow checker)
let x_kj = x_col_j[k].clone();

let row_indices = &l_col_k.row_indices()[(diag_csc_index + 1)..];
let l_values = &l_col_k.values()[(diag_csc_index + 1)..];

// Note: The remaining entries are below the diagonal
for (&i, l_ik) in row_indices.iter().zip(l_values) {
let x_ij = &mut x_col_j[i];
*x_ij -= l_ik.clone() * x_kj.clone();
}
let Some(diag_csc_index) = diag_csc_index else {
return spsolve_encountered_zero_diagonal();
};
let l_kk = l_col_k.values()[diag_csc_index].clone();

x_col_j[k] = x_kj;
} else {
return spsolve_encountered_zero_diagonal();
}
} else {
if l_kk.is_zero() {
return spsolve_encountered_zero_diagonal();
}
// Update entry associated with diagonal
x_col_j[k] /= l_kk;
// Copy value after updating (so we don't run into the borrow checker)
let x_kj = x_col_j[k].clone();

let row_indices = &l_col_k.row_indices()[(diag_csc_index + 1)..];
let l_values = &l_col_k.values()[(diag_csc_index + 1)..];

// Note: The remaining entries are below the diagonal
for (&i, l_ik) in row_indices.iter().zip(l_values) {
let x_ij = &mut x_col_j[i];
*x_ij -= l_ik.clone() * x_kj.clone();
}

x_col_j[k] = x_kj;
}
}

Expand Down
10 changes: 6 additions & 4 deletions src/base/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -398,11 +398,13 @@ where
/// iter::empty::<DMatrix<f64>>().sum::<DMatrix<f64>>(); // panics!
/// ```
fn sum<I: Iterator<Item = OMatrix<T, Dyn, C>>>(mut iter: I) -> OMatrix<T, Dyn, C> {
if let Some(first) = iter.next() {
iter.fold(first, |acc, x| acc + x)
} else {
panic!("Cannot compute `sum` of empty iterator.")
let mut ret = iter
.next()
.expect("Cannot compute `sum` of empty iterator.");
while let Some(next) = iter.next() {
ret += next;
}
ret
}
}

Expand Down
2 changes: 0 additions & 2 deletions src/geometry/isometry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ use crate::base::storage::Owned;
use crate::base::{Const, DefaultAllocator, OMatrix, SVector, Scalar, Unit};
use crate::geometry::{AbstractRotation, Point, Translation};

use crate::{Isometry3, Quaternion, Vector3, Vector4};

#[cfg(feature = "rkyv-serialize")]
use rkyv::bytecheck;

Expand Down
43 changes: 16 additions & 27 deletions src/geometry/quaternion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ impl<T: Scalar> PartialEq for Quaternion<T> {

impl<T: Scalar + Zero> Default for Quaternion<T> {
fn default() -> Self {
Quaternion {
Self {
coords: Vector4::zeros(),
}
}
Expand Down Expand Up @@ -468,17 +468,14 @@ where
where
T: RealField,
{
if let Some((q, n)) = Unit::try_new_and_get(self.clone(), T::zero()) {
if let Some(axis) = Unit::try_new(self.vector().clone_owned(), T::zero()) {
let angle = q.angle() / crate::convert(2.0f64);

(n, angle, Some(axis))
} else {
(n, T::zero(), None)
}
} else {
(T::zero(), T::zero(), None)
}
let Some((q, n)) = Unit::try_new_and_get(self.clone(), T::zero()) else {
return (T::zero(), T::zero(), None);
};
let Some(axis) = Unit::try_new(self.vector().clone_owned(), T::zero()) else {
return (n, T::zero(), None);
};
let angle = q.angle() / crate::convert(2.0f64);
(n, angle, Some(axis))
}

/// Compute the natural logarithm of a quaternion.
Expand Down Expand Up @@ -1319,11 +1316,9 @@ where
where
T: RealField,
{
if let Some(axis) = self.axis() {
axis.into_inner() * self.angle()
} else {
Vector3::zero()
}
self.axis()
.map(|axis| axis.into_inner() * self.angle())
.unwrap_or_else(|| <_>::zero())
}

/// The rotation axis and angle in (0, pi] of this unit quaternion.
Expand Down Expand Up @@ -1380,11 +1375,7 @@ where
where
T: RealField,
{
if let Some(v) = self.axis() {
Quaternion::from_imag(v.into_inner() * self.angle())
} else {
Quaternion::zero()
}
Quaternion::from_imag(self.scaled_axis())
}

/// Raise the quaternion to a given floating power.
Expand All @@ -1409,11 +1400,9 @@ where
where
T: RealField,
{
if let Some(v) = self.axis() {
Self::from_axis_angle(&v, self.angle() * n)
} else {
Self::identity()
}
self.axis()
.map(|v| Self::from_axis_angle(&v, self.angle() * n))
.unwrap_or_else(|| Self::identity())
}

/// Builds a rotation matrix from this unit quaternion.
Expand Down
61 changes: 30 additions & 31 deletions src/linalg/symmetric_eigen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,38 +151,37 @@ where
for i in start..n {
let j = i + 1;

if let Some((rot, norm)) = GivensRotation::cancel_y(&vec) {
if i > start {
// Not the first iteration.
off_diag[i - 1] = norm;
}

let mii = diag[i].clone();
let mjj = diag[j].clone();
let mij = off_diag[i].clone();

let cc = rot.c() * rot.c();
let ss = rot.s() * rot.s();
let cs = rot.c() * rot.s();

let b = cs.clone() * crate::convert(2.0) * mij.clone();

diag[i] = (cc.clone() * mii.clone() + ss.clone() * mjj.clone()) - b.clone();
diag[j] = (ss.clone() * mii.clone() + cc.clone() * mjj.clone()) + b;
off_diag[i] = cs * (mii - mjj) + mij * (cc - ss);

if i != n - 1 {
vec.x = off_diag[i].clone();
vec.y = -rot.s() * off_diag[i + 1].clone();
off_diag[i + 1] *= rot.c();
}

if let Some(ref mut q) = q_mat {
let rot = GivensRotation::new_unchecked(rot.c(), T::from_real(rot.s()));
rot.inverse().rotate_rows(&mut q.fixed_columns_mut::<2>(i));
}
} else {
let Some((rot, norm)) = GivensRotation::cancel_y(&vec) else {
break;
};
if i > start {
// Not the first iteration.
off_diag[i - 1] = norm;
}

let mii = diag[i].clone();
let mjj = diag[j].clone();
let mij = off_diag[i].clone();

let cc = rot.c() * rot.c();
let ss = rot.s() * rot.s();
let cs = rot.c() * rot.s();

let b = cs.clone() * crate::convert(2.0) * mij.clone();

diag[i] = (cc.clone() * mii.clone() + ss.clone() * mjj.clone()) - b.clone();
diag[j] = (ss.clone() * mii.clone() + cc.clone() * mjj.clone()) + b;
off_diag[i] = cs * (mii - mjj) + mij * (cc - ss);

if i != n - 1 {
vec.x = off_diag[i].clone();
vec.y = -rot.s() * off_diag[i + 1].clone();
off_diag[i + 1] *= rot.c();
}

if let Some(ref mut q) = q_mat {
let rot = GivensRotation::new_unchecked(rot.c(), T::from_real(rot.s()));
rot.inverse().rotate_rows(&mut q.fixed_columns_mut::<2>(i));
}
}

Expand Down