zoukankan      html  css  js  c++  java
  • 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

     备注:源码 点击下方链接

    源码下载

  • 相关阅读:
    转:Loadrunner——Block(块)技术
    转:Linux基本命令大全
    转:Loadrunner打开https报错“Internet…
    转:对TCP/IP网络协议的深入浅出归纳
    10.2.1 支持的网络视频类型
    10.2 网络视频
    10.1.2 完整的MediaStore视频示例
    10.1.1 来自MediaStore的视频缩略图
    10.1 使用MediaStore检索视频
    第10章 视频进阶
  • 原文地址:https://www.cnblogs.com/hsiang/p/6294864.html
Copyright © 2011-2022 走看看