Repository: bitshifter/glam-rs
Pull request #453 (2023-12-20 09:23:14)

Midpoint method for float Vectors
A super quick `midpoint()` method implementation for floating-point vectors, as requested in #448.

```rust
let v0 = Vec3::new(0.0, 1.0, 2.0);
let v1 = Vec3::new(-1.0, 0.0, 1.0);
println!("{}", v0.midpoint(v1));
// > [-0.5, 0.5, 1.5]
```

Still very new to the project architecture (and contributions in general) so feedback is very much appreciated!


Patch:
diff --git a/codegen/templates/vec.rs.tera b/codegen/templates/vec.rs.tera
index 6945c27..3775957 100644
--- a/codegen/templates/vec.rs.tera
+++ b/codegen/templates/vec.rs.tera
@@ -1482,6 +1482,16 @@ impl {{ self_t }} {
         self + ((rhs - self) * s)
     }
 
+    /// Calculates the midpoint between `self` and `rhs`. 
+    ///
+    /// The midpoint is the average of, or halfway point between, two vectors.
+    /// `a.midpoint(b)` should yield the same result as `a.lerp(b, 0.5)`
+    /// while being slightly cheaper to compute.
+    #[inline]
+    pub fn midpoint(self, rhs: Self) -> Self {
+        (self + rhs) * 0.5
+    }
+
     /// Returns true if the absolute difference of all elements between `self` and `rhs` is
     /// less than or equal to `max_abs_diff`.
     ///
diff --git a/src/f32/coresimd/vec3a.rs b/src/f32/coresimd/vec3a.rs
index 559143e..18e0ff9 100644
--- a/src/f32/coresimd/vec3a.rs
+++ b/src/f32/coresimd/vec3a.rs
@@ -643,6 +643,16 @@ impl Vec3A {
         self + ((rhs - self) * s)
     }
 
+    /// Calculates the midpoint between `self` and `rhs`.
+    ///
+    /// The midpoint is the average of, or halfway point between, two vectors.
+    /// `a.midpoint(b)` should yield the same result as `a.lerp(b, 0.5)`
+    /// while being slightly cheaper to compute.
+    #[inline]
+    pub fn midpoint(self, rhs: Self) -> Self {
+        (self + rhs) * 0.5
+    }
+
     /// Returns true if the absolute difference of all elements between `self` and `rhs` is
     /// less than or equal to `max_abs_diff`.
     ///
diff --git a/src/f32/coresimd/vec4.rs b/src/f32/coresimd/vec4.rs
index 81b4e7e..8c59aee 100644
--- a/src/f32/coresimd/vec4.rs
+++ b/src/f32/coresimd/vec4.rs
@@ -621,6 +621,16 @@ impl Vec4 {
         self + ((rhs - self) * s)
     }
 
+    /// Calculates the midpoint between `self` and `rhs`.
+    ///
+    /// The midpoint is the average of, or halfway point between, two vectors.
+    /// `a.midpoint(b)` should yield the same result as `a.lerp(b, 0.5)`
+    /// while being slightly cheaper to compute.
+    #[inline]
+    pub fn midpoint(self, rhs: Self) -> Self {
+        (self + rhs) * 0.5
+    }
+
     /// Returns true if the absolute difference of all elements between `self` and `rhs` is
     /// less than or equal to `max_abs_diff`.
     ///
diff --git a/src/f32/scalar/vec3a.rs b/src/f32/scalar/vec3a.rs
index 040a140..c2f8302 100644
--- a/src/f32/scalar/vec3a.rs
+++ b/src/f32/scalar/vec3a.rs
@@ -684,6 +684,16 @@ impl Vec3A {
         self + ((rhs - self) * s)
     }
 
+    /// Calculates the midpoint between `self` and `rhs`.
+    ///
+    /// The midpoint is the average of, or halfway point between, two vectors.
+    /// `a.midpoint(b)` should yield the same result as `a.lerp(b, 0.5)`
+    /// while being slightly cheaper to compute.
+    #[inline]
+    pub fn midpoint(self, rhs: Self) -> Self {
+        (self + rhs) * 0.5
+    }
+
     /// Returns true if the absolute difference of all elements between `self` and `rhs` is
     /// less than or equal to `max_abs_diff`.
     ///
diff --git a/src/f32/scalar/vec4.rs b/src/f32/scalar/vec4.rs
index 499c3cc..8660f25 100644
--- a/src/f32/scalar/vec4.rs
+++ b/src/f32/scalar/vec4.rs
@@ -729,6 +729,16 @@ impl Vec4 {
         self + ((rhs - self) * s)
     }
 
+    /// Calculates the midpoint between `self` and `rhs`.
+    ///
+    /// The midpoint is the average of, or halfway point between, two vectors.
+    /// `a.midpoint(b)` should yield the same result as `a.lerp(b, 0.5)`
+    /// while being slightly cheaper to compute.
+    #[inline]
+    pub fn midpoint(self, rhs: Self) -> Self {
+        (self + rhs) * 0.5
+    }
+
     /// Returns true if the absolute difference of all elements between `self` and `rhs` is
     /// less than or equal to `max_abs_diff`.
     ///
diff --git a/src/f32/sse2/vec3a.rs b/src/f32/sse2/vec3a.rs
index 96c62a7..8c677f4 100644
--- a/src/f32/sse2/vec3a.rs
+++ b/src/f32/sse2/vec3a.rs
@@ -681,6 +681,16 @@ impl Vec3A {
         self + ((rhs - self) * s)
     }
 
+    /// Calculates the midpoint between `self` and `rhs`.
+    ///
+    /// The midpoint is the average of, or halfway point between, two vectors.
+    /// `a.midpoint(b)` should yield the same result as `a.lerp(b, 0.5)`
+    /// while being slightly cheaper to compute.
+    #[inline]
+    pub fn midpoint(self, rhs: Self) -> Self {
+        (self + rhs) * 0.5
+    }
+
     /// Returns true if the absolute difference of all elements between `self` and `rhs` is
     /// less than or equal to `max_abs_diff`.
     ///
diff --git a/src/f32/sse2/vec4.rs b/src/f32/sse2/vec4.rs
index 3792aae..a3475f0 100644
--- a/src/f32/sse2/vec4.rs
+++ b/src/f32/sse2/vec4.rs
@@ -660,6 +660,16 @@ impl Vec4 {
         self + ((rhs - self) * s)
     }
 
+    /// Calculates the midpoint between `self` and `rhs`.
+    ///
+    /// The midpoint is the average of, or halfway point between, two vectors.
+    /// `a.midpoint(b)` should yield the same result as `a.lerp(b, 0.5)`
+    /// while being slightly cheaper to compute.
+    #[inline]
+    pub fn midpoint(self, rhs: Self) -> Self {
+        (self + rhs) * 0.5
+    }
+
     /// Returns true if the absolute difference of all elements between `self` and `rhs` is
     /// less than or equal to `max_abs_diff`.
     ///
diff --git a/src/f32/vec2.rs b/src/f32/vec2.rs
index 85f7fbd..6411549 100644
--- a/src/f32/vec2.rs
+++ b/src/f32/vec2.rs
@@ -616,6 +616,16 @@ impl Vec2 {
         self + ((rhs - self) * s)
     }
 
+    /// Calculates the midpoint between `self` and `rhs`.
+    ///
+    /// The midpoint is the average of, or halfway point between, two vectors.
+    /// `a.midpoint(b)` should yield the same result as `a.lerp(b, 0.5)`
+    /// while being slightly cheaper to compute.
+    #[inline]
+    pub fn midpoint(self, rhs: Self) -> Self {
+        (self + rhs) * 0.5
+    }
+
     /// Returns true if the absolute difference of all elements between `self` and `rhs` is
     /// less than or equal to `max_abs_diff`.
     ///
diff --git a/src/f32/vec3.rs b/src/f32/vec3.rs
index 8c3af6d..d2a0a2f 100644
--- a/src/f32/vec3.rs
+++ b/src/f32/vec3.rs
@@ -675,6 +675,16 @@ impl Vec3 {
         self + ((rhs - self) * s)
     }
 
+    /// Calculates the midpoint between `self` and `rhs`.
+    ///
+    /// The midpoint is the average of, or halfway point between, two vectors.
+    /// `a.midpoint(b)` should yield the same result as `a.lerp(b, 0.5)`
+    /// while being slightly cheaper to compute.
+    #[inline]
+    pub fn midpoint(self, rhs: Self) -> Self {
+        (self + rhs) * 0.5
+    }
+
     /// Returns true if the absolute difference of all elements between `self` and `rhs` is
     /// less than or equal to `max_abs_diff`.
     ///
diff --git a/src/f32/wasm32/vec3a.rs b/src/f32/wasm32/vec3a.rs
index 70ae013..61ead8f 100644
--- a/src/f32/wasm32/vec3a.rs
+++ b/src/f32/wasm32/vec3a.rs
@@ -656,6 +656,16 @@ impl Vec3A {
         self + ((rhs - self) * s)
     }
 
+    /// Calculates the midpoint between `self` and `rhs`.
+    ///
+    /// The midpoint is the average of, or halfway point between, two vectors.
+    /// `a.midpoint(b)` should yield the same result as `a.lerp(b, 0.5)`
+    /// while being slightly cheaper to compute.
+    #[inline]
+    pub fn midpoint(self, rhs: Self) -> Self {
+        (self + rhs) * 0.5
+    }
+
     /// Returns true if the absolute difference of all elements between `self` and `rhs` is
     /// less than or equal to `max_abs_diff`.
     ///
diff --git a/src/f32/wasm32/vec4.rs b/src/f32/wasm32/vec4.rs
index 4608b34..663dbbc 100644
--- a/src/f32/wasm32/vec4.rs
+++ b/src/f32/wasm32/vec4.rs
@@ -642,6 +642,16 @@ impl Vec4 {
         self + ((rhs - self) * s)
     }
 
+    /// Calculates the midpoint between `self` and `rhs`.
+    ///
+    /// The midpoint is the average of, or halfway point between, two vectors.
+    /// `a.midpoint(b)` should yield the same result as `a.lerp(b, 0.5)`
+    /// while being slightly cheaper to compute.
+    #[inline]
+    pub fn midpoint(self, rhs: Self) -> Self {
+        (self + rhs) * 0.5
+    }
+
     /// Returns true if the absolute difference of all elements between `self` and `rhs` is
     /// less than or equal to `max_abs_diff`.
     ///
diff --git a/src/f64/dvec2.rs b/src/f64/dvec2.rs
index 33bf6ac..fe72a10 100644
--- a/src/f64/dvec2.rs
+++ b/src/f64/dvec2.rs
@@ -616,6 +616,16 @@ impl DVec2 {
         self + ((rhs - self) * s)
     }
 
+    /// Calculates the midpoint between `self` and `rhs`.
+    ///
+    /// The midpoint is the average of, or halfway point between, two vectors.
+    /// `a.midpoint(b)` should yield the same result as `a.lerp(b, 0.5)`
+    /// while being slightly cheaper to compute.
+    #[inline]
+    pub fn midpoint(self, rhs: Self) -> Self {
+        (self + rhs) * 0.5
+    }
+
     /// Returns true if the absolute difference of all elements between `self` and `rhs` is
     /// less than or equal to `max_abs_diff`.
     ///
diff --git a/src/f64/dvec3.rs b/src/f64/dvec3.rs
index a7b0c87..49299e7 100644
--- a/src/f64/dvec3.rs
+++ b/src/f64/dvec3.rs
@@ -675,6 +675,16 @@ impl DVec3 {
         self + ((rhs - self) * s)
     }
 
+    /// Calculates the midpoint between `self` and `rhs`.
+    ///
+    /// The midpoint is the average of, or halfway point between, two vectors.
+    /// `a.midpoint(b)` should yield the same result as `a.lerp(b, 0.5)`
+    /// while being slightly cheaper to compute.
+    #[inline]
+    pub fn midpoint(self, rhs: Self) -> Self {
+        (self + rhs) * 0.5
+    }
+
     /// Returns true if the absolute difference of all elements between `self` and `rhs` is
     /// less than or equal to `max_abs_diff`.
     ///
diff --git a/src/f64/dvec4.rs b/src/f64/dvec4.rs
index acd9ac5..1b52f7f 100644
--- a/src/f64/dvec4.rs
+++ b/src/f64/dvec4.rs
@@ -717,6 +717,16 @@ impl DVec4 {
         self + ((rhs - self) * s)
     }
 
+    /// Calculates the midpoint between `self` and `rhs`.
+    ///
+    /// The midpoint is the average of, or halfway point between, two vectors.
+    /// `a.midpoint(b)` should yield the same result as `a.lerp(b, 0.5)`
+    /// while being slightly cheaper to compute.
+    #[inline]
+    pub fn midpoint(self, rhs: Self) -> Self {
+        (self + rhs) * 0.5
+    }
+
     /// Returns true if the absolute difference of all elements between `self` and `rhs` is
     /// less than or equal to `max_abs_diff`.
     ///


Test patch:
diff --git a/tests/vec2.rs b/tests/vec2.rs
index fd6df74..6f57be3 100644
--- a/tests/vec2.rs
+++ b/tests/vec2.rs
@@ -804,6 +804,14 @@ macro_rules! impl_vec2_float_tests {
             assert_approx_eq!($vec2::ZERO, v0.lerp(v1, 0.5));
         });
 
+        glam_test!(test_midpoint, {
+            let v0 = $vec2::new(-1.0, -1.0);
+            let v1 = $vec2::new(1.0, 1.0);
+            let v2 = $vec2::new(-1.5, 0.0);
+            assert_approx_eq!($vec2::ZERO, v0.midpoint(v1));
+            assert_approx_eq!($vec2::new(-0.25, 0.5), v1.midpoint(v2));
+        });
+
         glam_test!(test_is_finite, {
             assert!($vec2::new(0.0, 0.0).is_finite());
             assert!($vec2::new(-1e-10, 1e10).is_finite());
diff --git a/tests/vec3.rs b/tests/vec3.rs
index 0997826..5c8ed97 100644
--- a/tests/vec3.rs
+++ b/tests/vec3.rs
@@ -897,6 +897,14 @@ macro_rules! impl_vec3_float_tests {
             assert_approx_eq!($vec3::ZERO, v0.lerp(v1, 0.5));
         });
 
+        glam_test!(test_midpoint, {
+            let v0 = $vec3::new(-1.0, -1.0, -1.0);
+            let v1 = $vec3::new(1.0, 1.0, 1.0);
+            let v2 = $vec3::new(-1.5, 0.0, 1.0);
+            assert_approx_eq!($vec3::ZERO, v0.midpoint(v1));
+            assert_approx_eq!($vec3::new(-0.25, 0.5, 1.0), v1.midpoint(v2));
+        });
+
         glam_test!(test_is_finite, {
             assert!($vec3::new(0.0, 0.0, 0.0).is_finite());
             assert!($vec3::new(-1e-10, 1.0, 1e10).is_finite());
diff --git a/tests/vec4.rs b/tests/vec4.rs
index 499c7b8..2560d2d 100644
--- a/tests/vec4.rs
+++ b/tests/vec4.rs
@@ -1006,6 +1006,14 @@ macro_rules! impl_vec4_float_tests {
             assert_approx_eq!($vec4::ZERO, v0.lerp(v1, 0.5));
         });
 
+        glam_test!(test_midpoint, {
+            let v0 = $vec4::new(-1.0, -1.0, -1.0, -1.0);
+            let v1 = $vec4::new(1.0, 1.0, 1.0, 1.0);
+            let v2 = $vec4::new(-1.5, 0.0, 1.0, 0.5);
+            assert_approx_eq!($vec4::ZERO, v0.midpoint(v1));
+            assert_approx_eq!($vec4::new(-0.25, 0.5, 1.0, 0.75), v1.midpoint(v2));
+        });
+
         glam_test!(test_is_finite, {
             assert!($vec4::new(0.0, 0.0, 0.0, 0.0).is_finite());
             assert!($vec4::new(-1e-10, 1.0, 1e10, 42.0).is_finite());