Skip to main content

flake/misc/
math.rs

1#![allow(unused)]
2pub use cgmath::num_traits::*;
3pub use cgmath::prelude::*;
4pub use std::ops::Neg;
5
6pub type Vector2 = cgmath::Vector2<f32>;
7pub type Vector3 = cgmath::Vector3<f32>;
8pub type Vector4 = cgmath::Vector4<f32>;
9pub type Quaternion = cgmath::Quaternion<f32>;
10
11pub trait FlakeMath: Sized {
12    fn normalize_or_zero(&self) -> Self;
13    fn one() -> Self;
14    fn neg_one() -> Self;
15}
16
17impl<T> FlakeMath for T
18where
19    T: InnerSpace + Array<Element = <T as VectorSpace>::Scalar> + Copy,
20    T::Scalar: cgmath::BaseFloat,
21{
22    fn normalize_or_zero(&self) -> Self {
23        if self.magnitude2().is_zero() {
24            Self::zero()
25        } else {
26            self.normalize()
27        }
28    }
29
30    fn one() -> Self {
31        Self::from_value(T::Scalar::one())
32    }
33
34    fn neg_one() -> Self {
35        Self::from_value(T::Scalar::neg(T::Scalar::one()))
36    }
37}
38
39pub trait FlakeVector2Ext {
40    /// Returns the radian angle [-π, π] of this vector relative to (1, 0)
41    fn angle_rad(&self) -> f32;
42
43    /// Returns the radian direction looking from this point toward a target point
44    fn angle_towards(&self, target: Vector2) -> f32;
45}
46
47impl FlakeVector2Ext for Vector2 {
48    fn angle_rad(&self) -> f32 {
49        self.y.atan2(self.x)
50    }
51
52    fn angle_towards(&self, target: Vector2) -> f32 {
53        (target - *self).angle_rad()
54    }
55}
56
57use std::ops::{Add, Div, Mul, Sub};
58
59pub trait Number:
60    Copy
61    + PartialOrd
62    + Add<Output = Self>
63    + Sub<Output = Self>
64    + Mul<Output = Self>
65    + Div<Output = Self>
66{
67    fn to_f32(self) -> f32;
68    fn zero() -> Self;
69    fn one() -> Self;
70}
71
72pub fn lerp<T: Copy + Sub + Add<<<T as Sub>::Output as Mul<f32>>::Output, Output = T>>(
73    a: T,
74    b: T,
75    t: f32,
76) -> T
77where
78    <T as Sub>::Output: Mul<f32>,
79{
80    a + (b - a) * t
81}
82
83macro_rules! impl_number {
84    ($($t:ty),*) => {
85        $(impl Number for $t {
86            fn to_f32(self) -> f32 { self as f32 }
87            fn zero() -> Self { 0 as $t }
88            fn one() -> Self { 1 as $t }
89        })*
90    };
91}
92
93impl_number!(f32, f64, i8, i16, i32, i64, u8, u16, u32, u64, usize, isize);