egml_core/model/geometry/
direct_position.rs

1use crate::error::Error;
2use crate::operations::geometry::Geometry;
3use nalgebra::{Isometry3, Point3};
4use std::fmt;
5
6#[derive(Debug, Clone, Copy, PartialEq, Default)]
7pub struct DirectPosition {
8    x: f64,
9    y: f64,
10    z: f64,
11}
12
13impl DirectPosition {
14    pub fn new(x: f64, y: f64, z: f64) -> Result<Self, Error> {
15        if !x.is_finite() || !y.is_finite() || !z.is_finite() {
16            return Err(Error::ValueNotFinite(""));
17        }
18
19        Ok(Self { x, y, z })
20    }
21
22    pub fn x(&self) -> f64 {
23        self.x
24    }
25
26    pub fn y(&self) -> f64 {
27        self.y
28    }
29
30    pub fn z(&self) -> f64 {
31        self.z
32    }
33
34    pub fn coords(&self) -> [f64; 3] {
35        [self.x, self.y, self.z]
36    }
37
38    pub fn set_x(&mut self, val: f64) -> Result<(), Error> {
39        if !val.is_finite() {
40            return Err(Error::ValueNotFinite("x"));
41        }
42        self.x = val;
43        Ok(())
44    }
45
46    pub fn set_y(&mut self, val: f64) -> Result<(), Error> {
47        if !val.is_finite() {
48            return Err(Error::ValueNotFinite("y"));
49        }
50        self.y = val;
51        Ok(())
52    }
53
54    pub fn set_z(&mut self, val: f64) -> Result<(), Error> {
55        if !val.is_finite() {
56            return Err(Error::ValueNotFinite("z"));
57        }
58        self.z = val;
59        Ok(())
60    }
61
62    pub const MIN: DirectPosition = DirectPosition {
63        x: f64::MIN,
64        y: f64::MIN,
65        z: f64::MIN,
66    };
67    pub const MAX: DirectPosition = DirectPosition {
68        x: f64::MAX,
69        y: f64::MAX,
70        z: f64::MAX,
71    };
72    pub const ORIGIN: DirectPosition = DirectPosition {
73        x: 0.0,
74        y: 0.0,
75        z: 0.0,
76    };
77}
78
79impl Geometry for DirectPosition {
80    fn points(&self) -> Vec<&DirectPosition> {
81        Vec::from([self])
82    }
83
84    fn apply_transform(&mut self, m: &Isometry3<f64>) {
85        let p: Point3<f64> = m * Point3::new(self.x, self.y, self.z);
86        self.x = p.x;
87        self.y = p.y;
88        self.z = p.z;
89    }
90}
91
92impl fmt::Display for DirectPosition {
93    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
94        write!(f, "({}, {}, {})", self.x, self.y, self.z)
95    }
96}
97
98impl From<DirectPosition> for nalgebra::Vector3<f64> {
99    fn from(item: DirectPosition) -> Self {
100        Self::new(item.x, item.y, item.z)
101    }
102}
103
104impl From<nalgebra::Vector3<f64>> for DirectPosition {
105    fn from(item: nalgebra::Vector3<f64>) -> Self {
106        Self::new(item.x, item.y, item.z).unwrap()
107    }
108}
109
110impl From<&DirectPosition> for nalgebra::Vector3<f64> {
111    fn from(item: &DirectPosition) -> Self {
112        Self::new(item.x, item.y, item.z)
113    }
114}
115
116impl From<&nalgebra::Vector3<f64>> for DirectPosition {
117    fn from(item: &nalgebra::Vector3<f64>) -> Self {
118        Self::new(item.x, item.y, item.z).unwrap()
119    }
120}
121
122impl From<DirectPosition> for nalgebra::Point3<f64> {
123    fn from(item: DirectPosition) -> Self {
124        Self::new(item.x, item.y, item.z)
125    }
126}
127
128impl From<DirectPosition> for nalgebra::Point3<f32> {
129    fn from(item: DirectPosition) -> Self {
130        Self::new(item.x as f32, item.y as f32, item.z as f32)
131    }
132}
133
134impl From<nalgebra::Point3<f64>> for DirectPosition {
135    fn from(item: nalgebra::Point3<f64>) -> Self {
136        // TODO: how to handle error?
137        Self::new(item.x, item.y, item.z).expect("Should work")
138    }
139}
140
141impl From<DirectPosition> for parry3d_f64::math::Point<f64> {
142    fn from(item: DirectPosition) -> Self {
143        Self::new(item.x, item.y, item.z)
144    }
145}
146
147impl From<DirectPosition> for parry3d_f64::math::Point<f32> {
148    fn from(item: DirectPosition) -> Self {
149        Self::new(item.x as f32, item.y as f32, item.z as f32)
150    }
151}
152
153impl From<parry3d_f64::math::Point<f64>> for DirectPosition {
154    fn from(item: parry3d_f64::math::Point<f64>) -> Self {
155        Self::new(item.x, item.y, item.z).expect("Should work")
156    }
157}