jagua_rs/geometry/
d_transformation.rs1use std::borrow::Borrow;
2use std::f32::consts::PI;
3use std::fmt::Display;
4
5use crate::geometry::Transformation;
6use ordered_float::NotNan;
7
8#[derive(Clone, Debug, PartialEq, Eq, Hash, Copy, Default)]
9pub struct DTransformation {
12 pub rotation: NotNan<f32>,
14 pub translation: (NotNan<f32>, NotNan<f32>),
16}
17
18impl DTransformation {
19 pub fn new(rotation: f32, translation: (f32, f32)) -> Self {
20 Self {
21 rotation: NotNan::new(rotation).expect("rotation is NaN"),
22 translation: (
23 NotNan::new(translation.0).expect("translation.0 is NaN"),
24 NotNan::new(translation.1).expect("translation.1 is NaN"),
25 ),
26 }
27 }
28
29 pub const fn empty() -> Self {
30 const _0: NotNan<f32> = unsafe { NotNan::new_unchecked(0.0) };
31 Self {
32 rotation: _0,
33 translation: (_0, _0),
34 }
35 }
36
37 pub fn rotation(&self) -> f32 {
38 self.rotation.into()
39 }
40
41 pub fn translation(&self) -> (f32, f32) {
42 (self.translation.0.into(), self.translation.1.into())
43 }
44
45 pub fn compose(&self) -> Transformation {
46 self.into()
47 }
48}
49
50impl<T> From<T> for DTransformation
51where
52 T: Borrow<Transformation>,
53{
54 fn from(t: T) -> Self {
55 t.borrow().decompose()
56 }
57}
58
59impl Display for DTransformation {
60 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61 write!(
62 f,
63 "r: {:.3}°, t: ({:.3}, {:.3})",
64 self.rotation.to_degrees(),
65 self.translation.0.into_inner(),
66 self.translation.1.into_inner()
67 )
68 }
69}
70
71pub fn normalize_rotation(r: f32) -> f32 {
73 let normalized = r % (2.0 * PI);
74 if normalized < 0.0 {
75 normalized + 2.0 * PI
76 } else {
77 normalized
78 }
79}