Skip to content

Commit

Permalink
Add move_towards for vectors (#492)
Browse files Browse the repository at this point in the history
  • Loading branch information
chompaa committed Mar 13, 2024
1 parent 231a867 commit 30948c4
Show file tree
Hide file tree
Showing 17 changed files with 234 additions and 0 deletions.
15 changes: 15 additions & 0 deletions codegen/templates/vec.rs.tera
Expand Up @@ -1609,6 +1609,21 @@ impl {{ self_t }} {
self + ((rhs - self) * s)
}

/// Moves towards `rhs` based on the value `d`.
///
/// When `d` is `0.0`, the result will be equal to `self`. When `d` is equal to
/// `self.distance(rhs)`, the result will be equal to `rhs`. Will not go past `rhs`.
#[inline]
#[must_use]
pub fn move_towards(&self, rhs: Self, d: {{ scalar_t }}) -> Self {
let a = rhs - *self;
let len = a.length();
if len <= d || len <= 1e-4 {
return rhs;
}
*self + a / len * d
}

/// Calculates the midpoint between `self` and `rhs`.
///
/// The midpoint is the average of, or halfway point between, two vectors.
Expand Down
15 changes: 15 additions & 0 deletions src/f32/coresimd/vec3a.rs
Expand Up @@ -673,6 +673,21 @@ impl Vec3A {
self + ((rhs - self) * s)
}

/// Moves towards `rhs` based on the value `d`.
///
/// When `d` is `0.0`, the result will be equal to `self`. When `d` is equal to
/// `self.distance(rhs)`, the result will be equal to `rhs`. Will not go past `rhs`.
#[inline]
#[must_use]
pub fn move_towards(&self, rhs: Self, d: f32) -> Self {
let a = rhs - *self;
let len = a.length();
if len <= d || len <= 1e-4 {
return rhs;
}
*self + a / len * d
}

/// Calculates the midpoint between `self` and `rhs`.
///
/// The midpoint is the average of, or halfway point between, two vectors.
Expand Down
15 changes: 15 additions & 0 deletions src/f32/coresimd/vec4.rs
Expand Up @@ -651,6 +651,21 @@ impl Vec4 {
self + ((rhs - self) * s)
}

/// Moves towards `rhs` based on the value `d`.
///
/// When `d` is `0.0`, the result will be equal to `self`. When `d` is equal to
/// `self.distance(rhs)`, the result will be equal to `rhs`. Will not go past `rhs`.
#[inline]
#[must_use]
pub fn move_towards(&self, rhs: Self, d: f32) -> Self {
let a = rhs - *self;
let len = a.length();
if len <= d || len <= 1e-4 {
return rhs;
}
*self + a / len * d
}

/// Calculates the midpoint between `self` and `rhs`.
///
/// The midpoint is the average of, or halfway point between, two vectors.
Expand Down
15 changes: 15 additions & 0 deletions src/f32/scalar/vec3a.rs
Expand Up @@ -714,6 +714,21 @@ impl Vec3A {
self + ((rhs - self) * s)
}

/// Moves towards `rhs` based on the value `d`.
///
/// When `d` is `0.0`, the result will be equal to `self`. When `d` is equal to
/// `self.distance(rhs)`, the result will be equal to `rhs`. Will not go past `rhs`.
#[inline]
#[must_use]
pub fn move_towards(&self, rhs: Self, d: f32) -> Self {
let a = rhs - *self;
let len = a.length();
if len <= d || len <= 1e-4 {
return rhs;
}
*self + a / len * d
}

/// Calculates the midpoint between `self` and `rhs`.
///
/// The midpoint is the average of, or halfway point between, two vectors.
Expand Down
15 changes: 15 additions & 0 deletions src/f32/scalar/vec4.rs
Expand Up @@ -760,6 +760,21 @@ impl Vec4 {
self + ((rhs - self) * s)
}

/// Moves towards `rhs` based on the value `d`.
///
/// When `d` is `0.0`, the result will be equal to `self`. When `d` is equal to
/// `self.distance(rhs)`, the result will be equal to `rhs`. Will not go past `rhs`.
#[inline]
#[must_use]
pub fn move_towards(&self, rhs: Self, d: f32) -> Self {
let a = rhs - *self;
let len = a.length();
if len <= d || len <= 1e-4 {
return rhs;
}
*self + a / len * d
}

/// Calculates the midpoint between `self` and `rhs`.
///
/// The midpoint is the average of, or halfway point between, two vectors.
Expand Down
15 changes: 15 additions & 0 deletions src/f32/sse2/vec3a.rs
Expand Up @@ -721,6 +721,21 @@ impl Vec3A {
self + ((rhs - self) * s)
}

/// Moves towards `rhs` based on the value `d`.
///
/// When `d` is `0.0`, the result will be equal to `self`. When `d` is equal to
/// `self.distance(rhs)`, the result will be equal to `rhs`. Will not go past `rhs`.
#[inline]
#[must_use]
pub fn move_towards(&self, rhs: Self, d: f32) -> Self {
let a = rhs - *self;
let len = a.length();
if len <= d || len <= 1e-4 {
return rhs;
}
*self + a / len * d
}

/// Calculates the midpoint between `self` and `rhs`.
///
/// The midpoint is the average of, or halfway point between, two vectors.
Expand Down
15 changes: 15 additions & 0 deletions src/f32/sse2/vec4.rs
Expand Up @@ -700,6 +700,21 @@ impl Vec4 {
self + ((rhs - self) * s)
}

/// Moves towards `rhs` based on the value `d`.
///
/// When `d` is `0.0`, the result will be equal to `self`. When `d` is equal to
/// `self.distance(rhs)`, the result will be equal to `rhs`. Will not go past `rhs`.
#[inline]
#[must_use]
pub fn move_towards(&self, rhs: Self, d: f32) -> Self {
let a = rhs - *self;
let len = a.length();
if len <= d || len <= 1e-4 {
return rhs;
}
*self + a / len * d
}

/// Calculates the midpoint between `self` and `rhs`.
///
/// The midpoint is the average of, or halfway point between, two vectors.
Expand Down
15 changes: 15 additions & 0 deletions src/f32/vec2.rs
Expand Up @@ -646,6 +646,21 @@ impl Vec2 {
self + ((rhs - self) * s)
}

/// Moves towards `rhs` based on the value `d`.
///
/// When `d` is `0.0`, the result will be equal to `self`. When `d` is equal to
/// `self.distance(rhs)`, the result will be equal to `rhs`. Will not go past `rhs`.
#[inline]
#[must_use]
pub fn move_towards(&self, rhs: Self, d: f32) -> Self {
let a = rhs - *self;
let len = a.length();
if len <= d || len <= 1e-4 {
return rhs;
}
*self + a / len * d
}

/// Calculates the midpoint between `self` and `rhs`.
///
/// The midpoint is the average of, or halfway point between, two vectors.
Expand Down
15 changes: 15 additions & 0 deletions src/f32/vec3.rs
Expand Up @@ -705,6 +705,21 @@ impl Vec3 {
self + ((rhs - self) * s)
}

/// Moves towards `rhs` based on the value `d`.
///
/// When `d` is `0.0`, the result will be equal to `self`. When `d` is equal to
/// `self.distance(rhs)`, the result will be equal to `rhs`. Will not go past `rhs`.
#[inline]
#[must_use]
pub fn move_towards(&self, rhs: Self, d: f32) -> Self {
let a = rhs - *self;
let len = a.length();
if len <= d || len <= 1e-4 {
return rhs;
}
*self + a / len * d
}

/// Calculates the midpoint between `self` and `rhs`.
///
/// The midpoint is the average of, or halfway point between, two vectors.
Expand Down
15 changes: 15 additions & 0 deletions src/f32/wasm32/vec3a.rs
Expand Up @@ -692,6 +692,21 @@ impl Vec3A {
self + ((rhs - self) * s)
}

/// Moves towards `rhs` based on the value `d`.
///
/// When `d` is `0.0`, the result will be equal to `self`. When `d` is equal to
/// `self.distance(rhs)`, the result will be equal to `rhs`. Will not go past `rhs`.
#[inline]
#[must_use]
pub fn move_towards(&self, rhs: Self, d: f32) -> Self {
let a = rhs - *self;
let len = a.length();
if len <= d || len <= 1e-4 {
return rhs;
}
*self + a / len * d
}

/// Calculates the midpoint between `self` and `rhs`.
///
/// The midpoint is the average of, or halfway point between, two vectors.
Expand Down
15 changes: 15 additions & 0 deletions src/f32/wasm32/vec4.rs
Expand Up @@ -678,6 +678,21 @@ impl Vec4 {
self + ((rhs - self) * s)
}

/// Moves towards `rhs` based on the value `d`.
///
/// When `d` is `0.0`, the result will be equal to `self`. When `d` is equal to
/// `self.distance(rhs)`, the result will be equal to `rhs`. Will not go past `rhs`.
#[inline]
#[must_use]
pub fn move_towards(&self, rhs: Self, d: f32) -> Self {
let a = rhs - *self;
let len = a.length();
if len <= d || len <= 1e-4 {
return rhs;
}
*self + a / len * d
}

/// Calculates the midpoint between `self` and `rhs`.
///
/// The midpoint is the average of, or halfway point between, two vectors.
Expand Down
15 changes: 15 additions & 0 deletions src/f64/dvec2.rs
Expand Up @@ -646,6 +646,21 @@ impl DVec2 {
self + ((rhs - self) * s)
}

/// Moves towards `rhs` based on the value `d`.
///
/// When `d` is `0.0`, the result will be equal to `self`. When `d` is equal to
/// `self.distance(rhs)`, the result will be equal to `rhs`. Will not go past `rhs`.
#[inline]
#[must_use]
pub fn move_towards(&self, rhs: Self, d: f64) -> Self {
let a = rhs - *self;
let len = a.length();
if len <= d || len <= 1e-4 {
return rhs;
}
*self + a / len * d
}

/// Calculates the midpoint between `self` and `rhs`.
///
/// The midpoint is the average of, or halfway point between, two vectors.
Expand Down
15 changes: 15 additions & 0 deletions src/f64/dvec3.rs
Expand Up @@ -705,6 +705,21 @@ impl DVec3 {
self + ((rhs - self) * s)
}

/// Moves towards `rhs` based on the value `d`.
///
/// When `d` is `0.0`, the result will be equal to `self`. When `d` is equal to
/// `self.distance(rhs)`, the result will be equal to `rhs`. Will not go past `rhs`.
#[inline]
#[must_use]
pub fn move_towards(&self, rhs: Self, d: f64) -> Self {
let a = rhs - *self;
let len = a.length();
if len <= d || len <= 1e-4 {
return rhs;
}
*self + a / len * d
}

/// Calculates the midpoint between `self` and `rhs`.
///
/// The midpoint is the average of, or halfway point between, two vectors.
Expand Down
15 changes: 15 additions & 0 deletions src/f64/dvec4.rs
Expand Up @@ -749,6 +749,21 @@ impl DVec4 {
self + ((rhs - self) * s)
}

/// Moves towards `rhs` based on the value `d`.
///
/// When `d` is `0.0`, the result will be equal to `self`. When `d` is equal to
/// `self.distance(rhs)`, the result will be equal to `rhs`. Will not go past `rhs`.
#[inline]
#[must_use]
pub fn move_towards(&self, rhs: Self, d: f64) -> Self {
let a = rhs - *self;
let len = a.length();
if len <= d || len <= 1e-4 {
return rhs;
}
*self + a / len * d
}

/// Calculates the midpoint between `self` and `rhs`.
///
/// The midpoint is the average of, or halfway point between, two vectors.
Expand Down
8 changes: 8 additions & 0 deletions tests/vec2.rs
Expand Up @@ -820,6 +820,14 @@ macro_rules! impl_vec2_float_tests {
assert_approx_eq!($vec2::ZERO, v0.lerp(v1, 0.5));
});

glam_test!(test_move_towards, {
let v0 = $vec2::new(-1.0, -1.0);
let v1 = $vec2::new(1.0, 1.0);
assert_approx_eq!(v0, v0.move_towards(v1, 0.0));
assert_approx_eq!(v1, v0.move_towards(v1, v0.distance(v1)));
assert_approx_eq!(v1, v0.move_towards(v1, v0.distance(v1) + 1.0));
});

glam_test!(test_midpoint, {
let v0 = $vec2::new(-1.0, -1.0);
let v1 = $vec2::new(1.0, 1.0);
Expand Down
8 changes: 8 additions & 0 deletions tests/vec3.rs
Expand Up @@ -955,6 +955,14 @@ macro_rules! impl_vec3_float_tests {
assert_approx_eq!($vec3::ZERO, v0.lerp(v1, 0.5));
});

glam_test!(test_move_towards, {
let v0 = $vec3::new(-1.0, -1.0, -1.0);
let v1 = $vec3::new(1.0, 1.0, 1.0);
assert_approx_eq!(v0, v0.move_towards(v1, 0.0));
assert_approx_eq!(v1, v0.move_towards(v1, v0.distance(v1)));
assert_approx_eq!(v1, v0.move_towards(v1, v0.distance(v1) + 1.0));
});

glam_test!(test_midpoint, {
let v0 = $vec3::new(-1.0, -1.0, -1.0);
let v1 = $vec3::new(1.0, 1.0, 1.0);
Expand Down
8 changes: 8 additions & 0 deletions tests/vec4.rs
Expand Up @@ -1075,6 +1075,14 @@ macro_rules! impl_vec4_float_tests {
assert_approx_eq!($vec4::ZERO, v0.lerp(v1, 0.5));
});

glam_test!(test_move_towards, {
let v0 = $vec4::new(-1.0, -1.0, -1.0, -1.0);
let v1 = $vec4::new(1.0, 1.0, 1.0, 1.0);
assert_approx_eq!(v0, v0.move_towards(v1, 0.0));
assert_approx_eq!(v1, v0.move_towards(v1, v0.distance(v1)));
assert_approx_eq!(v1, v0.move_towards(v1, v0.distance(v1) + 1.0));
});

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);
Expand Down

0 comments on commit 30948c4

Please sign in to comment.