session_rust/
line.rs

1use crate::{Color, Point, Vector, Xform};
2use serde::{Deserialize, Serialize};
3use std::fmt;
4use std::ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Sub, SubAssign};
5use uuid::Uuid;
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8#[serde(tag = "type", rename = "Line")]
9pub struct Line {
10    pub guid: String,
11    pub name: String,
12    #[serde(rename = "x0")]
13    _x0: f32,
14    #[serde(rename = "y0")]
15    _y0: f32,
16    #[serde(rename = "z0")]
17    _z0: f32,
18    #[serde(rename = "x1")]
19    _x1: f32,
20    #[serde(rename = "y1")]
21    _y1: f32,
22    #[serde(rename = "z1")]
23    _z1: f32,
24    pub width: f32,
25    pub linecolor: Color,
26    #[serde(default = "Xform::identity")]
27    pub xform: Xform,
28}
29
30impl Default for Line {
31    fn default() -> Self {
32        Self {
33            _x0: 0.0,
34            _y0: 0.0,
35            _z0: 0.0,
36            _x1: 0.0,
37            _y1: 0.0,
38            _z1: 1.0,
39            guid: Uuid::new_v4().to_string(),
40            name: "my_line".to_string(),
41            linecolor: Color::white(),
42            width: 1.0,
43            xform: Xform::identity(),
44        }
45    }
46}
47
48impl Line {
49    pub fn new(x0: f32, y0: f32, z0: f32, x1: f32, y1: f32, z1: f32) -> Self {
50        Self {
51            _x0: x0,
52            _y0: y0,
53            _z0: z0,
54            _x1: x1,
55            _y1: y1,
56            _z1: z1,
57            ..Default::default()
58        }
59    }
60
61    pub fn from_points(p1: &Point, p2: &Point) -> Self {
62        Self::new(p1.x(), p1.y(), p1.z(), p2.x(), p2.y(), p2.z())
63    }
64
65    pub fn with_name(name: &str, x0: f32, y0: f32, z0: f32, x1: f32, y1: f32, z1: f32) -> Self {
66        Self {
67            name: name.to_string(),
68            _x0: x0,
69            _y0: y0,
70            _z0: z0,
71            _x1: x1,
72            _y1: y1,
73            _z1: z1,
74            ..Default::default()
75        }
76    }
77
78    pub fn x0(&self) -> f32 {
79        self._x0
80    }
81    pub fn y0(&self) -> f32 {
82        self._y0
83    }
84    pub fn z0(&self) -> f32 {
85        self._z0
86    }
87    pub fn x1(&self) -> f32 {
88        self._x1
89    }
90    pub fn y1(&self) -> f32 {
91        self._y1
92    }
93    pub fn z1(&self) -> f32 {
94        self._z1
95    }
96
97    pub fn set_x0(&mut self, v: f32) {
98        self._x0 = v;
99    }
100    pub fn set_y0(&mut self, v: f32) {
101        self._y0 = v;
102    }
103    pub fn set_z0(&mut self, v: f32) {
104        self._z0 = v;
105    }
106    pub fn set_x1(&mut self, v: f32) {
107        self._x1 = v;
108    }
109    pub fn set_y1(&mut self, v: f32) {
110        self._y1 = v;
111    }
112    pub fn set_z1(&mut self, v: f32) {
113        self._z1 = v;
114    }
115
116    pub fn length(&self) -> f32 {
117        let dx = self._x1 - self._x0;
118        let dy = self._y1 - self._y0;
119        let dz = self._z1 - self._z0;
120        (dx * dx + dy * dy + dz * dz).sqrt()
121    }
122
123    pub fn squared_length(&self) -> f32 {
124        let dx = self._x1 - self._x0;
125        let dy = self._y1 - self._y0;
126        let dz = self._z1 - self._z0;
127        dx * dx + dy * dy + dz * dz
128    }
129
130    pub fn to_vector(&self) -> Vector {
131        Vector::new(
132            self._x1 - self._x0,
133            self._y1 - self._y0,
134            self._z1 - self._z0,
135        )
136    }
137
138    pub fn point_at(&self, t: f32) -> Point {
139        let s = 1.0 - t;
140        Point::new(
141            s * self._x0 + t * self._x1,
142            s * self._y0 + t * self._y1,
143            s * self._z0 + t * self._z1,
144        )
145    }
146
147    pub fn start(&self) -> Point {
148        Point::new(self._x0, self._y0, self._z0)
149    }
150
151    pub fn end(&self) -> Point {
152        Point::new(self._x1, self._y1, self._z1)
153    }
154}
155
156impl Index<usize> for Line {
157    type Output = f32;
158
159    fn index(&self, index: usize) -> &Self::Output {
160        match index {
161            0 => &self._x0,
162            1 => &self._y0,
163            2 => &self._z0,
164            3 => &self._x1,
165            4 => &self._y1,
166            5 => &self._z1,
167            _ => panic!("Index out of bounds"),
168        }
169    }
170}
171
172impl IndexMut<usize> for Line {
173    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
174        match index {
175            0 => &mut self._x0,
176            1 => &mut self._y0,
177            2 => &mut self._z0,
178            3 => &mut self._x1,
179            4 => &mut self._y1,
180            5 => &mut self._z1,
181            _ => panic!("Index out of bounds"),
182        }
183    }
184}
185
186impl AddAssign<&Vector> for Line {
187    fn add_assign(&mut self, other: &Vector) {
188        self._x0 += other.x();
189        self._y0 += other.y();
190        self._z0 += other.z();
191        self._x1 += other.x();
192        self._y1 += other.y();
193        self._z1 += other.z();
194    }
195}
196
197impl SubAssign<&Vector> for Line {
198    fn sub_assign(&mut self, other: &Vector) {
199        self._x0 -= other.x();
200        self._y0 -= other.y();
201        self._z0 -= other.z();
202        self._x1 -= other.x();
203        self._y1 -= other.y();
204        self._z1 -= other.z();
205    }
206}
207
208impl MulAssign<f32> for Line {
209    fn mul_assign(&mut self, factor: f32) {
210        self._x0 *= factor;
211        self._y0 *= factor;
212        self._z0 *= factor;
213        self._x1 *= factor;
214        self._y1 *= factor;
215        self._z1 *= factor;
216    }
217}
218
219impl DivAssign<f32> for Line {
220    fn div_assign(&mut self, factor: f32) {
221        self._x0 /= factor;
222        self._y0 /= factor;
223        self._z0 /= factor;
224        self._x1 /= factor;
225        self._y1 /= factor;
226        self._z1 /= factor;
227    }
228}
229
230impl Add<&Vector> for Line {
231    type Output = Line;
232
233    fn add(self, other: &Vector) -> Line {
234        let mut result = self;
235        result += other;
236        result
237    }
238}
239
240impl Sub<&Vector> for Line {
241    type Output = Line;
242
243    fn sub(self, other: &Vector) -> Line {
244        let mut result = self;
245        result -= other;
246        result
247    }
248}
249
250impl Mul<f32> for Line {
251    type Output = Line;
252
253    fn mul(self, factor: f32) -> Line {
254        let mut result = self;
255        result *= factor;
256        result
257    }
258}
259
260impl Div<f32> for Line {
261    type Output = Line;
262
263    fn div(self, factor: f32) -> Line {
264        let mut result = self;
265        result /= factor;
266        result
267    }
268}
269
270impl fmt::Display for Line {
271    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
272        write!(
273            f,
274            "Line({}, {}, {}, {}, {}, {})",
275            self._x0, self._y0, self._z0, self._x1, self._y1, self._z1
276        )
277    }
278}
279
280impl Line {
281    pub fn jsondump(&self) -> Result<String, Box<dyn std::error::Error>> {
282        Ok(serde_json::to_string_pretty(self)?)
283    }
284
285    pub fn jsonload(json_data: &str) -> Result<Self, Box<dyn std::error::Error>> {
286        Ok(serde_json::from_str(json_data)?)
287    }
288}
289
290#[path = "line_test.rs"]
291#[cfg(test)]
292mod line_test;