2020-04-06 00:49:48 +08:00
use core ::mem ;
2018-09-20 16:50:34 +08:00
2019-03-23 21:29:07 +08:00
use crate ::aliases ::{ TMat , TVec } ;
2021-04-11 17:00:38 +08:00
use crate ::traits ::Number ;
2021-08-08 18:59:40 +08:00
use crate ::RealNumber ;
2018-09-20 16:50:34 +08:00
2018-09-22 19:18:59 +08:00
/// For each matrix or vector component `x` if `x >= 0`; otherwise, it returns `-x`.
2018-10-04 21:49:01 +08:00
///
/// # Examples:
///
/// ```
/// # use nalgebra_glm as glm;
/// let vec = glm::vec3(-1.0, 0.0, 2.0);
/// assert_eq!(glm::vec3(1.0, 0.0, 2.0), glm::abs(&vec));
///
/// let mat = glm::mat2(-0.0, 1.0, -3.0, 2.0);
/// assert_eq!(glm::mat2(0.0, 1.0, 3.0, 2.0), glm::abs(&mat));
/// ```
///
/// # See also:
///
2023-08-06 23:25:22 +08:00
/// * [`sign()`]
2021-04-11 17:00:38 +08:00
pub fn abs < T : Number , const R : usize , const C : usize > ( x : & TMat < T , R , C > ) -> TMat < T , R , C > {
2018-10-22 04:11:41 +08:00
x . abs ( )
2018-09-20 16:50:34 +08:00
}
2018-09-22 19:18:59 +08:00
/// For each matrix or vector component returns a value equal to the nearest integer that is greater than or equal to `x`.
2018-10-04 21:49:01 +08:00
///
/// # Examples:
///
/// ```
/// # use nalgebra_glm as glm;
/// let vec = glm::vec3(-1.5, 0.5, 2.8);
/// assert_eq!(glm::vec3(-1.0, 1.0, 3.0), glm::ceil(&vec));
/// ```
///
/// # See also:
///
2023-08-06 23:25:22 +08:00
/// * [`ceil()`]
/// * [`floor()`]
/// * [`fract()`]
/// * [`round()`]
/// * [`trunc()`]
2021-08-08 18:59:40 +08:00
pub fn ceil < T : RealNumber , const D : usize > ( x : & TVec < T , D > ) -> TVec < T , D > {
2018-09-21 01:54:12 +08:00
x . map ( | x | x . ceil ( ) )
2018-09-20 16:50:34 +08:00
}
2018-09-22 19:18:59 +08:00
/// Returns `min(max(x, min_val), max_val)`.
2018-10-04 21:49:01 +08:00
///
2018-10-06 22:22:46 +08:00
/// # Examples:
///
/// ```
/// # use nalgebra_glm as glm;
/// // Works with integers:
/// assert_eq!(3, glm::clamp_scalar(1, 3, 5));
/// assert_eq!(4, glm::clamp_scalar(4, 3, 5));
/// assert_eq!(5, glm::clamp_scalar(7, 3, 5));
///
/// // And it works with floats:
/// assert_eq!(3.25, glm::clamp_scalar(1.3, 3.25, 5.5));
/// assert_eq!(4.5, glm::clamp_scalar(4.5, 3.25, 5.5));
/// assert_eq!(5.5, glm::clamp_scalar(7.8, 3.25, 5.5));
/// ```
///
2018-10-04 21:49:01 +08:00
/// # See also:
///
2023-08-06 23:25:22 +08:00
/// * [`clamp()`]
/// * [`clamp_vec()`]
2021-04-11 17:00:38 +08:00
pub fn clamp_scalar < T : Number > ( x : T , min_val : T , max_val : T ) -> T {
2018-09-22 19:18:59 +08:00
na ::clamp ( x , min_val , max_val )
2018-09-20 16:50:34 +08:00
}
2018-10-06 22:22:46 +08:00
/// Returns `min(max(x[i], min_val), max_val)` for each component in `x`
/// using the values `min_val and `max_val` as bounds.
///
/// # Examples:
///
/// ```
/// # use nalgebra_glm as glm;
/// // Works with integers:
/// assert_eq!(glm::vec3(3, 4, 5),
/// glm::clamp(&glm::vec3(1, 4, 7), 3, 5));
///
/// // And it works with floats:
/// assert_eq!(glm::vec3(3.25, 4.5, 5.5),
/// glm::clamp(&glm::vec3(1.3, 4.5, 7.8), 3.25, 5.5));
/// ```
2018-10-04 21:49:01 +08:00
///
/// # See also:
///
2023-08-06 23:25:22 +08:00
/// * [`clamp_scalar()`]
/// * [`clamp_vec()`]
2021-04-11 17:00:38 +08:00
pub fn clamp < T : Number , const D : usize > ( x : & TVec < T , D > , min_val : T , max_val : T ) -> TVec < T , D > {
2018-09-22 19:18:59 +08:00
x . map ( | x | na ::clamp ( x , min_val , max_val ) )
2018-09-20 16:50:34 +08:00
}
2018-10-06 22:22:46 +08:00
/// Returns `min(max(x[i], min_val[i]), max_val[i])` for each component in `x`
/// using the components of `min_val` and `max_val` as bounds.
2018-10-04 21:49:01 +08:00
///
2018-10-07 12:31:41 +08:00
/// # Examples:
///
/// ```
/// # use nalgebra_glm as glm;
/// let min_bounds = glm::vec2(1.0, 3.0);
/// let max_bounds = glm::vec2(5.0, 6.0);
/// assert_eq!(glm::vec2(1.0, 6.0),
/// glm::clamp_vec(&glm::vec2(0.0, 7.0),
/// &min_bounds,
/// &max_bounds));
/// assert_eq!(glm::vec2(2.0, 6.0),
/// glm::clamp_vec(&glm::vec2(2.0, 7.0),
/// &min_bounds,
/// &max_bounds));
/// assert_eq!(glm::vec2(1.0, 4.0),
/// glm::clamp_vec(&glm::vec2(0.0, 4.0),
/// &min_bounds,
/// &max_bounds));
/// ```
///
2018-10-04 21:49:01 +08:00
/// # See also:
///
2023-08-06 23:25:22 +08:00
/// * [`clamp_scalar()`]
/// * [`clamp()`]
2021-04-11 17:00:38 +08:00
pub fn clamp_vec < T : Number , const D : usize > (
x : & TVec < T , D > ,
min_val : & TVec < T , D > ,
max_val : & TVec < T , D > ,
) -> TVec < T , D > {
2018-10-07 12:31:41 +08:00
x . zip_zip_map ( min_val , max_val , | a , min , max | na ::clamp ( a , min , max ) )
2018-09-20 16:50:34 +08:00
}
2018-09-22 19:18:59 +08:00
/// Returns a signed integer value representing the encoding of a floating-point value.
///
/// The floating-point value's bit-level representation is preserved.
2018-10-04 21:49:01 +08:00
///
/// # See also:
///
2023-08-06 23:25:22 +08:00
/// * [`float_bits_to_int_vec()`]
/// * [`float_bits_to_uint()`]
/// * [`float_bits_to_uint_vec()`]
/// * [`int_bits_to_float()`]
/// * [`int_bits_to_float_vec()`]
/// * [`uint_bits_to_float()`]
/// * [`uint_bits_to_float_scalar()`]
2018-09-21 01:54:12 +08:00
pub fn float_bits_to_int ( v : f32 ) -> i32 {
unsafe { mem ::transmute ( v ) }
2018-09-20 16:50:34 +08:00
}
2018-09-22 19:18:59 +08:00
/// Returns a signed integer value representing the encoding of each component of `v`.
///
/// The floating point value's bit-level representation is preserved.
2018-10-04 21:49:01 +08:00
///
/// # See also:
///
2023-08-06 23:25:22 +08:00
/// * [`float_bits_to_int()`]
/// * [`float_bits_to_uint()`]
/// * [`float_bits_to_uint_vec()`]
/// * [`int_bits_to_float()`]
/// * [`int_bits_to_float_vec()`]
/// * [`uint_bits_to_float()`]
/// * [`uint_bits_to_float_scalar()`]
2021-04-11 17:00:38 +08:00
pub fn float_bits_to_int_vec < const D : usize > ( v : & TVec < f32 , D > ) -> TVec < i32 , D > {
2018-10-05 11:15:17 +08:00
v . map ( float_bits_to_int )
2018-09-20 16:50:34 +08:00
}
2018-09-22 19:18:59 +08:00
/// Returns an unsigned integer value representing the encoding of a floating-point value.
///
/// The floating-point value's bit-level representation is preserved.
2018-10-04 21:49:01 +08:00
///
/// # See also:
///
2023-08-06 23:25:22 +08:00
/// * [`float_bits_to_int()`]
/// * [`float_bits_to_int_vec()`]
/// * [`float_bits_to_uint_vec()`]
/// * [`int_bits_to_float()`]
/// * [`int_bits_to_float_vec()`]
/// * [`uint_bits_to_float()`]
/// * [`uint_bits_to_float_scalar()`]
2018-09-21 01:54:12 +08:00
pub fn float_bits_to_uint ( v : f32 ) -> u32 {
unsafe { mem ::transmute ( v ) }
2018-09-20 16:50:34 +08:00
}
2018-09-22 19:18:59 +08:00
/// Returns an unsigned integer value representing the encoding of each component of `v`.
///
/// The floating point value's bit-level representation is preserved.
2018-10-04 21:49:01 +08:00
///
/// # See also:
///
2023-08-06 23:25:22 +08:00
/// * [`float_bits_to_int()`]
/// * [`float_bits_to_int_vec()`]
/// * [`float_bits_to_uint()`]
/// * [`int_bits_to_float()`]
/// * [`int_bits_to_float_vec()`]
/// * [`uint_bits_to_float()`]
/// * [`uint_bits_to_float_scalar()`]
2021-04-11 17:00:38 +08:00
pub fn float_bits_to_uint_vec < const D : usize > ( v : & TVec < f32 , D > ) -> TVec < u32 , D > {
2018-10-05 11:15:17 +08:00
v . map ( float_bits_to_uint )
2018-09-20 16:50:34 +08:00
}
2018-09-22 19:18:59 +08:00
/// Returns componentwise a value equal to the nearest integer that is less then or equal to `x`.
2018-10-04 21:49:01 +08:00
///
/// # Examples:
///
/// ```
/// # use nalgebra_glm as glm;
/// let vec = glm::vec3(-1.5, 0.5, 2.8);
/// assert_eq!(glm::vec3(-2.0, 0.0, 2.0), glm::floor(&vec));
/// ```
///
/// # See also:
///
2023-08-06 23:25:22 +08:00
/// * [`ceil()`]
/// * [`fract()`]
/// * [`round()`]
/// * [`trunc()`]
2021-08-08 18:59:40 +08:00
pub fn floor < T : RealNumber , const D : usize > ( x : & TVec < T , D > ) -> TVec < T , D > {
2018-09-21 01:54:12 +08:00
x . map ( | x | x . floor ( ) )
2018-09-20 16:50:34 +08:00
}
2020-11-15 23:57:49 +08:00
//// TODO: should be implemented for TVec/TMat?
2021-04-11 17:00:38 +08:00
//pub fn fma<T: Number>(a: T, b: T, c: T) -> T {
2020-11-15 23:57:49 +08:00
// // TODO: use an actual FMA
2018-09-22 19:18:59 +08:00
// a * b + c
//}
2018-09-20 16:50:34 +08:00
2018-09-22 19:18:59 +08:00
/// Returns the fractional part of each component of `x`.
2018-10-04 21:49:01 +08:00
///
/// # Examples:
///
/// ```
/// # use nalgebra_glm as glm;
/// let vec = glm::vec3(-1.5, 0.5, 2.25);
/// assert_eq!(glm::vec3(-0.5, 0.5, 0.25), glm::fract(&vec));
/// ```
///
/// # See also:
///
2023-08-06 23:25:22 +08:00
/// * [`ceil()`]
/// * [`floor()`]
/// * [`round()`]
/// * [`trunc()`]
2021-08-08 18:59:40 +08:00
pub fn fract < T : RealNumber , const D : usize > ( x : & TVec < T , D > ) -> TVec < T , D > {
2018-09-21 01:54:12 +08:00
x . map ( | x | x . fract ( ) )
2018-09-20 16:50:34 +08:00
}
2020-11-15 23:57:49 +08:00
//// TODO: should be implemented for TVec/TMat?
2018-09-21 01:54:12 +08:00
///// Returns the (significant, exponent) of this float number.
2021-08-08 18:59:40 +08:00
//pub fn frexp<T: RealNumber>(x: T, exp: T) -> (T, T) {
2020-11-15 23:57:49 +08:00
// // TODO: is there a better approach?
2018-09-21 01:54:12 +08:00
// let e = x.log2().ceil();
// (x * (-e).exp2(), e)
//}
2018-09-20 16:50:34 +08:00
2018-09-22 19:18:59 +08:00
/// Returns a floating-point value corresponding to a signed integer encoding of a floating-point value.
///
/// If an inf or NaN is passed in, it will not signal, and the resulting floating point value is unspecified. Otherwise, the bit-level representation is preserved.
2018-10-04 21:49:01 +08:00
///
/// # See also:
///
2023-08-06 23:25:22 +08:00
/// * [`float_bits_to_int()`]
/// * [`float_bits_to_int_vec()`]
/// * [`float_bits_to_uint()`]
/// * [`float_bits_to_uint_vec()`]
/// * [`int_bits_to_float_vec()`]
/// * [`uint_bits_to_float()`]
/// * [`uint_bits_to_float_scalar()`]
2018-09-21 01:54:12 +08:00
pub fn int_bits_to_float ( v : i32 ) -> f32 {
2018-10-05 13:28:32 +08:00
f32 ::from_bits ( v as u32 )
2018-09-20 16:50:34 +08:00
}
2018-09-22 19:18:59 +08:00
/// For each components of `v`, returns a floating-point value corresponding to a signed integer encoding of a floating-point value.
///
/// If an inf or NaN is passed in, it will not signal, and the resulting floating point value is unspecified. Otherwise, the bit-level representation is preserved.
2018-10-04 21:49:01 +08:00
///
/// # See also:
///
2023-08-06 23:25:22 +08:00
/// * [`float_bits_to_int()`]
/// * [`float_bits_to_int_vec()`]
/// * [`float_bits_to_uint()`]
/// * [`float_bits_to_uint_vec()`]
/// * [`int_bits_to_float()`]
/// * [`uint_bits_to_float()`]
/// * [`uint_bits_to_float_scalar()`]
2021-04-11 17:00:38 +08:00
pub fn int_bits_to_float_vec < const D : usize > ( v : & TVec < i32 , D > ) -> TVec < f32 , D > {
2018-10-05 11:15:17 +08:00
v . map ( int_bits_to_float )
2018-09-20 16:50:34 +08:00
}
2021-04-11 17:00:38 +08:00
//pub fn isinf<T: Scalar, const D: usize>(x: &TVec<T, D>) -> TVec<bool, D> {
2018-09-21 01:54:12 +08:00
// unimplemented!()
//
//}
//
2021-04-11 17:00:38 +08:00
//pub fn isnan<T: Scalar, const D: usize>(x: &TVec<T, D>) -> TVec<bool, D> {
2018-09-21 01:54:12 +08:00
// unimplemented!()
//
//}
2018-09-20 16:50:34 +08:00
2018-09-21 01:54:12 +08:00
///// Returns the (significant, exponent) of this float number.
2021-08-08 18:59:40 +08:00
//pub fn ldexp<T: RealNumber>(x: T, exp: T) -> T {
2020-11-15 23:57:49 +08:00
// // TODO: is there a better approach?
2018-09-21 01:54:12 +08:00
// x * (exp).exp2()
//}
2018-10-22 04:11:41 +08:00
/// Returns `x * (1.0 - a) + y * a`, i.e., the linear blend of the scalars x and y using the scalar value a.
///
/// The value for a is not restricted to the range `[0, 1]`.
///
/// # Examples:
///
/// ```
/// # use nalgebra_glm as glm;
/// assert_eq!(glm::mix_scalar(2.0, 20.0, 0.1), 3.8);
/// ```
///
/// # See also:
///
2023-08-06 23:25:22 +08:00
/// * [`mix()`]
/// * [`mix_vec()`]
2021-04-11 17:00:38 +08:00
pub fn mix_scalar < T : Number > ( x : T , y : T , a : T ) -> T {
x * ( T ::one ( ) - a ) + y * a
2018-10-22 04:11:41 +08:00
}
/// Returns `x * (1.0 - a) + y * a`, i.e., the linear blend of the vectors x and y using the scalar value a.
2018-09-22 19:18:59 +08:00
///
/// The value for a is not restricted to the range `[0, 1]`.
2018-10-22 04:11:41 +08:00
///
/// # Examples:
///
/// ```
/// # use nalgebra_glm as glm;
/// let x = glm::vec3(1.0, 2.0, 3.0);
/// let y = glm::vec3(10.0, 20.0, 30.0);
/// assert_eq!(glm::mix(&x, &y, 0.1), glm::vec3(1.9, 3.8, 5.7));
/// ```
///
/// # See also:
///
2023-08-06 23:25:22 +08:00
/// * [`mix_scalar()`]
/// * [`mix_vec()`]
2021-04-11 17:00:38 +08:00
pub fn mix < T : Number , const D : usize > ( x : & TVec < T , D > , y : & TVec < T , D > , a : T ) -> TVec < T , D > {
x * ( T ::one ( ) - a ) + y * a
2018-09-20 16:50:34 +08:00
}
2018-10-22 04:11:41 +08:00
/// Returns `x * (1.0 - a) + y * a`, i.e., the component-wise linear blend of `x` and `y` using the components of
/// the vector `a` as coefficients.
///
/// The value for a is not restricted to the range `[0, 1]`.
///
/// # Examples:
///
/// ```
/// # use nalgebra_glm as glm;
/// let x = glm::vec3(1.0, 2.0, 3.0);
/// let y = glm::vec3(10.0, 20.0, 30.0);
/// let a = glm::vec3(0.1, 0.2, 0.3);
/// assert_eq!(glm::mix_vec(&x, &y, &a), glm::vec3(1.9, 5.6, 11.1));
/// ```
///
/// # See also:
///
2023-08-06 23:25:22 +08:00
/// * [`mix_scalar()`]
/// * [`mix()`]
2021-04-11 17:00:38 +08:00
pub fn mix_vec < T : Number , const D : usize > (
x : & TVec < T , D > ,
y : & TVec < T , D > ,
a : & TVec < T , D > ,
) -> TVec < T , D > {
2023-08-19 01:23:26 +08:00
x . component_mul ( & ( TVec ::< T , D > ::repeat ( T ::one ( ) ) - a ) ) + y . component_mul ( a )
2018-10-22 04:11:41 +08:00
}
/// Returns `x * (1.0 - a) + y * a`, i.e., the linear blend of the scalars x and y using the scalar value a.
///
/// The value for a is not restricted to the range `[0, 1]`.
/// This is an alias for `mix_scalar`.
///
/// # Examples:
///
/// ```
/// # use nalgebra_glm as glm;
/// assert_eq!(glm::lerp_scalar(2.0, 20.0, 0.1), 3.8);
/// ```
///
/// # See also:
///
2023-08-06 23:25:22 +08:00
/// * [`lerp()`]
/// * [`lerp_vec()`]
2021-04-11 17:00:38 +08:00
pub fn lerp_scalar < T : Number > ( x : T , y : T , a : T ) -> T {
2018-10-22 04:11:41 +08:00
mix_scalar ( x , y , a )
}
/// Returns `x * (1.0 - a) + y * a`, i.e., the linear blend of the vectors x and y using the scalar value a.
///
/// The value for a is not restricted to the range `[0, 1]`.
/// This is an alias for `mix`.
///
/// # Examples:
///
/// ```
/// # use nalgebra_glm as glm;
/// let x = glm::vec3(1.0, 2.0, 3.0);
/// let y = glm::vec3(10.0, 20.0, 30.0);
/// assert_eq!(glm::lerp(&x, &y, 0.1), glm::vec3(1.9, 3.8, 5.7));
/// ```
///
/// # See also:
///
2023-08-06 23:25:22 +08:00
/// * [`lerp_scalar()`]
/// * [`lerp_vec()`]
2021-04-11 17:00:38 +08:00
pub fn lerp < T : Number , const D : usize > ( x : & TVec < T , D > , y : & TVec < T , D > , a : T ) -> TVec < T , D > {
2018-10-22 04:11:41 +08:00
mix ( x , y , a )
}
/// Returns `x * (1.0 - a) + y * a`, i.e., the component-wise linear blend of `x` and `y` using the components of
/// the vector `a` as coefficients.
///
/// The value for a is not restricted to the range `[0, 1]`.
/// This is an alias for `mix_vec`.
///
/// # Examples:
///
/// ```
/// # use nalgebra_glm as glm;
/// let x = glm::vec3(1.0, 2.0, 3.0);
/// let y = glm::vec3(10.0, 20.0, 30.0);
/// let a = glm::vec3(0.1, 0.2, 0.3);
/// assert_eq!(glm::lerp_vec(&x, &y, &a), glm::vec3(1.9, 5.6, 11.1));
/// ```
///
/// # See also:
///
2023-08-06 23:25:22 +08:00
/// * [`lerp_scalar()`]
/// * [`lerp()`]
2021-04-11 17:00:38 +08:00
pub fn lerp_vec < T : Number , const D : usize > (
x : & TVec < T , D > ,
y : & TVec < T , D > ,
a : & TVec < T , D > ,
) -> TVec < T , D > {
2018-10-22 04:11:41 +08:00
mix_vec ( x , y , a )
}
2018-09-22 19:21:02 +08:00
/// Component-wise modulus.
2018-09-22 19:18:59 +08:00
///
/// Returns `x - y * floor(x / y)` for each component in `x` using the corresponding component of `y`.
2018-10-04 21:49:01 +08:00
///
/// # See also:
///
2023-08-06 23:25:22 +08:00
/// * [`modf()`]
2021-04-11 17:00:38 +08:00
pub fn modf_vec < T : Number , const D : usize > ( x : & TVec < T , D > , y : & TVec < T , D > ) -> TVec < T , D > {
2018-09-21 01:54:12 +08:00
x . zip_map ( y , | x , y | x % y )
2018-09-20 16:50:34 +08:00
}
2018-09-22 19:18:59 +08:00
/// Modulus between two values.
2018-10-04 21:49:01 +08:00
///
/// # See also:
///
2023-08-06 23:25:22 +08:00
/// * [`modf_vec()`]
2021-04-11 17:00:38 +08:00
pub fn modf < T : Number > ( x : T , i : T ) -> T {
2018-09-21 01:54:12 +08:00
x % i
2018-09-20 16:50:34 +08:00
}
2018-09-22 19:21:02 +08:00
/// Component-wise rounding.
2018-09-22 19:18:59 +08:00
///
/// Values equal to `0.5` are rounded away from `0.0`.
2018-10-04 21:49:01 +08:00
///
/// # Examples:
///
/// ```
/// # use nalgebra_glm as glm;
/// let vec = glm::vec4(-1.5, 0.6, 1.5, -3.2);
/// assert_eq!(glm::vec4(-2.0, 1.0, 2.0, -3.0), glm::round(&vec));
/// ```
///
/// # See also:
///
2023-08-06 23:25:22 +08:00
/// * [`ceil()`]
/// * [`floor()`]
/// * [`fract()`]
/// * [`trunc()`]
2021-08-08 18:59:40 +08:00
pub fn round < T : RealNumber , const D : usize > ( x : & TVec < T , D > ) -> TVec < T , D > {
2018-09-21 01:54:12 +08:00
x . map ( | x | x . round ( ) )
2018-09-20 16:50:34 +08:00
}
2021-04-11 17:00:38 +08:00
//pub fn roundEven<T: Scalar, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
2018-09-21 01:54:12 +08:00
// unimplemented!()
//}
2018-09-20 16:50:34 +08:00
2018-10-05 11:54:52 +08:00
/// For each vector component `x`: 1 if `x > 0`, 0 if `x == 0`, or -1 if `x < 0`.
2018-10-05 03:04:37 +08:00
///
/// # Examples:
///
/// ```
/// # use nalgebra_glm as glm;
2018-10-06 22:20:57 +08:00
/// let vec = glm::vec4(-2.0, 0.0, -0.0, 2.0);
/// assert_eq!(glm::vec4(-1.0, 0.0, 0.0, 1.0), glm::sign(&vec));
2018-10-05 03:04:37 +08:00
/// ```
///
/// # See also:
///
2023-08-06 23:25:22 +08:00
/// * [`abs()`]
2018-10-05 03:04:37 +08:00
///
2021-04-11 17:00:38 +08:00
pub fn sign < T : Number , const D : usize > ( x : & TVec < T , D > ) -> TVec < T , D > {
x . map ( | x | if x . is_zero ( ) { T ::zero ( ) } else { x . signum ( ) } )
2018-09-20 16:50:34 +08:00
}
2018-09-22 19:18:59 +08:00
/// Returns 0.0 if `x <= edge0` and `1.0 if x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`.
///
/// This is useful in cases where you would want a threshold function with a smooth transition.
/// This is equivalent to: `let result = clamp((x - edge0) / (edge1 - edge0), 0, 1); return t * t * (3 - 2 * t);` Results are undefined if `edge0 >= edge1`.
2021-08-08 19:05:13 +08:00
pub fn smoothstep < T : RealNumber > ( edge0 : T , edge1 : T , x : T ) -> T {
2021-08-08 18:59:40 +08:00
let _3 = T ::from_subset ( & 3.0 f64 ) ;
let _2 = T ::from_subset ( & 2.0 f64 ) ;
2021-04-11 17:00:38 +08:00
let t = na ::clamp ( ( x - edge0 ) / ( edge1 - edge0 ) , T ::zero ( ) , T ::one ( ) ) ;
2018-09-21 01:54:12 +08:00
t * t * ( _3 - t * _2 )
2018-09-20 16:50:34 +08:00
}
2018-09-22 19:18:59 +08:00
/// Returns 0.0 if `x < edge`, otherwise it returns 1.0.
2021-04-11 17:00:38 +08:00
pub fn step_scalar < T : Number > ( edge : T , x : T ) -> T {
2018-09-21 01:54:12 +08:00
if edge > x {
2021-04-11 17:00:38 +08:00
T ::zero ( )
2018-09-21 01:54:12 +08:00
} else {
2021-04-11 17:00:38 +08:00
T ::one ( )
2018-09-21 01:54:12 +08:00
}
2018-09-20 16:50:34 +08:00
}
2018-09-22 23:36:08 +08:00
2018-09-22 19:18:59 +08:00
/// Returns 0.0 if `x[i] < edge`, otherwise it returns 1.0.
2021-04-11 17:00:38 +08:00
pub fn step < T : Number , const D : usize > ( edge : T , x : & TVec < T , D > ) -> TVec < T , D > {
2018-09-22 23:36:08 +08:00
x . map ( | x | step_scalar ( edge , x ) )
2018-09-20 16:50:34 +08:00
}
2018-09-22 19:18:59 +08:00
/// Returns 0.0 if `x[i] < edge[i]`, otherwise it returns 1.0.
2021-04-11 17:00:38 +08:00
pub fn step_vec < T : Number , const D : usize > ( edge : & TVec < T , D > , x : & TVec < T , D > ) -> TVec < T , D > {
2018-10-05 11:15:17 +08:00
edge . zip_map ( x , step_scalar )
2018-09-20 16:50:34 +08:00
}
2018-09-22 19:18:59 +08:00
/// Returns a value equal to the nearest integer to `x` whose absolute value is not larger than the absolute value of `x`.
2018-10-04 21:49:01 +08:00
///
/// # Examples:
///
/// ```
/// # use nalgebra_glm as glm;
/// let vec = glm::vec3(-1.5, 0.5, 2.8);
/// assert_eq!(glm::vec3(-1.0, 0.0, 2.0), glm::trunc(&vec));
/// ```
///
/// # See also:
///
2023-08-06 23:25:22 +08:00
/// * [`ceil()`]
/// * [`floor()`]
/// * [`fract()`]
/// * [`round()`]
2021-08-08 18:59:40 +08:00
pub fn trunc < T : RealNumber , const D : usize > ( x : & TVec < T , D > ) -> TVec < T , D > {
2018-09-21 01:54:12 +08:00
x . map ( | x | x . trunc ( ) )
2018-09-20 16:50:34 +08:00
}
2018-09-22 19:18:59 +08:00
/// Returns a floating-point value corresponding to a unsigned integer encoding of a floating-point value.
///
/// If an `inf` or `NaN` is passed in, it will not signal, and the resulting floating point value is unspecified. Otherwise, the bit-level representation is preserved.
2018-10-04 21:49:01 +08:00
///
/// # See also:
///
2023-08-06 23:25:22 +08:00
/// * [`float_bits_to_int()`]
/// * [`float_bits_to_int_vec()`]
/// * [`float_bits_to_uint()`]
/// * [`float_bits_to_uint_vec()`]
/// * [`int_bits_to_float()`]
/// * [`int_bits_to_float_vec()`]
/// * [`uint_bits_to_float()`]
2018-09-22 23:36:08 +08:00
pub fn uint_bits_to_float_scalar ( v : u32 ) -> f32 {
2018-10-05 13:28:32 +08:00
f32 ::from_bits ( v )
2018-09-20 16:50:34 +08:00
}
2018-09-22 19:18:59 +08:00
/// For each component of `v`, returns a floating-point value corresponding to a unsigned integer encoding of a floating-point value.
///
/// If an inf or NaN is passed in, it will not signal, and the resulting floating point value is unspecified. Otherwise, the bit-level representation is preserved.
2018-10-04 21:49:01 +08:00
///
/// # See also:
///
2023-08-06 23:25:22 +08:00
/// * [`float_bits_to_int()`]
/// * [`float_bits_to_int_vec()`]
/// * [`float_bits_to_uint()`]
/// * [`float_bits_to_uint_vec()`]
/// * [`int_bits_to_float()`]
/// * [`int_bits_to_float_vec()`]
/// * [`uint_bits_to_float_scalar()`]
2021-04-11 17:00:38 +08:00
pub fn uint_bits_to_float < const D : usize > ( v : & TVec < u32 , D > ) -> TVec < f32 , D > {
2018-10-05 11:15:17 +08:00
v . map ( uint_bits_to_float_scalar )
2018-10-04 21:49:01 +08:00
}