box2d_rs/
b2_math.rs

1use crate::b2_common::{b2_assert, B2_PI};
2use crate::private::common::b2_math as private;
3use std::f32::EPSILON;
4use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
5
6#[cfg(feature="serde_support")]
7use serde::{Serialize, Deserialize};
8
9pub fn b2_is_valid(x: f32) -> bool {
10    return x.is_finite();
11}
12
13pub fn b2_sqrt(x: f32) -> f32 {
14    return f32::sqrt(x);
15}
16pub fn b2_atan2(y: f32, x: f32) -> f32 {
17    return f32::atan2(y, x);
18}
19
20/// A 2D column vector.
21#[derive(Default, Clone, Copy, Debug, PartialEq)]
22#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))]
23pub struct B2vec2 {
24    pub x: f32,
25    pub y: f32,
26}
27
28impl B2vec2 {
29    /// Construct using coordinates.
30    pub fn new(x_in: f32, y_in: f32) -> B2vec2 {
31        return B2vec2 { x: x_in, y: y_in };
32    }
33
34    pub fn zero() -> B2vec2{
35        return B2vec2::new(0.0, 0.0);
36    }
37
38    /// Set this vector to all zeros.
39    pub fn set_zero(&mut self) {
40        self.x = 0.0;
41        self.y = 0.0;
42    }
43
44    /// Set this vector to some specified coordinates.
45    pub fn set(&mut self, x_: f32, y_: f32) {
46        self.x = x_;
47        self.y = y_;
48    }
49
50    pub fn get(self, i: i32) -> f32 {
51        assert!(i >= 0 && i < 2);
52
53        if i == 0 {
54            self.x
55        } else {
56            self.y
57        }
58    }
59
60    pub fn set_by_index(&mut self, i: i32, value: f32) {
61        assert!(i >= 0 && i < 2);
62
63        if i == 0 {
64            self.x = value;
65        } else {
66            self.y = value;
67        }
68    }
69
70    /// Get the length of this vector (the norm).
71    pub fn length(self) -> f32 {
72        return b2_sqrt(self.x * self.x + self.y * self.y);
73    }
74
75    /// Get the length squared. For performance, use this instead of
76    /// B2vec2::length (if possible).
77    pub fn length_squared(self) -> f32 {
78        return self.x * self.x + self.y * self.y;
79    }
80
81    /// Convert this vector into a unit vector. Returns the length.
82    pub fn normalize(&mut self) -> f32 {
83        let length = self.length();
84        if length < EPSILON {
85            return 0.0;
86        }
87        let inv_length: f32 = 1.0 / length;
88        self.x *= inv_length;
89        self.y *= inv_length;
90
91        return length;
92    }
93
94    /// Does this vector contain finite coordinates?
95    pub fn is_valid(self) -> bool {
96        return b2_is_valid(self.x) && b2_is_valid(self.y);
97    }
98
99    /// Get the skew vector such that dot(skew_vec, other) == cross(vec, other)
100    pub fn skew(self) -> B2vec2 {
101        return B2vec2::new(-self.y, self.x);
102    }
103}
104
105impl Neg for B2vec2 {
106    type Output = B2vec2;
107    /// Negate this vector.
108    fn neg(self) -> B2vec2 {
109        return B2vec2 {
110            x: -self.x,
111            y: -self.y,
112        };
113    }
114}
115
116impl AddAssign<B2vec2> for B2vec2 {
117    /// Add a vector to this vector.
118    fn add_assign(&mut self, other: B2vec2) {
119        self.x += other.x;
120        self.y += other.y;
121    }
122}
123
124impl SubAssign<B2vec2> for B2vec2 {
125    /// Subtract a vector from this vector.
126    fn sub_assign(&mut self, other: B2vec2) {
127        self.x -= other.x;
128        self.y -= other.y;
129    }
130}
131
132impl MulAssign<f32> for B2vec2 {
133    /// Multiply this vector by a scalar.
134    fn mul_assign(&mut self, other: f32) {
135        self.x *= other;
136        self.y *= other;
137    }
138}
139
140/// A 2D column vector with 3 elements.
141#[derive(Default, Clone, Copy, Debug)]
142#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))]
143pub struct B2Vec3 {
144    pub x: f32,
145    pub y: f32,
146    pub z: f32,
147}
148
149impl B2Vec3 {
150    /// Construct using coordinates.
151    pub fn new(x_in: f32, y_in: f32, z_in: f32) -> B2Vec3 {
152        return B2Vec3 {
153            x: x_in,
154            y: y_in,
155            z: z_in,
156        };
157    }
158
159    /// Set this vector to all zeros.
160    pub fn set_zero(&mut self) {
161        self.x = 0.0;
162        self.y = 0.0;
163        self.z = 0.0;
164    }
165
166    pub fn zero() -> Self{
167        return Self::new(0.0, 0.0, 0.0);
168    }
169
170    /// Set this vector to some specified coordinates.
171    pub fn set(&mut self, x_: f32, y_: f32, z_: f32) {
172        self.x = x_;
173        self.y = y_;
174        self.z = z_;
175    }
176}
177
178impl Neg for B2Vec3 {
179    type Output = B2Vec3;
180    /// Negate this vector.
181    fn neg(self) -> B2Vec3 {
182        return B2Vec3::new(-self.x, -self.y, -self.z);
183    }
184}
185
186impl AddAssign for B2Vec3 {
187    /// Add a vector to this vector.
188    fn add_assign(&mut self, v: B2Vec3) {
189        self.x += v.x;
190        self.y += v.y;
191        self.z += v.z;
192    }
193}
194
195impl SubAssign for B2Vec3 {
196    /// Subtract a vector from this vector.
197    fn sub_assign(&mut self, v: B2Vec3) {
198        self.x -= v.x;
199        self.y -= v.y;
200        self.z -= v.z;
201    }
202}
203
204impl MulAssign<f32> for B2Vec3 {
205    /// Multiply this vector by a scalar.
206    fn mul_assign(&mut self, s: f32) {
207        self.x *= s;
208        self.y *= s;
209        self.z *= s;
210    }
211}
212
213/// A 2-by-2 matrix. Stored in column-major order.
214#[derive(Default, Clone, Copy, Debug)]
215#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))]
216pub struct B2Mat22 {
217   pub ex: B2vec2,
218   pub ey: B2vec2,
219}
220
221impl B2Mat22 {
222    /// Construct this matrix using columns.
223    pub fn new(c1: B2vec2, c2: B2vec2) -> B2Mat22 {
224        return B2Mat22 { ex: c1, ey: c2 };
225    }
226
227    /// Construct this matrix using scalars.
228    pub fn new_scalars(a11: f32, a12: f32, a21: f32, a22: f32) -> B2Mat22 {
229        return B2Mat22 {
230            ex: B2vec2::new(a11, a21),
231            ey: B2vec2::new(a12, a22),
232        };
233    }
234
235    /// initialize this matrix using columns.
236    pub fn set(&mut self, c1: B2vec2, c2: B2vec2) {
237        self.ex = c1;
238        self.ey = c2;
239    }
240
241    /// Set this to the identity matrix.
242    pub fn set_identity(&mut self) {
243        self.ex.x = 1.0;
244        self.ey.x = 0.0;
245        self.ex.y = 0.0;
246        self.ey.y = 1.0;
247    }
248
249    /// Set this matrix to all zeros.
250    pub fn set_zero(&mut self) {
251        self.ex.x = 0.0;
252        self.ey.x = 0.0;
253        self.ex.y = 0.0;
254        self.ey.y = 0.0;
255    }
256
257    pub fn zero()->Self{
258        return Self::new(B2vec2::zero(), B2vec2::zero());
259    }
260
261    pub fn get_inverse(&mut self) -> B2Mat22 {
262        let a = self.ex.x;
263        let b = self.ey.x;
264        let c = self.ex.y;
265        let d = self.ey.y;
266        let mut det: f32 = a * d - b * c;
267        if det != 0.0 {
268            det = 1.0 / det;
269        }
270        return B2Mat22 {
271            ex: B2vec2::new(det * d, -det * c),
272            ey: B2vec2::new(-det * b, det * a),
273        };
274    }
275
276    /// solve A * x = b, where b is a column vector. This is more efficient
277    /// than computing the inverse in one-shot cases.
278    pub fn solve(self, b: B2vec2) -> B2vec2 {
279        let a11 = self.ex.x;
280        let a12 = self.ey.x;
281        let a21 = self.ex.y;
282        let a22 = self.ey.y;
283        let mut det: f32 = a11 * a22 - a12 * a21;
284        if det != 0.0 {
285            det = 1.0 / det;
286        }
287        let x: B2vec2;
288        x = B2vec2 {
289            x: det * (a22 * b.x - a12 * b.y),
290            y: det * (a11 * b.y - a21 * b.x),
291        };
292        return x;
293    }
294}
295
296/// A 3-by-3 matrix. Stored in column-major order.
297#[derive(Default, Clone, Copy, Debug)]
298#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))]
299pub struct B2Mat33 {
300    pub ex: B2Vec3,
301    pub ey: B2Vec3,
302    pub ez: B2Vec3,
303}
304
305impl B2Mat33 {
306    /// Construct this matrix using columns.
307    pub fn new(c1: B2Vec3, c2: B2Vec3, c3: B2Vec3) -> B2Mat33 {
308        return B2Mat33 {
309            ex: c1,
310            ey: c2,
311            ez: c3,
312        };
313    }
314
315    /// Set this matrix to all zeros.
316    pub fn set_zero(&mut self) {
317        self.ex.set_zero();
318        self.ey.set_zero();
319        self.ez.set_zero();
320    }
321
322    pub fn zero()->Self{
323        return Self::new(B2Vec3::zero(), B2Vec3::zero(),B2Vec3::zero());
324    }
325
326    /// solve A * x = b, where b is a column vector. This is more efficient
327    /// than computing the inverse in one-shot cases.
328    pub fn solve33(self, b: B2Vec3) -> B2Vec3 {
329        return private::solve33(self, b);
330    }
331
332    /// solve A * x = b, where b is a column vector. This is more efficient
333    /// than computing the inverse in one-shot cases. solve only the upper
334    /// 2-by-2 matrix equation.
335    pub fn solve22(self, b: B2vec2) -> B2vec2 {
336        return private::solve22(self, b);
337    }
338
339    /// Get the inverse of this matrix as a 2-by-2.
340    /// Returns the zero matrix if singular.
341    pub fn get_inverse22(self, m: &mut B2Mat33) {
342        return private::get_inverse22(self, m);
343    }
344
345    /// Get the symmetric inverse of this matrix as a 3-by-3.
346    /// Returns the zero matrix if singular.
347    pub fn get_sym_inverse33(self, m: &mut B2Mat33) {
348        return private::get_sym_inverse33(self, m);
349    }
350}
351
352/// Rotation
353#[derive(Clone, Default, Copy, Debug)]
354#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))]
355pub struct B2Rot {
356    /// Sine and cosine
357    pub s: f32,
358    pub c: f32,
359}
360
361impl B2Rot {
362    /// initialize from an angle in radians
363    pub fn new(angle: f32) -> B2Rot {
364        // TODO_ERIN optimize
365        return B2Rot {
366            s: f32::sin(angle),
367            c: f32::cos(angle),
368        };
369    }
370
371    /// Set using an angle in radians.
372    pub fn set(&mut self, angle: f32) {
373        // TODO_ERIN optimize
374        self.s = f32::sin(angle);
375        self.c = f32::cos(angle);
376    }
377
378    /// Set to the identity rotation
379    pub fn set_identity(&mut self) {
380        self.s = 0.0;
381        self.c = 1.0;
382    }
383
384    /// Get the angle in radians
385    pub fn get_angle(self) -> f32 {
386        return f32::atan2(self.s, self.c);
387    }
388
389    /// Get the x-axis
390    pub fn get_xaxis(self) -> B2vec2 {
391        return B2vec2::new(self.c, self.s);
392    }
393
394    /// Get the u-axis
395    pub fn get_yaxis(self) -> B2vec2 {
396        return B2vec2::new(-self.s, self.c);
397    }
398}
399
400/// A transform contains translation and rotation. It is used to represent
401/// the position and orientation of rigid frames.
402#[derive(Default, Clone, Copy, Debug)]
403#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))]
404pub struct B2Transform {
405    pub p: B2vec2,
406    pub q: B2Rot,
407}
408
409impl B2Transform {
410    /// initialize using a position vector and a rotation.
411    pub fn new(position: B2vec2, rotation: B2Rot) -> B2Transform {
412        return B2Transform {
413            p: position,
414            q: rotation,
415        };
416    }
417
418    /// Set this to the identity transform.
419    pub fn set_identity(&mut self) {
420        self.p.set_zero();
421        self.q.set_identity();
422    }
423
424    /// Set this based on the position and angle.
425    pub fn set(&mut self, position: B2vec2, angle: f32) {
426        self.p = position;
427        self.q.set(angle);
428    }
429}
430
431/// This describes the motion of a body/shape for TOI computation.
432/// Shapes are defined with respect to the body origin, which may
433/// no coincide with the center of mass. However, to support dynamics
434/// we must interpolate the center of mass position.
435#[derive(Default, Clone, Copy, Debug)]
436#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))]
437pub struct B2Sweep {
438    pub local_center: B2vec2, //< local center of mass position
439    pub c0: B2vec2,
440    pub c: B2vec2, //< center world positions
441    pub a0: f32,
442    pub a: f32, //< world angles
443
444    // Fraction of the current time step in the range [0,1]
445    // c0 and a0 are the positions at alpha0.
446    pub alpha0: f32,
447}
448
449impl B2Sweep {
450    /// Get the interpolated transform at a specific time.
451    /// * `transform` - the output transform
452    /// * `beta` - is a factor in [0,1], where 0 indicates alpha0.
453    pub fn get_transform(self, transform: &mut B2Transform, beta: f32) {
454        b2_sweep_get_transform(self, transform, beta);
455    }
456
457    /// advance the sweep forward, yielding a new initial state.
458    /// * `alpha` - the new initial time.
459    pub fn advance(&mut self, alpha: f32) {
460        b2_sweep_advance(self, alpha);
461    }
462
463    /// normalize the angles.
464    pub fn normalize(&mut self) {
465        b2_sweep_normalize(self);
466    }
467}
468
469/// Perform the dot product on two vectors.
470pub fn b2_dot(a: B2vec2, b: B2vec2) -> f32 {
471    return a.x * b.x + a.y * b.y;
472}
473
474/// Perform the cross product on two vectors. In 2D this produces a scalar.
475pub fn b2_cross(a: B2vec2, b: B2vec2) -> f32 {
476    return a.x * b.y - a.y * b.x;
477}
478
479/// Perform the cross product on a vector and a scalar. In 2D this produces
480/// a vector.
481pub fn b2_cross_vec_by_scalar(a: B2vec2, s: f32) -> B2vec2 {
482    return B2vec2::new(s * a.y, -s * a.x);
483}
484
485/// Perform the cross product on a scalar and a vector. In 2D this produces
486/// a vector.
487pub fn b2_cross_scalar_by_vec(s: f32, a: B2vec2) -> B2vec2 {
488    return B2vec2::new(-s * a.y, s * a.x);
489}
490
491/// Multiply a matrix times a vector. If a rotation matrix is provided,
492/// then this transforms the vector from one frame to another.
493pub fn b2_mul(a: B2Mat22, v: B2vec2) -> B2vec2 {
494    return B2vec2::new(a.ex.x * v.x + a.ey.x * v.y, a.ex.y * v.x + a.ey.y * v.y);
495}
496
497/// Multiply a matrix transpose times a vector. If a rotation matrix is provided,
498/// then this transforms the vector from one frame to another (inverse transform).
499pub fn b2_mul_t(a: B2Mat22, v: B2vec2) -> B2vec2 {
500    return B2vec2::new(b2_dot(v, a.ex), b2_dot(v, a.ey));
501}
502
503impl Add for B2vec2 {
504    type Output = B2vec2;
505    /// Add two vectors component-wise.
506    fn add(self, b: B2vec2) -> B2vec2 {
507        return B2vec2::new(self.x + b.x, self.y + b.y);
508    }
509}
510impl Sub for B2vec2 {
511    type Output = B2vec2;
512    /// Subtract two vectors component-wise.
513    fn sub(self, b: B2vec2) -> B2vec2 {
514        return B2vec2::new(self.x - b.x, self.y - b.y);
515    }
516}
517
518impl Mul<B2vec2> for f32 {
519    type Output = B2vec2;
520    fn mul(self, a: B2vec2) -> B2vec2 {
521        return B2vec2::new(self * a.x, self * a.y);
522    }
523}
524
525pub fn is_equal(a: B2vec2, b: B2vec2) -> bool {
526    return a.x == b.x && a.y == b.y;
527}
528
529pub fn not_equal(a: B2vec2, b: B2vec2) -> bool {
530    return a.x != b.x || a.y != b.y;
531}
532
533pub fn b2_distance_vec2(a: B2vec2, b: B2vec2) -> f32 {
534    let c: B2vec2 = a - b;
535    return c.length();
536}
537
538pub fn b2_distance_vec2_squared(a: B2vec2, b: B2vec2) -> f32 {
539    let c: B2vec2 = a - b;
540    return b2_dot(c, c);
541}
542
543impl Mul<B2Vec3> for f32 {
544    type Output = B2Vec3;
545
546    fn mul(self, a: B2Vec3) -> B2Vec3 {
547        return B2Vec3::new(self * a.x, self * a.y, self * a.z);
548    }
549}
550
551impl Add for B2Vec3 {
552    type Output = B2Vec3;
553    /// Add two vectors component-wise.
554    fn add(self, b: B2Vec3) -> B2Vec3 {
555        return B2Vec3::new(self.x + b.x, self.y + b.y, self.z + b.z);
556    }
557}
558
559/// Subtract two vectors component-wise.
560impl Sub for B2Vec3 {
561    type Output = B2Vec3;
562    /// Add two vectors component-wise.
563    fn sub(self, b: B2Vec3) -> B2Vec3 {
564        return B2Vec3::new(self.x - b.x, self.y - b.y, self.z - b.z);
565    }
566}
567
568/// Perform the dot product on two vectors.
569pub fn b2_dot_vec3(a: B2Vec3, b: B2Vec3) -> f32 {
570    return a.x * b.x + a.y * b.y + a.z * b.z;
571}
572
573/// Perform the cross product on two vectors.
574pub fn b2_cross_vec3(a: B2Vec3, b: B2Vec3) -> B2Vec3 {
575    return B2Vec3::new(
576        a.y * b.z - a.z * b.y,
577        a.z * b.x - a.x * b.z,
578        a.x * b.y - a.y * b.x,
579    );
580}
581impl Add for B2Mat22 {
582    type Output = B2Mat22;
583    fn add(self, b: B2Mat22) -> B2Mat22 {
584        return B2Mat22::new(self.ex + b.ex, self.ey + b.ey);
585    }
586}
587
588// A * b
589pub fn b2_mul_mat22(a: B2Mat22, b: B2Mat22) -> B2Mat22 {
590    return B2Mat22::new(b2_mul(a, b.ex), b2_mul(a, b.ey));
591}
592
593// A^T * b
594pub fn b2_mul_t_mat22(a: B2Mat22, b: B2Mat22) -> B2Mat22 {
595    let c1 = B2vec2::new(b2_dot(a.ex, b.ex), b2_dot(a.ey, b.ex));
596    let c2 = B2vec2::new(b2_dot(a.ex, b.ey), b2_dot(a.ey, b.ey));
597    return B2Mat22::new(c1, c2);
598}
599
600/// Multiply a matrix times a vector.
601pub fn b2_mul_mat33(a: B2Mat33, v: B2Vec3) -> B2Vec3 {
602    return v.x * a.ex + v.y * a.ey + v.z * a.ez;
603}
604
605/// Multiply a matrix times a vector.
606pub fn b2_mul22(a: B2Mat33, v: B2vec2) -> B2vec2 {
607    return B2vec2::new(a.ex.x * v.x + a.ey.x * v.y, a.ex.y * v.x + a.ey.y * v.y);
608}
609
610/// Multiply two rotations: q * r
611pub fn b2_mul_rot(q: B2Rot, r: B2Rot) -> B2Rot {
612    // [qc -qs] * [rc -rs] = [qc*rc-qs*rs -qc*rs-qs*rc]
613    // [qs  qc]   [rs  rc]   [qs*rc+qc*rs -qs*rs+qc*rc]
614    // s = qs * rc + qc * rs
615    // c = qc * rc - qs * rs
616    let qr = B2Rot {
617        s: q.s * r.c + q.c * r.s,
618        c: q.c * r.c - q.s * r.s,
619    };
620    return qr;
621}
622
623/// Transpose multiply two rotations: qT * r
624pub fn b2_mul_t_rot(q: B2Rot, r: B2Rot) -> B2Rot {
625    // [ qc qs] * [rc -rs] = [qc*rc+qs*rs -qc*rs+qs*rc]
626    // [-qs qc]   [rs  rc]   [-qs*rc+qc*rs qs*rs+qc*rc]
627    // s = qc * rs - qs * rc
628    // c = qc * rc + qs * rs
629    let qr = B2Rot {
630        s: q.c * r.s - q.s * r.c,
631        c: q.c * r.c + q.s * r.s,
632    };
633    return qr;
634}
635
636/// Rotate a vector
637pub fn b2_mul_rot_by_vec2(q: B2Rot, v: B2vec2) -> B2vec2 {
638    return B2vec2::new(q.c * v.x - q.s * v.y, q.s * v.x + q.c * v.y);
639}
640
641/// Inverse rotate a vector
642pub fn b2_mul_t_rot_by_vec2(q: B2Rot, v: B2vec2) -> B2vec2 {
643    return B2vec2::new(q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y);
644}
645
646pub fn b2_mul_transform_by_vec2(t: B2Transform, v: B2vec2) -> B2vec2 {
647    let x: f32 = (t.q.c * v.x - t.q.s * v.y) + t.p.x;
648    let y: f32 = (t.q.s * v.x + t.q.c * v.y) + t.p.y;
649
650    return B2vec2::new(x, y);
651}
652
653pub fn b2_mul_t_transform_by_vec2(t: B2Transform, v: B2vec2) -> B2vec2 {
654    let px: f32 = v.x - t.p.x;
655    let py: f32 = v.y - t.p.y;
656    let x: f32 = t.q.c * px + t.q.s * py;
657    let y: f32 = -t.q.s * px + t.q.c * py;
658
659    return B2vec2::new(x, y);
660}
661
662// v2 = A.q.Rot(b.q.Rot(v1) + b.p) + A.p
663//    = (A.q * b.q).Rot(v1) + A.q.Rot(b.p) + A.p
664pub fn b2_mul_transform(a: B2Transform, b: B2Transform) -> B2Transform {
665    let c = B2Transform {
666        q: b2_mul_rot(a.q.clone(), b.q.clone()),
667        p: b2_mul_rot_by_vec2(a.q, b.p) + a.p,
668    };
669    return c;
670}
671
672// v2 = A.q' * (b.q * v1 + b.p - A.p)
673//    = A.q' * b.q * v1 + A.q' * (b.p - A.p)
674pub fn b2_mul_t_transform(a: B2Transform, b: B2Transform) -> B2Transform {
675    let c = B2Transform {
676        q: b2_mul_t_rot(a.q, b.q),
677        p: b2_mul_t_rot_by_vec2(a.q, b.p - a.p),
678    };
679    return c;
680}
681
682// pub fn b2_abs<T>(a: T) -> T
683// where T: PartialOrd + Neg
684// {
685// 	return if a > T::new(0) { a }else{ -a};
686// }
687
688pub fn b2_abs_i32(v: i32) -> i32 {
689    return i32::abs(v);
690}
691
692pub fn b2_abs(v: f32) -> f32 {
693    return f32::abs(v);
694}
695
696pub fn b2_abs_vec2(a: B2vec2) -> B2vec2 {
697    return B2vec2::new(b2_abs(a.x), b2_abs(a.y));
698}
699
700pub fn b2_abs_mat22(a: B2Mat22) -> B2Mat22 {
701    return B2Mat22::new(b2_abs_vec2(a.ex), b2_abs_vec2(a.ey));
702}
703
704pub fn b2_min<T>(a: T, b: T) -> T
705where
706    T: PartialOrd,
707{
708    return if a < b { a } else { b };
709}
710
711pub fn b2_min_vec2(a: B2vec2, b: B2vec2) -> B2vec2 {
712    return B2vec2::new(b2_min(a.x, b.x), b2_min(a.y, b.y));
713}
714
715pub fn b2_max<T>(a: T, b: T) -> T
716where
717    T: PartialOrd,
718{
719    return if a > b { a } else { b };
720}
721
722pub fn b2_max_vec2(a: B2vec2, b: B2vec2) -> B2vec2 {
723    return B2vec2::new(b2_max(a.x, b.x), b2_max(a.y, b.y));
724}
725
726pub fn b2_clamp<T>(a: T, low: T, high: T) -> T
727where
728    T: PartialOrd,
729{
730    return b2_max(low, b2_min(a, high));
731}
732
733pub fn b2_clamp_vec2(a: B2vec2, low: B2vec2, high: B2vec2) -> B2vec2 {
734    return b2_max_vec2(low, b2_max_vec2(a, high));
735}
736
737pub fn b2_swap<T: Clone>(a: &mut T, b: &mut T) {
738    let tmp = a.clone();
739    *a = b.clone();
740    *b = tmp;
741}
742
743/// "Next Largest Power of 2
744/// Given a binary integer value x, the next largest power of 2 can be computed by a SWAR algorithm
745/// that recursively "folds" the upper bits into the lower bits. This process yields a bit vector with
746/// the same most significant 1 as x, but all 1's below it. Adding 1 to that value yields the next
747/// largest power of 2. For a 32-bit value:"
748pub fn b2_next_power_of_two(v: u32) -> u32 {
749    let mut x: u32 = v;
750    x |= x >> 1;
751    x |= x >> 2;
752    x |= x >> 4;
753    x |= x >> 8;
754    x |= x >> 16;
755    return x + 1;
756}
757
758pub fn b2_is_power_of_two(x: u32) -> bool {
759    let result: bool = x > 0 && (x & (x - 1)) == 0;
760    return result;
761}
762
763// https://fgiesen.wordpress.com/2012/08/15/linear-interpolation-past-present-and-future/
764pub fn b2_sweep_get_transform(self_: B2Sweep, xf: &mut B2Transform, beta: f32) {
765    xf.p = (1.0 - beta) * self_.c0 + beta * self_.c;
766	let angle: f32 = (1.0 - beta) * self_.a0 + beta * self_.a;
767    xf.q.set(angle);
768
769    // Shift to origin
770    xf.p -= b2_mul_rot_by_vec2(xf.q, self_.local_center);
771}
772
773pub fn b2_sweep_advance(self_: &mut B2Sweep, alpha: f32) {
774    b2_assert(self_.alpha0 < 1.0);
775    let beta: f32 = (alpha - self_.alpha0) / (1.0 - self_.alpha0);
776    self_.c0 += beta * (self_.c - self_.c0);
777    self_.a0 += beta * (self_.a - self_.a0);
778    self_.alpha0 = alpha;
779}
780
781/// normalize an angle in radians to be between -pi and pi
782pub fn b2_sweep_normalize(self_: &mut B2Sweep) {
783    let two_pi: f32 = 2.0 * B2_PI;
784    let d: f32 = two_pi * f32::floor(self_.a0 / two_pi);
785    self_.a0 -= d;
786    self_.a -= d;
787}