xref: /StarryEngine/starry_client/src/base/graphicspath.rs (revision 1c11e7de96780739183c72b37d2ef00a30237651)
1 /// 路径中点的类型
2 pub enum PointType {
3     Move,
4     Connect,
5 }
6 
7 /// 表示一条几何路径
8 pub struct GraphicsPath {
9     /// 当前点x坐标
10     x: i32,
11     /// 当前点y坐标
12     y: i32,
13     /// 点集合
14     pub points: Vec<(i32, i32, PointType)>,
15 }
16 
17 #[allow(dead_code)]
18 impl GraphicsPath {
19     pub fn new() -> GraphicsPath {
20         GraphicsPath {
21             x: 0,
22             y: 0,
23             points: Vec::new(),
24         }
25     }
26 
27     /// 移动值指定点
28     pub fn move_to(&mut self, x: i32, y: i32) {
29         self.points.push((x, y, PointType::Move));
30         self.x = x;
31         self.y = y;
32     }
33 
34     /// 连线至指定点
35     pub fn line_to(&mut self, x: i32, y: i32) {
36         self.points.push((x, y, PointType::Connect));
37         self.x = x;
38         self.y = y;
39     }
40 
41     /// 绘制一条二次贝塞尔曲线
42     pub fn quadratic_bezier_curve_to(&mut self, argx1: i32, argy1: i32, argx2: i32, argy2: i32) {
43         let mut t: f32 = 0.0;
44         let mut u: f32;
45         let mut tt: f32;
46         let mut uu: f32;
47         let mut x: f32;
48         let mut y: f32;
49 
50         // 根据二次贝塞尔曲线公式,构造一百个点
51         while t < 1.0 {
52             u = 1.0 - t;
53             uu = u * u;
54             tt = t * t;
55 
56             x = (self.x as f32) * uu;
57             y = (self.y as f32) * uu;
58 
59             x += 2.0 * u * t * (argx1 as f32);
60             y += 2.0 * u * t * (argy1 as f32);
61 
62             x += tt * (argx2 as f32);
63             y += tt * (argy2 as f32);
64 
65             t += 0.01;
66             self.points.push((x as i32, y as i32, PointType::Connect));
67         }
68 
69         self.x = argx2;
70         self.y = argy2;
71     }
72 
73     /// 绘制一条三次贝塞尔曲线
74     pub fn cubic_bezier_curve_to(
75         &mut self,
76         argx1: i32,
77         argy1: i32,
78         argx2: i32,
79         argy2: i32,
80         argx3: i32,
81         argy3: i32,
82     ) {
83         let mut t: f32 = 0.0;
84         let mut u: f32;
85         let mut tt: f32;
86         let mut uu: f32;
87         let mut uuu: f32;
88         let mut ttt: f32;
89         let mut x: f32;
90         let mut y: f32;
91 
92         // 根据三次贝塞尔曲线公式,构造一百个点
93         while t < 1.0 {
94             u = 1.0 - t;
95             tt = t * t;
96             uu = u * u;
97             uuu = uu * u;
98             ttt = tt * t;
99 
100             x = (self.x as f32) * uuu;
101             y = (self.y as f32) * uuu;
102 
103             x += 3.0 * uu * t * (argx1 as f32);
104             y += 3.0 * uu * t * (argy1 as f32);
105 
106             x += 3.0 * u * tt * (argx2 as f32);
107             y += 3.0 * u * tt * (argy2 as f32);
108 
109             x += ttt * (argx3 as f32);
110             y += ttt * (argy3 as f32);
111 
112             t += 0.01;
113             self.points.push((x as i32, y as i32, PointType::Connect));
114         }
115 
116         self.x = argx3;
117         self.y = argy3;
118     }
119 }
120