1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// SPDX-License-Identifier: ISC
use crate::point::Point3;
use crate::value::GroupValue;
/// An ELLIPSE entity.
///
/// Defaults to a full ellipse (`start_parameter` = 0, `end_parameter` = 2π).
#[derive(Debug, Clone, Copy)]
pub struct Ellipse {
/// Center point.
pub center: Point3,
/// Major axis endpoint relative to center.
///
/// The length of this vector is the semi-major axis length, and
/// its direction defines the ellipse's orientation.
pub major_axis: Point3,
/// Ratio of minor axis to major axis.
///
/// A value of 1.0 produces a circle; values closer to 0
/// produce increasingly eccentric ellipses.
pub minor_axis_ratio: f64,
/// Start parameter in radians.
///
/// This is the eccentric anomaly, not the geometric angle. For a
/// full ellipse this is 0. For an elliptical arc, the geometric
/// start angle can be recovered with `atan2(sin(t) * b, cos(t) * a)`
/// where `a` and `b` are the semi-major and semi-minor axis lengths.
pub start_parameter: f64,
/// End parameter in radians.
///
/// For a full ellipse this is 2π.
pub end_parameter: f64,
}
impl Default for Ellipse {
fn default() -> Self {
Self {
center: Point3::default(),
major_axis: Point3::default(),
minor_axis_ratio: 1.0,
start_parameter: 0.0,
end_parameter: core::f64::consts::TAU,
}
}
}
impl Ellipse {
pub(crate) fn feed(&mut self, code: u16, val: &GroupValue) {
if let Some(v) = val.as_f64() {
match code {
10 => self.center.x = v,
20 => self.center.y = v,
30 => self.center.z = v,
11 => self.major_axis.x = v,
21 => self.major_axis.y = v,
31 => self.major_axis.z = v,
40 => self.minor_axis_ratio = v,
41 => self.start_parameter = v,
42 => self.end_parameter = v,
_ => {}
}
}
}
}