C# 实现Bezier曲线(vs2008)

时间:2022-09-10 21:02:20
  1 using System;
  2 
  3 using System.Collections.Generic;
  4 
  5 using System.ComponentModel;
  6 
  7 using System.Data;
  8 
  9 using System.Drawing;
 10 
 11 using System.Linq;
 12 
 13 using System.Text;
 14 
 15 using System.Windows.Forms;
 16 
 17  
 18 
 19 namespace doBezier
 20 
 21 {
 22 
 23     public partial class Form1 : Form
 24 
 25     {
 26 
 27         PointF[] p = new PointF[100];   //存储控制点坐标
 28 
 29         int count;                    //记录已输入的控制点个数
 30 
 31         Graphics g;                  //GDI 对象
 32 
 33  
 34 
 35         public Form1()
 36 
 37         {
 38 
 39             InitializeComponent();
 40 
 41             g = CreateGraphics();
 42 
 43             count = 0;
 44 
 45         }
 46 
 47  
 48 
 49         private void Form1_Load(object sender, EventArgs e)
 50 
 51         {
 52 
 53  
 54 
 55         }
 56 
 57  
 58 
 59         private void Form1_MouseClick(object sender, MouseEventArgs e)
 60 
 61         {
 62 
 63             if (e.Button == MouseButtons.Left)
 64 
 65             {
 66 
 67                 if (count == 0)      //如果输入的是第一个点,先清空窗口
 68 
 69                     g.Clear(BackColor);
 70 
 71  
 72 
 73                 g.FillRectangle(Brushes.Red, e.X - 2, e.Y - 2, 4, 4);  //输出一个标记
 74 
 75                 p[count] = new PointF(e.X, e.Y);                 //存储
 76 
 77                 count ;                                    //记录输入控制点个数
 78 
 79                 return;
 80 
 81             }
 82 
 83             else
 84 
 85             {
 86 
 87                 PointF q1 = new PointF();
 88 
 89                 PointF q2 = new PointF();
 90 
 91                 double u;
 92 
 93  
 94 
 95                 for (int i = 0; i <= 100; i )//生成100个点并连成折线
 96 
 97                 {
 98 
 99                     u = (double)i / 100.0;
100 
101                     if (i == 0)
102 
103                     {
104 
105                         q1 = deCasteljau(u);
106 
107                     }
108 
109                     else
110 
111                     {
112 
113                         q2 = deCasteljau(u);
114 
115                         g.DrawLine(Pens.Black, q1, q2);
116 
117                         q1.X = q2.X;
118 
119                         q1.Y = q2.Y;
120 
121                     }
122 
123                 }
124 
125                 count = 0;
126 
127                 return;
128 
129             }
130 
131         }
132 
133  
134 
135         PointF deCasteljau(double u)   //曲线参数为u,函数返回一个二维点 
136 
137         {
138 
139             int i, k;
140 
141             //以下将控制点数组p[],复制到数组q[]
142 
143             PointF[] q = new PointF[100];
144 
145             for (i = 0; i < count; i )
146 
147             {
148 
149                 q[i].X = p[i].X;
150 
151                 q[i].Y = p[i].Y;
152 
153             }
154 
155             //以下用de Casteljau割角算法计算bezier曲线上参数点u对应的x,y,
156 
157             //计算完成后,结果存储在q[0]
158 
159             for (k = 1; k < count; k )
160 
161                 for (i = 0; i < count - k; i )
162 
163                 {
164 
165                     q[i].X = (float)(1.0 - u) * q[i].X   (float)u * q[i   1].X;
166 
167                     q[i].Y = (float)(1.0 - u) * q[i].Y   (float)u * q[i   1].Y;
168 
169                 }
170 
171             return new PointF(q[0].X, q[0].Y);
172 
173         }
174 
175  
176 
177         private void Form1_Paint(object sender, PaintEventArgs e)
178 
179         {
180 
181  
182 
183         }
184 
185     }
186 
187 }