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