Skip to content

Commit a8170d7

Browse files
authored
Add vector normalize_and_length method. (#627)
1 parent fecd1c0 commit a8170d7

File tree

17 files changed

+275
-0
lines changed

17 files changed

+275
-0
lines changed

src/f32/coresimd/vec3a.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,21 @@ impl Vec3A {
626626
self.normalize_or(Self::ZERO)
627627
}
628628

629+
/// Returns `self` normalized to length 1.0 and the length of `self`.
630+
///
631+
/// If `self` is zero length then `(Self::X, 0.0)` is returned.
632+
#[inline]
633+
#[must_use]
634+
pub fn normalize_and_length(self) -> (Self, f32) {
635+
let length = self.length();
636+
let rcp = 1.0 / length;
637+
if rcp.is_finite() && rcp > 0.0 {
638+
(self * rcp, length)
639+
} else {
640+
(Self::X, 0.0)
641+
}
642+
}
643+
629644
/// Returns whether `self` is length `1.0` or not.
630645
///
631646
/// Uses a precision threshold of approximately `1e-4`.

src/f32/coresimd/vec4.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,21 @@ impl Vec4 {
620620
self.normalize_or(Self::ZERO)
621621
}
622622

623+
/// Returns `self` normalized to length 1.0 and the length of `self`.
624+
///
625+
/// If `self` is zero length then `(Self::X, 0.0)` is returned.
626+
#[inline]
627+
#[must_use]
628+
pub fn normalize_and_length(self) -> (Self, f32) {
629+
let length = self.length();
630+
let rcp = 1.0 / length;
631+
if rcp.is_finite() && rcp > 0.0 {
632+
(self * rcp, length)
633+
} else {
634+
(Self::X, 0.0)
635+
}
636+
}
637+
623638
/// Returns whether `self` is length `1.0` or not.
624639
///
625640
/// Uses a precision threshold of approximately `1e-4`.

src/f32/neon/vec3a.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,21 @@ impl Vec3A {
668668
self.normalize_or(Self::ZERO)
669669
}
670670

671+
/// Returns `self` normalized to length 1.0 and the length of `self`.
672+
///
673+
/// If `self` is zero length then `(Self::X, 0.0)` is returned.
674+
#[inline]
675+
#[must_use]
676+
pub fn normalize_and_length(self) -> (Self, f32) {
677+
let length = self.length();
678+
let rcp = 1.0 / length;
679+
if rcp.is_finite() && rcp > 0.0 {
680+
(self * rcp, length)
681+
} else {
682+
(Self::X, 0.0)
683+
}
684+
}
685+
671686
/// Returns whether `self` is length `1.0` or not.
672687
///
673688
/// Uses a precision threshold of approximately `1e-4`.

src/f32/neon/vec4.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,21 @@ impl Vec4 {
649649
self.normalize_or(Self::ZERO)
650650
}
651651

652+
/// Returns `self` normalized to length 1.0 and the length of `self`.
653+
///
654+
/// If `self` is zero length then `(Self::X, 0.0)` is returned.
655+
#[inline]
656+
#[must_use]
657+
pub fn normalize_and_length(self) -> (Self, f32) {
658+
let length = self.length();
659+
let rcp = 1.0 / length;
660+
if rcp.is_finite() && rcp > 0.0 {
661+
(self * rcp, length)
662+
} else {
663+
(Self::X, 0.0)
664+
}
665+
}
666+
652667
/// Returns whether `self` is length `1.0` or not.
653668
///
654669
/// Uses a precision threshold of approximately `1e-4`.

src/f32/scalar/vec3a.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,21 @@ impl Vec3A {
649649
self.normalize_or(Self::ZERO)
650650
}
651651

652+
/// Returns `self` normalized to length 1.0 and the length of `self`.
653+
///
654+
/// If `self` is zero length then `(Self::X, 0.0)` is returned.
655+
#[inline]
656+
#[must_use]
657+
pub fn normalize_and_length(self) -> (Self, f32) {
658+
let length = self.length();
659+
let rcp = 1.0 / length;
660+
if rcp.is_finite() && rcp > 0.0 {
661+
(self * rcp, length)
662+
} else {
663+
(Self::X, 0.0)
664+
}
665+
}
666+
652667
/// Returns whether `self` is length `1.0` or not.
653668
///
654669
/// Uses a precision threshold of approximately `1e-4`.

src/f32/scalar/vec4.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,21 @@ impl Vec4 {
703703
self.normalize_or(Self::ZERO)
704704
}
705705

706+
/// Returns `self` normalized to length 1.0 and the length of `self`.
707+
///
708+
/// If `self` is zero length then `(Self::X, 0.0)` is returned.
709+
#[inline]
710+
#[must_use]
711+
pub fn normalize_and_length(self) -> (Self, f32) {
712+
let length = self.length();
713+
let rcp = 1.0 / length;
714+
if rcp.is_finite() && rcp > 0.0 {
715+
(self * rcp, length)
716+
} else {
717+
(Self::X, 0.0)
718+
}
719+
}
720+
706721
/// Returns whether `self` is length `1.0` or not.
707722
///
708723
/// Uses a precision threshold of approximately `1e-4`.

src/f32/sse2/vec3a.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,21 @@ impl Vec3A {
667667
self.normalize_or(Self::ZERO)
668668
}
669669

670+
/// Returns `self` normalized to length 1.0 and the length of `self`.
671+
///
672+
/// If `self` is zero length then `(Self::X, 0.0)` is returned.
673+
#[inline]
674+
#[must_use]
675+
pub fn normalize_and_length(self) -> (Self, f32) {
676+
let length = self.length();
677+
let rcp = 1.0 / length;
678+
if rcp.is_finite() && rcp > 0.0 {
679+
(self * rcp, length)
680+
} else {
681+
(Self::X, 0.0)
682+
}
683+
}
684+
670685
/// Returns whether `self` is length `1.0` or not.
671686
///
672687
/// Uses a precision threshold of approximately `1e-4`.

src/f32/sse2/vec4.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,21 @@ impl Vec4 {
657657
self.normalize_or(Self::ZERO)
658658
}
659659

660+
/// Returns `self` normalized to length 1.0 and the length of `self`.
661+
///
662+
/// If `self` is zero length then `(Self::X, 0.0)` is returned.
663+
#[inline]
664+
#[must_use]
665+
pub fn normalize_and_length(self) -> (Self, f32) {
666+
let length = self.length();
667+
let rcp = 1.0 / length;
668+
if rcp.is_finite() && rcp > 0.0 {
669+
(self * rcp, length)
670+
} else {
671+
(Self::X, 0.0)
672+
}
673+
}
674+
660675
/// Returns whether `self` is length `1.0` or not.
661676
///
662677
/// Uses a precision threshold of approximately `1e-4`.

src/f32/vec2.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,21 @@ impl Vec2 {
572572
self.normalize_or(Self::ZERO)
573573
}
574574

575+
/// Returns `self` normalized to length 1.0 and the length of `self`.
576+
///
577+
/// If `self` is zero length then `(Self::X, 0.0)` is returned.
578+
#[inline]
579+
#[must_use]
580+
pub fn normalize_and_length(self) -> (Self, f32) {
581+
let length = self.length();
582+
let rcp = 1.0 / length;
583+
if rcp.is_finite() && rcp > 0.0 {
584+
(self * rcp, length)
585+
} else {
586+
(Self::X, 0.0)
587+
}
588+
}
589+
575590
/// Returns whether `self` is length `1.0` or not.
576591
///
577592
/// Uses a precision threshold of approximately `1e-4`.

src/f32/vec3.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,21 @@ impl Vec3 {
639639
self.normalize_or(Self::ZERO)
640640
}
641641

642+
/// Returns `self` normalized to length 1.0 and the length of `self`.
643+
///
644+
/// If `self` is zero length then `(Self::X, 0.0)` is returned.
645+
#[inline]
646+
#[must_use]
647+
pub fn normalize_and_length(self) -> (Self, f32) {
648+
let length = self.length();
649+
let rcp = 1.0 / length;
650+
if rcp.is_finite() && rcp > 0.0 {
651+
(self * rcp, length)
652+
} else {
653+
(Self::X, 0.0)
654+
}
655+
}
656+
642657
/// Returns whether `self` is length `1.0` or not.
643658
///
644659
/// Uses a precision threshold of approximately `1e-4`.

0 commit comments

Comments
 (0)