Skip to content

Commit f4c64a6

Browse files
authored
Merge pull request #99 from staszewski/checked-vector-normalization
2 parents f5e9ea8 + 6b18056 commit f4c64a6

2 files changed

Lines changed: 34 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111

12+
- Add `Vector::try_normalized` ([#99](https://github.com/helsing-ai/sguaba/pull/99)).
1213
### Changed
1314

1415
### Deprecated

src/vectors.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,16 @@ where
751751
Self::from_nalgebra_vector(self.inner.normalize())
752752
}
753753

754+
/// Returns a unit vector with the same direction as this vector.
755+
///
756+
/// Returns `None` if this vector's magnitude is less than or equal to `min_norm`.
757+
#[must_use]
758+
pub fn try_normalized(&self, min_norm: f64) -> Option<Self> {
759+
self.inner
760+
.try_normalize(min_norm)
761+
.map(Self::from_nalgebra_vector)
762+
}
763+
754764
/// Computes the dot (scalar) product between this vector and another.
755765
///
756766
/// Note that this method's return value is unitless since the unit of the dot product is not
@@ -1392,6 +1402,29 @@ mod tests {
13921402
assert_eq!(v.to_cartesian(), [m(0.0), m(0.0), m(0.0)]);
13931403
}
13941404

1405+
#[test]
1406+
fn try_normalized_zero_vector_returns_none() {
1407+
let v = Vector::<TestFrd>::zero();
1408+
1409+
assert_eq!(v.try_normalized(0.0), None);
1410+
}
1411+
1412+
#[test]
1413+
fn try_normalized_nonzero_vector_returns_unit_vector() {
1414+
let v = vector!(f = m(3.0), r = m(0.0), d = m(4.0); in TestFrd);
1415+
1416+
let normalized = v.try_normalized(0.0).expect("non-zero vector");
1417+
1418+
assert_abs_diff_eq!(normalized.magnitude().get::<meter>(), 1.0);
1419+
}
1420+
1421+
#[test]
1422+
fn try_normalized_returns_none_below_min_norm() {
1423+
let v = vector!(f = m(3.0), r = m(0.0), d = m(4.0); in TestFrd); // magnitude is 5, but we set min_norm to 6
1424+
1425+
assert_eq!(v.try_normalized(6.0), None);
1426+
}
1427+
13951428
#[test]
13961429
fn lerp_works() {
13971430
let v1 = vector!(f = m(0.0), r = m(0.0), d = m(0.0); in TestFrd);

0 commit comments

Comments
 (0)