1use std::fmt::Display;
8
9use crate::{motion::SpatialRotation, vector3d::Vector3D};
10use nalgebra::{IsometryMatrix3, Translation3};
11
12#[derive(Clone, Debug, Copy, PartialEq, Default)]
17pub struct SE3(pub(crate) IsometryMatrix3<f64>);
18
19impl SE3 {
20 #[must_use]
22 pub fn new(translation: Vector3D, axis_angle: Vector3D) -> Self {
23 let rotation = SpatialRotation::from_axis_angle(&axis_angle, axis_angle.norm());
24 SE3::from_parts(
25 Vector3D::new(translation.0.x, translation.0.y, translation.0.z),
26 rotation,
27 )
28 }
29
30 #[must_use]
32 pub fn from_parts(translation: Vector3D, rotation: SpatialRotation) -> Self {
33 SE3(IsometryMatrix3::from_parts(
34 Translation3::from(translation.0),
35 rotation.0,
36 ))
37 }
38
39 #[must_use]
41 pub fn identity() -> Self {
42 SE3(IsometryMatrix3::identity())
43 }
44
45 #[must_use]
47 pub fn inverse(&self) -> Self {
48 SE3(self.0.inverse())
49 }
50
51 #[must_use]
53 pub fn translation(&self) -> Vector3D {
54 Vector3D(self.0.translation.vector)
55 }
56
57 #[must_use]
59 pub fn rotation(&self) -> SpatialRotation {
60 SpatialRotation(self.0.rotation)
61 }
62}
63
64impl std::ops::Mul for SE3 {
65 type Output = SE3;
66
67 fn mul(self, rhs: Self) -> Self::Output {
68 SE3(self.0 * rhs.0)
69 }
70}
71
72impl std::ops::Mul<&SE3> for &SE3 {
73 type Output = SE3;
74
75 fn mul(self, rhs: &SE3) -> Self::Output {
76 SE3(self.0 * rhs.0)
77 }
78}
79
80impl std::ops::Mul<SE3> for &SE3 {
81 type Output = SE3;
82
83 fn mul(self, rhs: SE3) -> Self::Output {
84 SE3(self.0 * rhs.0)
85 }
86}
87
88impl std::ops::Mul<&SE3> for SE3 {
89 type Output = SE3;
90
91 fn mul(self, rhs: &SE3) -> Self::Output {
92 SE3(self.0 * rhs.0)
93 }
94}
95
96impl Display for SE3 {
97 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
98 let r = self.0.rotation.matrix();
99
100 writeln!(f, "SE3: R=┌ ┐ t=┌ ┐")?;
101 for i in 0..3 {
102 writeln!(
103 f,
104 " │ {:>+8.5} {:>+8.5} {:>+8.5} │ │ {:>+8.5} │",
105 r[(i, 0)],
106 r[(i, 1)],
107 r[(i, 2)],
108 self.0.translation.vector[i]
109 )?;
110 }
111 writeln!(f, " └ ┘ └ ┘")?;
112 Ok(())
113 }
114}
115
116pub trait ActSE3 {
118 fn act(&self, se3: &SE3) -> Self;
120
121 fn act_inv(&self, se3: &SE3) -> Self;
123}
124
125impl SE3 {
126 pub fn act<T: ActSE3>(&self, obj: &T) -> T {
128 obj.act(self)
129 }
130
131 pub fn act_inv<T: ActSE3>(&self, obj: &T) -> T {
133 obj.act_inv(self)
134 }
135}