Plane-constrained translation handles

This commit is contained in:
Danny McGee
2023-10-11 20:48:21 -04:00
parent fef5840343
commit 7d121af4a1
5 changed files with 127 additions and 39 deletions
+54
View File
@@ -0,0 +1,54 @@
use std::ops;
use super::NearlyEq;
pub trait Lerp {
fn lerp(self, a: Self, b: Self) -> Self;
fn inv_lerp(self, a: Self, b: Self) -> Self;
fn remap(self, from: (Self, Self), to: (Self, Self)) -> Self
where
Self: Sized;
}
#[rustfmt::skip] trait One { fn one() -> Self; }
#[rustfmt::skip] impl One for f32 { fn one() -> Self { 1. } }
#[rustfmt::skip] impl One for f64 { fn one() -> Self { 1_f64 } }
#[rustfmt::skip] trait Zero { fn zero() -> Self; }
#[rustfmt::skip] impl Zero for f32 { fn zero() -> Self { 0. } }
#[rustfmt::skip] impl Zero for f64 { fn zero() -> Self { 0_f64 } }
// lol it would have been faster and less code to just copy/paste. At least I tried.
impl<T> Lerp for T
where
T: ops::Add<Output = T>
+ ops::Sub<Output = T>
+ ops::Mul<Output = T>
+ ops::Div<Output = T>
+ NearlyEq<T>
+ One
+ Zero
+ Sized
+ Copy,
{
fn lerp(self, a: Self, b: Self) -> Self {
(<Self as One>::one() - self) * a + b * self
}
fn inv_lerp(self, a: Self, b: Self) -> Self {
let dividend = b - a;
if !dividend.nearly_eq(<Self as Zero>::zero()) {
(self - a) / dividend
} else {
b
}
}
fn remap(self, from: (Self, Self), to: (Self, Self)) -> Self
where
Self: Sized,
{
let t = self.inv_lerp(from.0, from.1);
t.lerp(to.0, to.1)
}
}