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