xref: /StarryEngine/starry_client/src/base/graphicspath.rs (revision bee61dca287acb4b9fd6d747ba3f687aebacab90)
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 
60             x += 2.0 * u * t * (argx1 as f32);
61             y += 2.0 * u * t * (argy1 as f32);
62 
63             x += tt * (argx2 as f32);
64             y += tt * (argy2 as f32);
65 
66             t += 0.01;
67             self.points.push((x as i32, y as i32, PointType::Connect));
68         }
69 
70         self.x = argx2;
71         self.y = argy2;
72     }
73 
74     /// 绘制一条三次贝塞尔曲线
75     pub fn cubic_bezier_curve_to(
76         &mut self,
77         argx1: i32,
78         argy1: i32,
79         argx2: i32,
80         argy2: i32,
81         argx3: i32,
82         argy3: i32,
83     ) {
84         let mut t: f32 = 0.0;
85         let mut u: f32;
86         let mut tt: f32;
87         let mut uu: f32;
88         let mut uuu: f32;
89         let mut ttt: f32;
90         let mut x: f32;
91         let mut y: f32;
92 
93         // 根据三次贝塞尔曲线公式,构造一百个点
94         while t < 1.0 {
95             u = 1.0 - t;
96             tt = t * t;
97             uu = u * u;
98             uuu = uu * u;
99             ttt = tt * t;
100 
101             x = (self.x as f32) * uuu;
102             y = (self.y as f32) * uuu;
103 
104             x += 3.0 * uu * t * (argx1 as f32);
105             y += 3.0 * uu * t * (argy1 as f32);
106 
107             x += 3.0 * u * tt * (argx2 as f32);
108             y += 3.0 * u * tt * (argy2 as f32);
109 
110             x += ttt * (argx3 as f32);
111             y += ttt * (argy3 as f32);
112 
113             t += 0.01;
114             self.points.push((x as i32, y as i32, PointType::Connect));
115         }
116 
117         self.x = argx3;
118         self.y = argy3;
119     }
120 }
121