theta_chart/coord/
arc.rs

1use crate::{
2    coord::{Point, Vector},
3    TAU,
4};
5
6#[derive(Debug, Default, Clone)]
7pub struct Arc {
8    pub origin: Point,
9    pub begin: Vector,
10    pub end: Vector,
11    pub sweep: bool,
12    pub large: bool,
13}
14
15impl Arc {
16    pub fn new(origin: Point, begin: Vector, end: Vector, large: bool) -> Self {
17        Self {
18            origin,
19            begin,
20            end,
21            sweep: true,
22            large,
23        }
24    }
25
26    pub fn new_polar(origin: Point, begin: Vector, tau: f64) -> Self {
27        let end = begin.clone().az_rotate_tau(tau);
28        let large = tau.abs() >= TAU / 2.0;
29        Self {
30            origin,
31            begin,
32            end,
33            sweep: true,
34            large,
35        }
36    }
37
38    pub fn delta_xy(&self) -> (f64, f64) {
39        let end_point = self.end.to_point();
40        let begin_point = self.begin.to_point();
41        (
42            end_point.get_x() - begin_point.get_x(),
43            end_point.get_y() - begin_point.get_y(),
44        )
45    }
46
47    // TODO: cfg feature SVG
48    pub fn gen_path(&self, radius: f64) -> String {
49        let (dx, dy) = self.delta_xy();
50        format!(
51            "M 0,0 l {},{} a{},{}  0 {},1 {},{} Z",
52            self.begin.get_x() * radius,
53            self.begin.get_y() * radius,
54            radius,
55            radius,
56            self.large as i32,
57            dx * radius,
58            dy * radius
59        )
60    }
61}