work
This commit is contained in:
parent
3d3ffbf79a
commit
78bc7aa8a1
@ -1,6 +1,6 @@
|
|||||||
use bnum::cast::As;
|
use bnum::cast::As;
|
||||||
use bnum::types::{I256,I512};
|
use bnum::types::{I256,I512};
|
||||||
use fixed::FixedI128;
|
use fixed::{FixedI64,FixedI128};
|
||||||
use typenum::{Sum,Unsigned};
|
use typenum::{Sum,Unsigned};
|
||||||
|
|
||||||
#[derive(Clone,Copy,Debug)]
|
#[derive(Clone,Copy,Debug)]
|
||||||
@ -33,6 +33,16 @@ pub trait WideMul<Rhs=Self>{
|
|||||||
}
|
}
|
||||||
|
|
||||||
//going wide from foreign fixed type
|
//going wide from foreign fixed type
|
||||||
|
impl<A,B> WideMul<FixedI64<B>> for FixedI64<A>
|
||||||
|
where
|
||||||
|
A:std::ops::Add<B>,
|
||||||
|
B:Unsigned,
|
||||||
|
{
|
||||||
|
type Output=FixedI128<Sum<A,B>>;
|
||||||
|
fn wide_mul(self,rhs:FixedI64<B>)->Self::Output{
|
||||||
|
self.wide_mul(rhs)
|
||||||
|
}
|
||||||
|
}
|
||||||
impl<A,B> WideMul<FixedI128<B>> for FixedI128<A>
|
impl<A,B> WideMul<FixedI128<B>> for FixedI128<A>
|
||||||
where
|
where
|
||||||
A:std::ops::Add<B>,
|
A:std::ops::Add<B>,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Stolen from https://github.com/c1m50c/fixed-vectors (MIT license)
|
// Stolen from https://github.com/c1m50c/fixed-vectors (MIT license)
|
||||||
mod wide;
|
pub mod wide;
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[macro_export(local_inner_macros)]
|
#[macro_export(local_inner_macros)]
|
||||||
@ -196,7 +196,7 @@ macro_rules! impl_vector {
|
|||||||
$crate::impl_operator!( $struct { $($field), + }, BitXor, bitxor, Self );
|
$crate::impl_operator!( $struct { $($field), + }, BitXor, bitxor, Self );
|
||||||
|
|
||||||
// Impl floating-point based methods
|
// Impl floating-point based methods
|
||||||
//$crate::impl_floating_point_operations!( $struct { $($field), + }, $size );
|
$crate::impl_wide_operations!( $struct { $($field), + }, $size );
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,281 +1,32 @@
|
|||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[macro_export(local_inner_macros)]
|
#[macro_export(local_inner_macros)]
|
||||||
macro_rules! impl_floating_point_operations {
|
macro_rules! impl_wide_operations {
|
||||||
( $struct: ident { $($field: ident), + }, $size: expr ) => {
|
( $struct: ident { $($field: ident), + }, $size: expr ) => {
|
||||||
impl<T: num_traits::float::FloatCore> $struct<T> {
|
impl<U,T:Copy+fixed_wide::wide::WideMul<Output=U>> fixed_wide::wide::WideMul for $struct<T> {
|
||||||
/// Returns the dot product of two vectors.
|
type Output=$struct<U>;
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use fixed_vectors::Vector2;
|
|
||||||
///
|
|
||||||
/// let a = Vector2::new(1.0, 2.0);
|
|
||||||
/// let b = Vector2::new(2.0, 4.0);
|
|
||||||
/// let dot = a.dot(&b);
|
|
||||||
///
|
|
||||||
/// assert_eq!(dot, 10.0);
|
|
||||||
/// ```
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn dot(&self, other: &Self) -> T {
|
fn wide_mul(self, rhs: Self) -> Self::Output {
|
||||||
|
$struct{
|
||||||
|
$( $field: self.$field.wide_mul(rhs.$field) ), +
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<T:Copy+fixed_wide::wide::WideMul<Output=T>+std::ops::Add<Output=T>> $struct<T> {
|
||||||
|
#[inline]
|
||||||
|
pub fn wide_dot(&self, other: &Self) -> <T as fixed_wide::wide::WideMul>::Output {
|
||||||
$crate::sum_repeating!(
|
$crate::sum_repeating!(
|
||||||
$( + (self.$field * other.$field) ) +
|
$( + (self.$field.wide_mul(other.$field)) ) +
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
pub fn length_squared(&self) -> <T as fixed_wide::wide::WideMul>::Output {
|
||||||
/// Returns the squared magnitude of vector.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use fixed_vectors::Vector3;
|
|
||||||
///
|
|
||||||
/// let vec3 = Vector3::new(3.33, 2.04, 1.337);
|
|
||||||
/// let lsq = vec3.length_squared();
|
|
||||||
///
|
|
||||||
/// assert!(lsq >= 17.0);
|
|
||||||
/// ```
|
|
||||||
pub fn length_squared(&self) -> T {
|
|
||||||
let squared = Self {
|
let squared = Self {
|
||||||
$( $field: self.$field * self.$field ), +
|
$( $field: self.$field.wide_mul(self.$field) ), +
|
||||||
};
|
};
|
||||||
|
|
||||||
$crate::sum_repeating!(
|
$crate::sum_repeating!(
|
||||||
$( + squared.$field ) +
|
$( + squared.$field ) +
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Applies [`floor`](num_traits::float::FloatCore::floor) on all fields within the vector,
|
|
||||||
/// converting each field to the largest integer less than or equal to its value.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use fixed_vectors::Vector2;
|
|
||||||
///
|
|
||||||
/// let vec2 = Vector2::new(1.6, 2.3).floor();
|
|
||||||
///
|
|
||||||
/// assert_eq!(vec2, Vector2::new(1.0, 2.0));
|
|
||||||
/// ```
|
|
||||||
#[inline]
|
|
||||||
pub fn floor(self) -> Self {
|
|
||||||
self.map(T::floor)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Applies [`ceil`](num_traits::float::FloatCore::ceil) on all fields within the vector,
|
|
||||||
/// converting each field to the largest integer greater than or equal to its value.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use fixed_vectors::Vector2;
|
|
||||||
///
|
|
||||||
/// let vec2 = Vector2::new(1.6, 2.3).ceil();
|
|
||||||
///
|
|
||||||
/// assert_eq!(vec2, Vector2::new(2.0, 3.0));
|
|
||||||
/// ```
|
|
||||||
#[inline]
|
|
||||||
pub fn ceil(self) -> Self {
|
|
||||||
self.map(T::ceil)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Applies [`round`](num_traits::float::FloatCore::round) on all fields within the vector,
|
|
||||||
/// converting each field's value to its nearest integer.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use fixed_vectors::Vector2;
|
|
||||||
///
|
|
||||||
/// let vec2 = Vector2::new(1.6, 2.3).round();
|
|
||||||
///
|
|
||||||
/// assert_eq!(vec2, Vector2::new(2.0, 2.0));
|
|
||||||
/// ```
|
|
||||||
#[inline]
|
|
||||||
pub fn round(self) -> Self {
|
|
||||||
self.map(T::round)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Applies [`abs`](num_traits::float::FloatCore::abs) on all fields within the vector,
|
|
||||||
/// converting each field to their absolute value.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use fixed_vectors::Vector2;
|
|
||||||
///
|
|
||||||
/// let vec2 = Vector2::new(-2.6, 2.3).abs();
|
|
||||||
///
|
|
||||||
/// assert_eq!(vec2, Vector2::new(2.6, 2.3));
|
|
||||||
/// ```
|
|
||||||
#[inline]
|
|
||||||
pub fn abs(self) -> Self {
|
|
||||||
self.map(T::abs)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Applies [`trunc`](num_traits::float::FloatCore::trunc) on all fields within the vector,
|
|
||||||
/// converting each field's value to their integer parts.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use fixed_vectors::Vector2;
|
|
||||||
///
|
|
||||||
/// let vec2 = Vector2::new(-2.6, 2.3).trunc();
|
|
||||||
///
|
|
||||||
/// assert_eq!(vec2, Vector2::new(-2.0, 2.0));
|
|
||||||
/// ```
|
|
||||||
#[inline]
|
|
||||||
pub fn trunc(self) -> Self {
|
|
||||||
self.map(T::trunc)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Applies [`fract`](num_traits::float::FloatCore::fract) on all fields within the vector,
|
|
||||||
/// converting each field's value to their fractional parts.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use fixed_vectors::Vector2;
|
|
||||||
///
|
|
||||||
/// let vec2 = Vector2::new(-2.5, 2.25).fract();
|
|
||||||
///
|
|
||||||
/// assert_eq!(vec2, Vector2::new(-0.5, 0.25));
|
|
||||||
/// ```
|
|
||||||
#[inline]
|
|
||||||
pub fn fract(self) -> Self {
|
|
||||||
self.map(T::fract)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Applies [`powi`](num_traits::float::FloatCore::powi) on all fields within the vector,
|
|
||||||
/// raising each field's value to an integer power.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use fixed_vectors::Vector2;
|
|
||||||
///
|
|
||||||
/// let vec2 = Vector2::new(2.0, 4.0).powi(2);
|
|
||||||
///
|
|
||||||
/// assert_eq!(vec2, Vector2::new(4.0, 16.0));
|
|
||||||
/// ```
|
|
||||||
#[inline]
|
|
||||||
pub fn powi(self, n: i32) -> Self {
|
|
||||||
self.map(|f| f.powi(n))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Linearly interpolates between two Vectors by a normalized `weight`.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use fixed_vectors::Vector2;
|
|
||||||
///
|
|
||||||
/// let vec2 = Vector2::new(1.0, 2.0).lerp(
|
|
||||||
/// Vector2::new(2.0, 3.0), 1.0
|
|
||||||
/// );
|
|
||||||
///
|
|
||||||
/// assert_eq!(vec2, Vector2::new(2.0, 3.0));
|
|
||||||
/// ```
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn lerp(self, to: Self, weight: T) -> Self {
|
|
||||||
Self {
|
|
||||||
$( $field: self.$field + (weight * (to.$field - self.$field)) ), +
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> $struct<T>
|
|
||||||
where
|
|
||||||
T: $crate::macros::floating::_FloatingPoint
|
|
||||||
+ num_traits::float::FloatCore
|
|
||||||
{
|
|
||||||
/// Consumes the vector and returns it with all of its fields converted to their square-root.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use fixed_vectors::Vector2;
|
|
||||||
///
|
|
||||||
/// let vec2 = Vector2::new(64.0, 25.0).sqrt();
|
|
||||||
///
|
|
||||||
/// assert_eq!(vec2, Vector2::new(8.0, 5.0));
|
|
||||||
/// ```
|
|
||||||
#[inline]
|
|
||||||
pub fn sqrt(self) -> Self {
|
|
||||||
self.map(T::sqrt)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the magnitude of the vector.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use fixed_vectors::Vector3;
|
|
||||||
///
|
|
||||||
/// let vec3 = Vector3::new(1.5, 2.0, 3.33);
|
|
||||||
/// let length = vec3.length();
|
|
||||||
///
|
|
||||||
/// assert!(length < 4.2);
|
|
||||||
/// ```
|
|
||||||
#[inline]
|
|
||||||
pub fn length(&self) -> T {
|
|
||||||
self.length_squared().sqrt()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Consumes the vector and returns it as normalized vector.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use fixed_vectors::Vector2;
|
|
||||||
///
|
|
||||||
/// let vec2 = Vector2::new(14.3, 7.9).normalized();
|
|
||||||
///
|
|
||||||
/// assert!(vec2.x < 1.0);
|
|
||||||
/// assert!(vec2.y < 1.0);
|
|
||||||
/// ```
|
|
||||||
pub fn normalized(self) -> Self {
|
|
||||||
let length_squared = self.length_squared();
|
|
||||||
|
|
||||||
if length_squared == T::zero() {
|
|
||||||
return Self { $( $field: T::zero() ), + };
|
|
||||||
}
|
|
||||||
|
|
||||||
let length = length_squared.sqrt();
|
|
||||||
|
|
||||||
Self {
|
|
||||||
$( $field: self.$field / length ), +
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Normalizes the vector through mutation.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use fixed_vectors::Vector2;
|
|
||||||
///
|
|
||||||
/// let mut vec2 = Vector2::new(14.3, 7.9);
|
|
||||||
/// vec2.normalize();
|
|
||||||
///
|
|
||||||
/// assert!(vec2.x < 1.0);
|
|
||||||
/// assert!(vec2.y < 1.0);
|
|
||||||
/// ```
|
|
||||||
pub fn normalize(&mut self) {
|
|
||||||
let length_squared = self.length_squared();
|
|
||||||
|
|
||||||
if length_squared == T::zero() {
|
|
||||||
*self = Self { $( $field: T::zero() ), + };
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let length = length_squared.sqrt();
|
|
||||||
|
|
||||||
*self = Self {
|
|
||||||
$( $field: self.$field / length ), +
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -290,26 +41,3 @@ macro_rules! sum_repeating {
|
|||||||
$($item) *
|
$($item) *
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Required trait for `sqrt` impls
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub trait _FloatingPoint {
|
|
||||||
fn sqrt(self) -> Self;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
impl _FloatingPoint for f32 {
|
|
||||||
#[inline(always)]
|
|
||||||
fn sqrt(self) -> Self {
|
|
||||||
libm::sqrtf(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
impl _FloatingPoint for f64 {
|
|
||||||
#[inline(always)]
|
|
||||||
fn sqrt(self) -> Self {
|
|
||||||
libm::sqrt(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -18,7 +18,7 @@ fn it_works() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn main(){
|
pub fn wide_vec3(){
|
||||||
let max=i32::MAX as i64;
|
let v=crate::vector::Vector3::from_value(Planar64::from(1));
|
||||||
println!("{} {}",max*max,i64::MAX);
|
let v1=v.wide_mul(v);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user