nalgebra_glm/
common.rs

1use core::mem;
2
3use crate::RealNumber;
4use crate::aliases::{TMat, TVec};
5use crate::traits::Number;
6
7/// For each matrix or vector component `x` if `x >= 0`; otherwise, it returns `-x`.
8///
9/// # Examples:
10///
11/// ```
12/// # use nalgebra_glm as glm;
13/// let vec = glm::vec3(-1.0, 0.0, 2.0);
14/// assert_eq!(glm::vec3(1.0, 0.0, 2.0), glm::abs(&vec));
15///
16/// let mat = glm::mat2(-0.0, 1.0, -3.0, 2.0);
17/// assert_eq!(glm::mat2(0.0, 1.0, 3.0, 2.0), glm::abs(&mat));
18/// ```
19///
20/// # See also:
21///
22/// * [`sign()`]
23pub fn abs<T: Number, const R: usize, const C: usize>(x: &TMat<T, R, C>) -> TMat<T, R, C> {
24    x.abs()
25}
26
27/// For each matrix or vector component returns a value equal to the nearest integer that is greater than or equal to `x`.
28///
29/// # Examples:
30///
31/// ```
32/// # use nalgebra_glm as glm;
33/// let vec = glm::vec3(-1.5, 0.5, 2.8);
34/// assert_eq!(glm::vec3(-1.0, 1.0, 3.0), glm::ceil(&vec));
35/// ```
36///
37/// # See also:
38///
39/// * [`ceil()`]
40/// * [`floor()`]
41/// * [`fract()`]
42/// * [`round()`]
43/// * [`trunc()`]
44pub fn ceil<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
45    x.map(|x| x.ceil())
46}
47
48/// Returns `min(max(x, min_val), max_val)`.
49///
50/// # Examples:
51///
52/// ```
53/// # use nalgebra_glm as glm;
54/// // Works with integers:
55/// assert_eq!(3, glm::clamp_scalar(1, 3, 5));
56/// assert_eq!(4, glm::clamp_scalar(4, 3, 5));
57/// assert_eq!(5, glm::clamp_scalar(7, 3, 5));
58///
59/// // And it works with floats:
60/// assert_eq!(3.25, glm::clamp_scalar(1.3, 3.25, 5.5));
61/// assert_eq!(4.5, glm::clamp_scalar(4.5, 3.25, 5.5));
62/// assert_eq!(5.5, glm::clamp_scalar(7.8, 3.25, 5.5));
63/// ```
64///
65/// # See also:
66///
67/// * [`clamp()`]
68/// * [`clamp_vec()`]
69pub fn clamp_scalar<T: Number>(x: T, min_val: T, max_val: T) -> T {
70    na::clamp(x, min_val, max_val)
71}
72
73/// Returns `min(max(x[i], min_val), max_val)` for each component in `x`
74/// using the values `min_val and `max_val` as bounds.
75///
76/// # Examples:
77///
78/// ```
79/// # use nalgebra_glm as glm;
80/// // Works with integers:
81/// assert_eq!(glm::vec3(3, 4, 5),
82///            glm::clamp(&glm::vec3(1, 4, 7), 3, 5));
83///
84/// // And it works with floats:
85/// assert_eq!(glm::vec3(3.25, 4.5, 5.5),
86///            glm::clamp(&glm::vec3(1.3, 4.5, 7.8), 3.25, 5.5));
87/// ```
88///
89/// # See also:
90///
91/// * [`clamp_scalar()`]
92/// * [`clamp_vec()`]
93pub fn clamp<T: Number, const D: usize>(x: &TVec<T, D>, min_val: T, max_val: T) -> TVec<T, D> {
94    x.map(|x| na::clamp(x, min_val, max_val))
95}
96
97/// Returns `min(max(x[i], min_val[i]), max_val[i])` for each component in `x`
98/// using the components of `min_val` and `max_val` as bounds.
99///
100/// # Examples:
101///
102/// ```
103/// # use nalgebra_glm as glm;
104/// let min_bounds = glm::vec2(1.0, 3.0);
105/// let max_bounds = glm::vec2(5.0, 6.0);
106/// assert_eq!(glm::vec2(1.0, 6.0),
107///            glm::clamp_vec(&glm::vec2(0.0, 7.0),
108///                           &min_bounds,
109///                           &max_bounds));
110/// assert_eq!(glm::vec2(2.0, 6.0),
111///            glm::clamp_vec(&glm::vec2(2.0, 7.0),
112///                           &min_bounds,
113///                           &max_bounds));
114/// assert_eq!(glm::vec2(1.0, 4.0),
115///            glm::clamp_vec(&glm::vec2(0.0, 4.0),
116///                           &min_bounds,
117///                           &max_bounds));
118/// ```
119///
120/// # See also:
121///
122/// * [`clamp_scalar()`]
123/// * [`clamp()`]
124pub fn clamp_vec<T: Number, const D: usize>(
125    x: &TVec<T, D>,
126    min_val: &TVec<T, D>,
127    max_val: &TVec<T, D>,
128) -> TVec<T, D> {
129    x.zip_zip_map(min_val, max_val, |a, min, max| na::clamp(a, min, max))
130}
131
132/// Returns a signed integer value representing the encoding of a floating-point value.
133///
134/// The floating-point value's bit-level representation is preserved.
135///
136/// # See also:
137///
138/// * [`float_bits_to_int_vec()`]
139/// * [`float_bits_to_uint()`]
140/// * [`float_bits_to_uint_vec()`]
141/// * [`int_bits_to_float()`]
142/// * [`int_bits_to_float_vec()`]
143/// * [`uint_bits_to_float()`]
144/// * [`uint_bits_to_float_scalar()`]
145pub fn float_bits_to_int(v: f32) -> i32 {
146    unsafe { mem::transmute(v) }
147}
148
149/// Returns a signed integer value representing the encoding of each component of `v`.
150///
151/// The floating point value's bit-level representation is preserved.
152///
153/// # See also:
154///
155/// * [`float_bits_to_int()`]
156/// * [`float_bits_to_uint()`]
157/// * [`float_bits_to_uint_vec()`]
158/// * [`int_bits_to_float()`]
159/// * [`int_bits_to_float_vec()`]
160/// * [`uint_bits_to_float()`]
161/// * [`uint_bits_to_float_scalar()`]
162pub fn float_bits_to_int_vec<const D: usize>(v: &TVec<f32, D>) -> TVec<i32, D> {
163    v.map(float_bits_to_int)
164}
165
166/// Returns an unsigned integer value representing the encoding of a floating-point value.
167///
168/// The floating-point value's bit-level representation is preserved.
169///
170/// # See also:
171///
172/// * [`float_bits_to_int()`]
173/// * [`float_bits_to_int_vec()`]
174/// * [`float_bits_to_uint_vec()`]
175/// * [`int_bits_to_float()`]
176/// * [`int_bits_to_float_vec()`]
177/// * [`uint_bits_to_float()`]
178/// * [`uint_bits_to_float_scalar()`]
179pub fn float_bits_to_uint(v: f32) -> u32 {
180    unsafe { mem::transmute(v) }
181}
182
183/// Returns an unsigned integer value representing the encoding of each component of `v`.
184///
185/// The floating point value's bit-level representation is preserved.
186///
187/// # See also:
188///
189/// * [`float_bits_to_int()`]
190/// * [`float_bits_to_int_vec()`]
191/// * [`float_bits_to_uint()`]
192/// * [`int_bits_to_float()`]
193/// * [`int_bits_to_float_vec()`]
194/// * [`uint_bits_to_float()`]
195/// * [`uint_bits_to_float_scalar()`]
196pub fn float_bits_to_uint_vec<const D: usize>(v: &TVec<f32, D>) -> TVec<u32, D> {
197    v.map(float_bits_to_uint)
198}
199
200/// Returns componentwise a value equal to the nearest integer that is less then or equal to `x`.
201///
202/// # Examples:
203///
204/// ```
205/// # use nalgebra_glm as glm;
206/// let vec = glm::vec3(-1.5, 0.5, 2.8);
207/// assert_eq!(glm::vec3(-2.0, 0.0, 2.0), glm::floor(&vec));
208/// ```
209///
210/// # See also:
211///
212/// * [`ceil()`]
213/// * [`fract()`]
214/// * [`round()`]
215/// * [`trunc()`]
216pub fn floor<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
217    x.map(|x| x.floor())
218}
219
220//// TODO: should be implemented for TVec/TMat?
221//pub fn fma<T: Number>(a: T, b: T, c: T) -> T {
222//    // TODO: use an actual FMA
223//    a * b + c
224//}
225
226/// Returns the fractional part of each component of `x`.
227///
228/// # Examples:
229///
230/// ```
231/// # use nalgebra_glm as glm;
232/// let vec = glm::vec3(-1.5, 0.5, 2.25);
233/// assert_eq!(glm::vec3(-0.5, 0.5, 0.25), glm::fract(&vec));
234/// ```
235///
236/// # See also:
237///
238/// * [`ceil()`]
239/// * [`floor()`]
240/// * [`round()`]
241/// * [`trunc()`]
242pub fn fract<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
243    x.map(|x| x.fract())
244}
245
246//// TODO: should be implemented for TVec/TMat?
247///// Returns the (significant, exponent) of this float number.
248//pub fn frexp<T: RealNumber>(x: T, exp: T) -> (T, T) {
249//    // TODO: is there a better approach?
250//    let e = x.log2().ceil();
251//    (x * (-e).exp2(), e)
252//}
253
254/// Returns a floating-point value corresponding to a signed integer encoding of a floating-point value.
255///
256/// 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.
257///
258/// # See also:
259///
260/// * [`float_bits_to_int()`]
261/// * [`float_bits_to_int_vec()`]
262/// * [`float_bits_to_uint()`]
263/// * [`float_bits_to_uint_vec()`]
264/// * [`int_bits_to_float_vec()`]
265/// * [`uint_bits_to_float()`]
266/// * [`uint_bits_to_float_scalar()`]
267pub fn int_bits_to_float(v: i32) -> f32 {
268    f32::from_bits(v as u32)
269}
270
271/// For each components of `v`, returns a floating-point value corresponding to a signed integer encoding of a floating-point value.
272///
273/// 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.
274///
275/// # See also:
276///
277/// * [`float_bits_to_int()`]
278/// * [`float_bits_to_int_vec()`]
279/// * [`float_bits_to_uint()`]
280/// * [`float_bits_to_uint_vec()`]
281/// * [`int_bits_to_float()`]
282/// * [`uint_bits_to_float()`]
283/// * [`uint_bits_to_float_scalar()`]
284pub fn int_bits_to_float_vec<const D: usize>(v: &TVec<i32, D>) -> TVec<f32, D> {
285    v.map(int_bits_to_float)
286}
287
288//pub fn isinf<T: Scalar, const D: usize>(x: &TVec<T, D>) -> TVec<bool, D> {
289//        unimplemented!()
290//
291//}
292//
293//pub fn isnan<T: Scalar, const D: usize>(x: &TVec<T, D>) -> TVec<bool, D> {
294//        unimplemented!()
295//
296//}
297
298///// Returns the (significant, exponent) of this float number.
299//pub fn ldexp<T: RealNumber>(x: T, exp: T) -> T {
300//    // TODO: is there a better approach?
301//    x * (exp).exp2()
302//}
303
304/// Returns `x * (1.0 - a) + y * a`, i.e., the linear blend of the scalars x and y using the scalar value a.
305///
306/// The value for a is not restricted to the range `[0, 1]`.
307///
308/// # Examples:
309///
310/// ```
311/// # use nalgebra_glm as glm;
312/// assert_eq!(glm::mix_scalar(2.0, 20.0, 0.1), 3.8);
313/// ```
314///
315/// # See also:
316///
317/// * [`mix()`]
318/// * [`mix_vec()`]
319pub fn mix_scalar<T: Number>(x: T, y: T, a: T) -> T {
320    x * (T::one() - a) + y * a
321}
322
323/// Returns `x * (1.0 - a) + y * a`, i.e., the linear blend of the vectors x and y using the scalar value a.
324///
325/// The value for a is not restricted to the range `[0, 1]`.
326///
327/// # Examples:
328///
329/// ```
330/// # use nalgebra_glm as glm;
331/// let x = glm::vec3(1.0, 2.0, 3.0);
332/// let y = glm::vec3(10.0, 20.0, 30.0);
333/// assert_eq!(glm::mix(&x, &y, 0.1), glm::vec3(1.9, 3.8, 5.7));
334/// ```
335///
336/// # See also:
337///
338/// * [`mix_scalar()`]
339/// * [`mix_vec()`]
340pub fn mix<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, a: T) -> TVec<T, D> {
341    x * (T::one() - a) + y * a
342}
343
344/// Returns `x * (1.0 - a) + y * a`, i.e., the component-wise linear blend of `x` and `y` using the components of
345/// the vector `a` as coefficients.
346///
347/// The value for a is not restricted to the range `[0, 1]`.
348///
349/// # Examples:
350///
351/// ```
352/// # use nalgebra_glm as glm;
353/// let x = glm::vec3(1.0, 2.0, 3.0);
354/// let y = glm::vec3(10.0, 20.0, 30.0);
355/// let a = glm::vec3(0.1, 0.2, 0.3);
356/// assert_eq!(glm::mix_vec(&x, &y, &a), glm::vec3(1.9, 5.6, 11.1));
357/// ```
358///
359/// # See also:
360///
361/// * [`mix_scalar()`]
362/// * [`mix()`]
363pub fn mix_vec<T: Number, const D: usize>(
364    x: &TVec<T, D>,
365    y: &TVec<T, D>,
366    a: &TVec<T, D>,
367) -> TVec<T, D> {
368    x.component_mul(&(TVec::<T, D>::repeat(T::one()) - a)) + y.component_mul(a)
369}
370
371/// Returns `x * (1.0 - a) + y * a`, i.e., the linear blend of the scalars x and y using the scalar value a.
372///
373/// The value for a is not restricted to the range `[0, 1]`.
374/// This is an alias for `mix_scalar`.
375///
376/// # Examples:
377///
378/// ```
379/// # use nalgebra_glm as glm;
380/// assert_eq!(glm::lerp_scalar(2.0, 20.0, 0.1), 3.8);
381/// ```
382///
383/// # See also:
384///
385/// * [`lerp()`]
386/// * [`lerp_vec()`]
387pub fn lerp_scalar<T: Number>(x: T, y: T, a: T) -> T {
388    mix_scalar(x, y, a)
389}
390
391/// Returns `x * (1.0 - a) + y * a`, i.e., the linear blend of the vectors x and y using the scalar value a.
392///
393/// The value for a is not restricted to the range `[0, 1]`.
394/// This is an alias for `mix`.
395///
396/// # Examples:
397///
398/// ```
399/// # use nalgebra_glm as glm;
400/// let x = glm::vec3(1.0, 2.0, 3.0);
401/// let y = glm::vec3(10.0, 20.0, 30.0);
402/// assert_eq!(glm::lerp(&x, &y, 0.1), glm::vec3(1.9, 3.8, 5.7));
403/// ```
404///
405/// # See also:
406///
407/// * [`lerp_scalar()`]
408/// * [`lerp_vec()`]
409pub fn lerp<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, a: T) -> TVec<T, D> {
410    mix(x, y, a)
411}
412
413/// Returns `x * (1.0 - a) + y * a`, i.e., the component-wise linear blend of `x` and `y` using the components of
414/// the vector `a` as coefficients.
415///
416/// The value for a is not restricted to the range `[0, 1]`.
417/// This is an alias for `mix_vec`.
418///
419/// # Examples:
420///
421/// ```
422/// # use nalgebra_glm as glm;
423/// let x = glm::vec3(1.0, 2.0, 3.0);
424/// let y = glm::vec3(10.0, 20.0, 30.0);
425/// let a = glm::vec3(0.1, 0.2, 0.3);
426/// assert_eq!(glm::lerp_vec(&x, &y, &a), glm::vec3(1.9, 5.6, 11.1));
427/// ```
428///
429/// # See also:
430///
431/// * [`lerp_scalar()`]
432/// * [`lerp()`]
433pub fn lerp_vec<T: Number, const D: usize>(
434    x: &TVec<T, D>,
435    y: &TVec<T, D>,
436    a: &TVec<T, D>,
437) -> TVec<T, D> {
438    mix_vec(x, y, a)
439}
440
441/// Component-wise modulus.
442///
443/// Returns `x - y * floor(x / y)` for each component in `x` using the corresponding component of `y`.
444///
445/// # See also:
446///
447/// * [`modf()`]
448pub fn modf_vec<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<T, D> {
449    x.zip_map(y, |x, y| x % y)
450}
451
452/// Modulus between two values.
453///
454/// # See also:
455///
456/// * [`modf_vec()`]
457pub fn modf<T: Number>(x: T, i: T) -> T {
458    x % i
459}
460
461/// Component-wise rounding.
462///
463/// Values equal to `0.5` are rounded away from `0.0`.
464///
465/// # Examples:
466///
467/// ```
468/// # use nalgebra_glm as glm;
469/// let vec = glm::vec4(-1.5, 0.6, 1.5, -3.2);
470/// assert_eq!(glm::vec4(-2.0, 1.0, 2.0, -3.0), glm::round(&vec));
471/// ```
472///
473/// # See also:
474///
475/// * [`ceil()`]
476/// * [`floor()`]
477/// * [`fract()`]
478/// * [`trunc()`]
479pub fn round<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
480    x.map(|x| x.round())
481}
482
483//pub fn roundEven<T: Scalar, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
484//        unimplemented!()
485//}
486
487/// For each vector component `x`:  1 if `x > 0`, 0 if `x == 0`, or -1 if `x < 0`.
488///
489/// # Examples:
490///
491/// ```
492/// # use nalgebra_glm as glm;
493/// let vec = glm::vec4(-2.0, 0.0, -0.0, 2.0);
494/// assert_eq!(glm::vec4(-1.0, 0.0, 0.0, 1.0), glm::sign(&vec));
495/// ```
496///
497/// # See also:
498///
499/// * [`abs()`]
500///
501pub fn sign<T: Number, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
502    x.map(|x| if x.is_zero() { T::zero() } else { x.signum() })
503}
504
505/// 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`.
506///
507/// This is useful in cases where you would want a threshold function with a smooth transition.
508/// 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`.
509pub fn smoothstep<T: RealNumber>(edge0: T, edge1: T, x: T) -> T {
510    let _3 = T::from_subset(&3.0f64);
511    let _2 = T::from_subset(&2.0f64);
512    let t = na::clamp((x - edge0) / (edge1 - edge0), T::zero(), T::one());
513    t * t * (_3 - t * _2)
514}
515
516/// Returns 0.0 if `x < edge`, otherwise it returns 1.0.
517pub fn step_scalar<T: Number>(edge: T, x: T) -> T {
518    if edge > x { T::zero() } else { T::one() }
519}
520
521/// Returns 0.0 if `x[i] < edge`, otherwise it returns 1.0.
522pub fn step<T: Number, const D: usize>(edge: T, x: &TVec<T, D>) -> TVec<T, D> {
523    x.map(|x| step_scalar(edge, x))
524}
525
526/// Returns 0.0 if `x[i] < edge[i]`, otherwise it returns 1.0.
527pub fn step_vec<T: Number, const D: usize>(edge: &TVec<T, D>, x: &TVec<T, D>) -> TVec<T, D> {
528    edge.zip_map(x, step_scalar)
529}
530
531/// Returns a value equal to the nearest integer to `x` whose absolute value is not larger than the absolute value of `x`.
532///
533/// # Examples:
534///
535/// ```
536/// # use nalgebra_glm as glm;
537/// let vec = glm::vec3(-1.5, 0.5, 2.8);
538/// assert_eq!(glm::vec3(-1.0, 0.0, 2.0), glm::trunc(&vec));
539/// ```
540///
541/// # See also:
542///
543/// * [`ceil()`]
544/// * [`floor()`]
545/// * [`fract()`]
546/// * [`round()`]
547pub fn trunc<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
548    x.map(|x| x.trunc())
549}
550
551/// Returns a floating-point value corresponding to a unsigned integer encoding of a floating-point value.
552///
553/// 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.
554///
555/// # See also:
556///
557/// * [`float_bits_to_int()`]
558/// * [`float_bits_to_int_vec()`]
559/// * [`float_bits_to_uint()`]
560/// * [`float_bits_to_uint_vec()`]
561/// * [`int_bits_to_float()`]
562/// * [`int_bits_to_float_vec()`]
563/// * [`uint_bits_to_float()`]
564pub fn uint_bits_to_float_scalar(v: u32) -> f32 {
565    f32::from_bits(v)
566}
567
568/// For each component of `v`, returns a floating-point value corresponding to a unsigned integer encoding of a floating-point value.
569///
570/// 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.
571///
572/// # See also:
573///
574/// * [`float_bits_to_int()`]
575/// * [`float_bits_to_int_vec()`]
576/// * [`float_bits_to_uint()`]
577/// * [`float_bits_to_uint_vec()`]
578/// * [`int_bits_to_float()`]
579/// * [`int_bits_to_float_vec()`]
580/// * [`uint_bits_to_float_scalar()`]
581pub fn uint_bits_to_float<const D: usize>(v: &TVec<u32, D>) -> TVec<f32, D> {
582    v.map(uint_bits_to_float_scalar)
583}