C# 簡單實現直線方程,拋物線方程


本例子是簡單的在WinForm程序中實現在坐標系中繪制直線方程,拋物線方程,點。重新學習解析幾何方面的知識。僅供學習分享使用,如有不足之處,還請指正。

涉及知識點:

  • 直線方程的表達方式:一般表達式Ax+By+C=0
  • 拋物線表達式:y=Ax2+Bx+C
  • 坐標轉換:由於WinForm中的坐標原點是左上角,數學二維坐標系的原點是在中間,所以需要轉換
  • 單位轉換:WinForm的單位是Pixls,但坐標系的單位不是,需要進行縮放。
  • 畫圖方法:程序中使用GDI+進行畫圖。

----------------------------------------------------------------------------------------------------------------------

效果圖

如下:

---------------------------------------------------------------------------------------------------------

多邊形擴展

【如下圖所示】

//求多邊形對應的邊的平行線,然后再求相鄰平行線的交點,連起來即是擴展多邊形

核心算法

主要代碼如下:

【方程類】

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 
  6 namespace DemoGeometry
  7 {
  8     /// <summary>
  9     /// 方程基類
 10     /// </summary>
 11     public abstract class Equation
 12     {
 13         public int A { get; set; }
 14         public int B { get; set; }
 15         public int C { get; set; }
 16 
 17         /// <summary>
 18         /// 判斷是否有效
 19         /// </summary>
 20         /// <returns></returns>
 21         public abstract bool IsValid();
 22 
 23         /// <summary>
 24         /// 通過Y值獲取x值
 25         /// </summary>
 26         /// <param name="y"></param>
 27         /// <returns></returns>
 28         public abstract float GetValueFromY(float y);
 29         /// <summary>
 30         /// 通過X獲取Y值
 31         /// </summary>
 32         /// <param name="x"></param>
 33         /// <returns></returns>
 34         public abstract float GetValueFromX(float x);
 35     }
 36 
 37     /// <summary>
 38     /// 直線方程類一般式:Ax+By+C=0(A、B不同時為0)【適用於所有直線】
 39     /// </summary>
 40     public class LinearEquation:Equation
 41     {
 42         /// <summary>
 43         /// 通過X值得到Y值
 44         /// </summary>
 45         /// <param name="x"></param>
 46         /// <returns></returns>
 47         public override float GetValueFromX(float x)
 48         {
 49             if (B == 0)
 50             {
 51                 return float.MaxValue;
 52             }
 53             return -A * x * 1.0f / B - C * 1.0f / B;
 54         }
 55 
 56         public override float GetValueFromY(float y)
 57         {
 58             if (A == 0)
 59             {
 60                 return float.MaxValue;
 61             }
 62             return -B * y * 1.0f / A - C * 1.0f / A;
 63         }
 64 
 65         /// <summary>
 66         /// 判斷是否有效方程
 67         /// </summary>
 68         /// <returns></returns>
 69         public override bool IsValid()
 70         {
 71             bool flag = true;
 72             if (A == 0 && B == 0)
 73             {
 74                 flag = false;
 75             }
 76             return flag;
 77         }
 78 
 79         public override string ToString()
 80         {
 81             return string.Format("{0}x+{1}y+{2}=0", A, B, C);
 82         }
 83     }
 84 
 85     /// <summary>
 86     /// 拋物線方程表達式 y=ax2+bx+c
 87     /// </summary>
 88     public class ParabolicEquation:Equation
 89     {
 90 
 91         /// <summary>
 92         /// 判斷是否有效的方程
 93         /// </summary>
 94         /// <returns></returns>
 95         public override bool IsValid()
 96         {
 97             //A 不得等於0
 98             return A != 0;
 99         }
100 
101         /// <summary>
102         /// 通過X值得到Y值
103         /// </summary>
104         /// <param name="x"></param>
105         /// <returns></returns>
106         public override float GetValueFromX(float x)
107         {
108             double y = A * Math.Pow(x, 2) + B * x + C;
109             return float.Parse(y.ToString());
110         }
111 
112         public override float GetValueFromY(float y)
113         {
114             return 0.0f;
115         }
116     }
117 }
View Code

【控件類】

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Drawing;
  5 using System.Data;
  6 using System.Linq;
  7 using System.Text;
  8 using System.Windows.Forms;
  9 
 10 namespace DemoGeometry
 11 {
 12     /// <summary>
 13     /// 坐標系控件
 14     /// </summary>
 15     public partial class AxisControl : UserControl
 16     {
 17         #region 屬性
 18 
 19         private Axis _AxisX = new Axis() {  XName = "x" };
 20         /// <summary>
 21         /// X軸
 22         /// </summary>
 23         public Axis AxisX { get { return this._AxisX; }  }
 24 
 25         private Axis _AxisY = new Axis() { XName = "y" };
 26         /// <summary>
 27         /// Y軸
 28         /// </summary>
 29         public Axis AxisY { get { return this._AxisY; } }
 30 
 31         /// <summary>
 32         /// 邊界留空白
 33         /// </summary>
 34         private int bound = 10;
 35 
 36         public int Bound
 37         {
 38             get { return bound; }
 39             set { bound = value; }
 40         }
 41 
 42         /// <summary>
 43         /// 表示單位,10個像素表示1
 44         /// </summary>
 45         private int unit = 30;
 46 
 47         public int Unit
 48         {
 49             get { return unit; }
 50             set { unit = value; }
 51         }
 52 
 53         /// <summary>
 54         /// 文本字體
 55         /// </summary>
 56         private Font t_Font = new Font("Arial", 10F);
 57 
 58         private PointF center;
 59 
 60         private int index = 0;
 61 
 62         private int lineWidth = 2;
 63 
 64         #endregion
 65 
 66         public AxisControl()
 67         {
 68             InitializeComponent();
 69         }
 70 
 71         private void InitInfo() {
 72             //繪制坐標軸
 73             var width = this.Width * 1.0f;
 74             var height = this.Height * 1.0f;
 75             center = new PointF(width / 2, height / 2);
 76         }
 77 
 78         /// <summary>
 79         /// 重繪界面函數
 80         /// </summary>
 81         /// <param name="e"></param>
 82         protected override void OnPaint(PaintEventArgs e)
 83         {
 84             base.OnPaint(e);
 85             InitInfo();
 86             Graphics g = e.Graphics;
 87             var width = this.Width * 1.0f;
 88             var height = this.Height * 1.0f;
 89             Pen pen = new Pen(Color.Black);
 90             var left = new PointF(bound,center.Y);//
 91             var right = new PointF(width - bound, center.Y);
 92             var bottom = new PointF(center.X, height - bound);
 93             var top = new PointF(center.X, bound);
 94             g.DrawString("0", t_Font, Brushes.Black, new PointF(center.X + bound/2, center.Y+bound/2));
 95             //畫X軸,X軸的箭頭
 96             g.DrawLine(pen, left, right);
 97             g.DrawLine(pen, new PointF(right.X - bound/2, right.Y - bound/2), right);
 98             g.DrawLine(pen, new PointF(right.X - bound/2, right.Y + bound/2), right);
 99             var xName = string.IsNullOrEmpty(this._AxisX.XName) ? "x" : this._AxisX.XName;
100             g.DrawString(xName, t_Font, Brushes.Black, new PointF(right.X - bound, right.Y + 2 * bound));
101             //繪制X軸的刻度
102             var xMax = Math.Floor((right.X - left.X) / (2*unit));//
103             this._AxisX.Max = int.Parse( xMax.ToString());
104             for (var i = 0; i < xMax; i++) {
105                 //正刻度
106                 g.DrawLine(pen, new PointF(center.X + (i + 1) * unit, center.Y), new PointF(center.X + (i + 1) * unit, center.Y - 2));
107                 g.DrawString((i + 1).ToString(), t_Font, Brushes.Black, new PointF(center.X + (i + 1) * unit, center.Y+2));
108                 //負刻度
109                 g.DrawLine(pen, new PointF(center.X - (i + 1) * unit, center.Y), new PointF(center.X - (i + 1) * unit, center.Y - 2));
110                 g.DrawString("-"+(i + 1).ToString(), t_Font, Brushes.Black, new PointF(center.X - (i + 1) * unit, center.Y + 2));
111             }
112             //畫Y軸,Y軸的箭頭
113             g.DrawLine(pen, bottom, top);
114             g.DrawLine(pen, new PointF(top.X - bound/2, top.Y + bound/2), top);
115             g.DrawLine(pen, new PointF(top.X + bound/2, top.Y + bound/2), top);
116             var yName = string.IsNullOrEmpty(_AxisY.XName) ? "y" : _AxisY.XName;
117             g.DrawString(AxisY.XName, t_Font, Brushes.Black, new PointF(top.X + 2 * bound, top.Y - bound));
118             //繪制Y軸的刻度
119             var yMax = Math.Floor((bottom.Y - top.Y) / (2 * unit));//
120             this._AxisY.Max = int.Parse(yMax.ToString());
121             for (var i = 0; i < yMax; i++)
122             {
123                 //正刻度
124                 g.DrawLine(pen, new PointF(center.X , center.Y- (i + 1) * unit), new PointF(center.X+ 2 , center.Y- (i + 1) * unit ));
125                 g.DrawString((i + 1).ToString(), t_Font, Brushes.Black, new PointF(center.X+ 2 , center.Y- (i + 1) * unit));
126                 //負刻度
127                 g.DrawLine(pen, new PointF(center.X, center.Y + (i + 1) * unit), new PointF(center.X+ 2, center.Y + (i + 1) * unit ));
128                 g.DrawString("-" + (i + 1).ToString(), t_Font, Brushes.Black, new PointF(center.X+ 2 , center.Y+ (i + 1) * unit ));
129             }
130         }
131 
132         /// <summary>
133         /// 判斷直線方程是否在坐標軸范圍內
134         /// </summary>
135         /// <param name="linear"></param>
136         /// <returns></returns>
137         public bool CheckLineIsValid(LinearEquation linear)
138         {
139             bool flagX = false;
140             bool flagY = false;
141             var y = linear.GetValueFromX(0f);
142 
143             //判斷y坐標的值有沒有越界
144             if (y == float.MaxValue)
145             {
146                 //表示是垂直於x軸的直線
147                 var x0 = -linear.C*1.0f / linear.A;
148                 if (x0 >= 0 - this._AxisX.Max && x0 < this._AxisX.Max)
149                 {
150                     flagY = true;
151                 }
152                 else
153                 {
154                     flagY = false;
155                 }
156                 
157             }
158             else
159             {
160                 if (y <= this._AxisY.Max && y >= 0 - this._AxisY.Max)
161                 {
162                     flagY = true;
163                 }
164                 else
165                 {
166                     flagY = false;
167                 }
168             }
169             //判斷x坐標的值
170             var x = linear.GetValueFromY(0f);
171             if (x == float.MaxValue)
172             {
173                 var y0 = -linear.C*1.0f / linear.B;
174 
175                 if (y0 <= this._AxisY.Max && y0 >= 0 - this._AxisY.Max)
176                 {
177                     flagX = true;
178                 }
179                 else
180                 {
181                     flagX = false;
182                 }
183             }
184             else
185             {
186                 if (x <= this._AxisX.Max && x >= 0 - this._AxisX.Max)
187                 {
188                     flagX = true;
189                 }
190                 else
191                 {
192                     flagX = false;
193                 }
194             }
195 
196             return flagX && flagY;//只有x,y都滿足條件,才是有效的
197         }
198 
199         /// <summary>
200         /// 判斷點是否在坐標軸范圍內
201         /// </summary>
202         /// <returns></returns>
203         public bool CheckPointIsValid(PointF point)
204         {
205             bool flagX = false;
206             bool flagY = false;
207             if (point.X <= this._AxisX.Max && point.X >= 0 - this._AxisX.Max)
208             {
209                 flagX = true;
210             }
211             if (point.Y <= this._AxisY.Max && point.Y >= 0 - this._AxisY.Max)
212             {
213                 flagY = true;
214             }
215             return flagX && flagY;
216         }
217 
218         /// <summary>
219         /// 檢查拋物線方程是否有效
220         /// </summary>
221         /// <param name="parabolic"></param>
222         /// <returns></returns>
223         public bool CheckParabolicIsValid(ParabolicEquation parabolic) {
224             List<PointF> lstPoint = GetPointFromEquation(parabolic);
225             if (lstPoint.Count > 2)
226             {
227                 return true;
228             }
229             else {
230                 return false;
231             }
232         }
233 
234         /// <summary>
235         /// 將刻度轉換成像素
236         /// </summary>
237         public List<PointF> ConvertScaleToPixls(List<PointF> lstScale)
238         {
239             List<PointF> lstPixls = new List<PointF>();
240             if (lstScale != null && lstScale.Count > 0) {
241                 var p = lstScale.Select(s => new PointF(center.X + s.X * unit, center.Y - s.Y * unit));
242                 lstPixls = p.ToList();
243             }
244             return lstPixls;
245         }
246 
247         /// <summary>
248         /// 轉換刻度到像素
249         /// </summary>
250         /// <param name="s"></param>
251         /// <returns></returns>
252         public PointF ConvertScaleToPixls(PointF s)
253         {
254             return new PointF(center.X + s.X * unit, center.Y - s.Y * unit);
255         }
256 
257         /// <summary>
258         /// 生成直線
259         /// </summary>
260         /// <param name="linear"></param>
261         public bool GenerateLinear(LinearEquation linear) {
262 
263             Color lineColor = Color.Blue;//線條的顏色
264             Graphics g = this.CreateGraphics();
265             //分別獲取兩個端點的值,連成線即可
266             var x1 = this._AxisX.Max;
267             var y2 = this._AxisY.Max;
268             var x3 = 0 - this._AxisX.Max;
269             var y4 = 0 - this._AxisY.Max;
270             var y1 = linear.GetValueFromX(x1);
271             var x2 = linear.GetValueFromY(y2);
272             var y3 = linear.GetValueFromX(x3);
273             var x4 = linear.GetValueFromY(y4);
274             var point1 = new PointF(x1, y1);
275             var point2 = new PointF(x2, y2);
276             var point3 = new PointF(x3, y3);
277             var point4 = new PointF(x4, y4);
278             List<PointF> lstTmp = new List<PointF>() { point1, point2, point3, point4 };
279             List<PointF> lstPoint=new List<PointF>();
280             foreach (PointF point in lstTmp)
281             {
282                 //判斷點是否合理
283                 if (CheckPointIsValid(point))
284                 {
285                     lstPoint.Add(point);
286                 }
287             }
288             if (lstPoint.Count() < 2) {
289                 //如果點的個數小於2,不能繪制直線
290                 return false;
291             }
292             //將刻度點,轉換成像素點
293             List<PointF> lstPixlsPoint = ConvertScaleToPixls(lstPoint);
294             g.DrawLine(new Pen(lineColor,lineWidth),lstPixlsPoint[0],lstPixlsPoint[1]);
295             g.DrawString(string.Format("L{0}", index), t_Font, Brushes.Black, new PointF(lstPixlsPoint[1].X + 2, lstPixlsPoint[1].Y - 2));
296             this.lblInfo.Text += string.Format("L{0}:{1}x+{2}y+{3}=0 ; ", index, linear.A, linear.B, linear.C);
297             index++;
298             return true;
299         }
300 
301         /// <summary>
302         /// 生成點
303         /// </summary>
304         /// <param name="point"></param>
305         /// <returns></returns>
306         public bool GeneratePoint(PointF point)
307         {
308             Graphics g = this.CreateGraphics();
309             PointF p = ConvertScaleToPixls(point);
310             g.FillEllipse(Brushes.Red, p.X, p.Y, 4, 4);
311             g.DrawString(string.Format("P{0}", index), t_Font, Brushes.Black, new PointF(p.X + 4, p.Y - 4));
312             this.lblInfo.Text += string.Format("P{0}:({1},{2}) ; ", index, point.X, point.Y);
313             index++;
314             return true;
315         }
316 
317         public bool GenerateParabolic(ParabolicEquation parabolic)
318         {
319             List<PointF> lstPoint = GetPointFromEquation(parabolic);
320             //將刻度點,轉換成像素點
321             List<PointF> lstPixlsPoint = ConvertScaleToPixls(lstPoint);
322             Color lineColor = Color.SeaGreen;//線條的顏色
323             Graphics g = this.CreateGraphics();
324             g.DrawCurve(new Pen(lineColor,lineWidth), lstPixlsPoint.ToArray());
325             g.DrawString(string.Format("P{0}", index), t_Font, Brushes.Black, new PointF(lstPixlsPoint[1].X + 2, lstPixlsPoint[1].Y - 2));
326             this.lblInfo.Text += string.Format("P{0}:y={1}x2+{2}x+{3} ; ", index, parabolic.A, parabolic.B, parabolic.C);
327             index++;
328             return true;
329         }
330 
331         /// <summary>
332         /// 從拋物線方程中取點值
333         /// </summary>
334         /// <param name="parabolic"></param>
335         /// <returns></returns>
336         public List<PointF> GetPointFromEquation(ParabolicEquation parabolic) {
337             List<PointF> lstPoint = new List<PointF>();
338             //從坐標軸最小值開始,隔0.5 取一個
339             int j=0;
340             for (float i = 0 - this._AxisX.Max; i <= this._AxisX.Max; i = i + 0.5f)
341             {
342                 PointF p = new PointF(i, parabolic.GetValueFromX(i));
343                 //再判斷點是否在坐標軸內
344                 if (CheckPointIsValid(p) && (j==0 || lstPoint[j-1].X==i-0.5f))
345                 {
346                     lstPoint.Add(p);//拋物線內的點應該是連續的
347                     j++;
348                 }
349             }
350             return lstPoint;
351         }
352 
353         /// <summary>
354         /// 清除已經畫上去的線條
355         /// </summary>
356         /// <returns></returns>
357         public bool Clear() {
358             Graphics g = this.CreateGraphics();
359             g.Clear(Color.White);
360             this.lblInfo.Text = "";
361             this.Refresh();//重新刷新界面,清除已經畫上去的線條
362             index = 0;
363             return true;
364         }
365     }
366 
367     /// <summary>
368     /// 坐標軸描述
369     /// </summary>
370     public class Axis{
371 
372         /// <summary>
373         /// 刻度表示最大值
374         /// </summary>
375         public int Max { get; set; }
376 
377         /// <summary>
378         /// 名稱
379         /// </summary>
380         public string XName{get;set;}
381 
382         ///// <summary>
383         ///// 間隔
384         ///// </summary>
385         //public int Interval{get;set;}
386     }
387 }
View Code

【主界面類】

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 using System.Linq;
  7 using System.Text;
  8 using System.Windows.Forms;
  9 
 10 namespace DemoGeometry
 11 {
 12     public partial class MainForm : Form
 13     {
 14         public MainForm()
 15         {
 16             InitializeComponent();
 17         }
 18 
 19         private void btnLine_Click(object sender, EventArgs e)
 20         {
 21             if (this.linearControl1.IsValid())
 22             {
 23                 var a = this.linearControl1.A;
 24                 var b = this.linearControl1.B;
 25                 var c = this.linearControl1.C;
 26                 //判斷方程的參數,是否有效
 27                 LinearEquation linear = new LinearEquation() { A = a, B = b, C = c };
 28                 if (!linear.IsValid())
 29                 {
 30                     MessageBox.Show("輸入的方程參數無效");
 31                     return;
 32                 }
 33                 if (!this.axisControl1.CheckLineIsValid(linear))
 34                 {
 35                     MessageBox.Show("輸入的方程不在坐標軸內");
 36                     return;
 37                 }
 38                 bool flag = this.axisControl1.GenerateLinear(linear);
 39                 if (!flag)
 40                 {
 41                     MessageBox.Show("生成直線失敗");
 42                     return;
 43                 }
 44             }
 45         }
 46 
 47         private void btnClear_Click(object sender, EventArgs e)
 48         {
 49             this.axisControl1.Clear();
 50         }
 51 
 52         private void btnPoint_Click(object sender, EventArgs e)
 53         {
 54             if (this.pointControl1.IsValid())
 55             {
 56                 float x = this.pointControl1.X;
 57                 float y = this.pointControl1.Y;
 58                 PointF point = new PointF(x, y);
 59                 if (!this.axisControl1.CheckPointIsValid(point)) {
 60                     MessageBox.Show("輸入的點不在坐標軸內");
 61                     return;
 62                 }
 63                 bool flag = this.axisControl1.GeneratePoint(point);
 64                 if (!flag)
 65                 {
 66                     MessageBox.Show("生成點失敗");
 67                     return;
 68                 }
 69             }
 70             
 71         }
 72 
 73         private void btnParabolic_Click(object sender, EventArgs e)
 74         {
 75             if (this.parabolicControl1.IsValid())
 76             {
 77                 var a = this.parabolicControl1.A;
 78                 var b = this.parabolicControl1.B;
 79                 var c = this.parabolicControl1.C;
 80                 //判斷方程的參數,是否有效
 81                 ParabolicEquation parabolic = new ParabolicEquation() { A = a, B = b, C = c };
 82                 if (!parabolic.IsValid())
 83                 {
 84                     MessageBox.Show("輸入的方程參數無效");
 85                     return;
 86                 }
 87                 if (!this.axisControl1.CheckParabolicIsValid(parabolic))
 88                 {
 89                     MessageBox.Show("輸入的方程不在坐標軸內");
 90                     return;
 91                 }
 92                 bool flag = this.axisControl1.GenerateParabolic(parabolic);
 93                 if (!flag)
 94                 {
 95                     MessageBox.Show("生成拋物線失敗");
 96                     return;
 97                 }
 98             }
 99         }
100     }
101 }
View Code

 【擴展多邊形代碼】

  1  /// <summary>
  2         /// 生成多邊形
  3         /// </summary>
  4         /// <param name="lstPoints"></param>
  5         /// <returns></returns>
  6         public bool GeneratePolygon(List<PointF> lstPoints ,bool isOriginal=true) {
  7 
  8             Color lineColor = Color.Red;//線條的顏色
  9             if (isOriginal)
 10             {
 11                 lineColor = Color.Red;
 12             }
 13             else {
 14                 lineColor = Color.Blue;
 15             }
 16             
 17             Graphics g = this.CreateGraphics();
 18             //畫點
 19             foreach (var p in lstPoints) {
 20                 this.GeneratePoint(p);
 21             }
 22             //將刻度點,轉換成像素點
 23             List<PointF> lstPixlsPoint = ConvertScaleToPixls(lstPoints);
 24             //繪制多邊形
 25             g.DrawPolygon(new Pen(lineColor,2), lstPixlsPoint.ToArray());
 26             return true;
 27         }
 28 
 29         /// <summary>
 30         /// 擴展多邊形,即在現有多邊形的基礎上進行擴展
 31         /// </summary>
 32         /// <param name="lstPoints"></param>
 33         /// <returns></returns>
 34         public bool GenerateExpandPolygon(List<PointF> lstPoints,PointF center,float distance) {
 35             //1.求多邊形對應的外擴平行斜線
 36             List<LinearEquation> lstLines = new List<LinearEquation>();
 37             int len = lstPoints.Count();
 38             for (int i = 0; i < len; i++) {
 39                 var p0 = lstPoints[i];//第i個元素
 40                 var p1 = lstPoints[(i + 1) % len];//第i+1個元素
 41                 LinearEquation linearEquation = new LinearEquation();
 42                 if (p0.X == p1.X)
 43                 {
 44                     //垂直於x軸,沒有斜率
 45                     linearEquation.A = 1;
 46                     linearEquation.B = 0;
 47                     if (p0.X > center.X)
 48                     {
 49                         linearEquation.C = -(p0.X + distance);
 50                     }
 51                     else {
 52                         linearEquation.C = -(p0.X - distance);
 53                     }
 54                     
 55                 }
 56                 else if (p0.Y == p1.Y)
 57                 {
 58                     //垂直於y軸,斜率為0
 59                     linearEquation.A = 0;
 60                     linearEquation.B = 1;
 61                     if (p0.Y > center.Y)
 62                     {
 63                         linearEquation.C = -(p0.Y + distance);
 64                     }
 65                     else {
 66                         linearEquation.C = -(p0.Y - distance);
 67                     }
 68                 }
 69                 else {
 70                     //先求兩點對應的點斜式方程y=kx+b
 71                     float k = (p0.Y - p1.Y) / (p0.X - p1.X);
 72                     float b = p0.Y - k * p0.X;
 73                     //求出平行線對應的b即可。
 74                     float b_center = center.Y - k * center.X;
 75                     linearEquation.A = k;
 76                     linearEquation.B = -1;//如果此處為-1,則C=b
 77 
 78                     if (b > b_center)
 79                     {
 80                         //如果在原點上方
 81 
 82                         linearEquation.C =(b+(float) Math.Abs((distance/(Math.Sin(-Math.PI/2-Math.Atan(k))))));
 83                     }
 84                     else {
 85                         //如果在原點下方
 86                         linearEquation.C = (b - (float)Math.Abs((distance / (Math.Sin(-Math.PI / 2 - Math.Atan(k))))));
 87                     }
 88                 }
 89                 //this.GenerateLinear(linearEquation);
 90                 lstLines.Add(linearEquation);
 91             }
 92             List<PointF> lstNewPoints = new List<PointF>();
 93             //2.求相鄰外擴平行斜線的交點
 94             for (int i = 0; i < len; i++) {
 95                 var line0 = lstLines[i];
 96                 var line1 = lstLines[(i + 1) % len];
 97                 float x = 0.0f;
 98                 float y = 0.0f;
 99                 if (line0.A == 0.0f)
100                 {
101                     y = -line0.C / line0.B;
102                     x= line1.GetValueFromY(y);
103                 }
104                 else if (line0.B == 0.0f)
105                 {
106                     x = -line0.C / line0.A;
107                     y = line1.GetValueFromX(x);
108                 }
109                 else if (line1.A == 0.0f)
110                 {
111                     y = -line1.C / line1.B;
112                     x = line0.GetValueFromY(y);
113                 }
114                 else if (line1.B == 0.0f)
115                 {
116                     x = -line1.C / line1.A;
117                     y = line0.GetValueFromX(x);
118                 }
119                 else {
120                     //兩個都有斜率的直線的交點
121                     float k0 = -line0.A / line0.B;
122                     float k1 = -line1.A / line1.B;
123                     float b0 = -line0.C / line0.B;
124                     float b1 = -line1.C / line1.B;
125                     x = (b1 - b0) / (k0 - k1);
126                     y = line0.GetValueFromX(x);
127                 }
128                 lstNewPoints.Add(new PointF(x, y));
129             }
130             this.GeneratePolygon(lstNewPoints, false);
131             //
132             return true;
133         }
View Code

 備注:源碼 點擊下方鏈接

源碼下載


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM