C# 简单实现直线方程,抛物线方程

C# 简单实现直线方程,抛物线方程,第1张

概述C#根据直线方程抛物线方程进行画线。
绘制多边形,并在现有多边形基础上向外扩展出新的多边形

本例子是简单的在WinForm程序中实现在坐标系中绘制直线方程,抛物线方程,点。重新学习解析几何方面的知识。仅供学习分享使用,如有不足之处,还请指正。

涉及知识点:

直线方程的表达方式:一般表达式Ax+By+C=0抛物线表达式:y=Ax2+Bx+C坐标转换:由于WinForm中的坐标原点是左上角,数学二维坐标系的原点是在中间,所以需要转换单位转换:WinForm的单位是Pixls,但坐标系的单位不是,需要进行缩放。画图方法:程序中使用GDI+进行画图。

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

效果图

如下:

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

多边形扩展

【如下图所示】

//求多边形对应的边的平行线,然后再求相邻平行线的交点,连起来即是扩展多边形

核心算法

主要代码如下:

【方程类】

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

【控件类】

@H_866_502@

 System.ComponentModel; System.Drawing;  5  System.Data;  8  System.windows.Forms;  9  10  11  12      13      坐标系控件 14      15     partial  AxisControl : UserControl 16  17         #region 属性 18  19         private Axis _AxisX = new Axis() {  Xname = x }; 21          X轴 22          23         public Axis AxisX { get { this._AxisX; }  } 24  25         private Axis _AxisY = new Axis() { Xname = y Y轴 28          29         public Axis AxisY { ._AxisY; } } 30  边界留空白private int bound = 10 35  36         int Bound 37  38              bound; } 39             set { bound = value; } 40  41  表示单位,10个像素表示1 45         int unit = 30 46  Unit unit; } 50             set { unit = 51  52  53          54          文本字体 55         private Font t_Font = new Font(Arial 57  58         private PointF center; 59  60         int index =  61  62         int linewidth = 2 63  64         #endregion 65  66         public AxisControl() 67  68             InitializeComponent(); 69  70  71         voID InitInfo() {绘制坐标轴 73             var wIDth = this.WIDth * 1.0f 74             var height = this.Height *  75             center = new PointF(wIDth / 2,height / ); 76  77  78          79          重绘界面函数 80          81         <param name="e"></param> 82         protected  OnPaint(PaintEventArgs e) 84             base.OnPaint(e); 85             InitInfo(); 86             Graphics g = e.Graphics; 87              88              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 =  PointF(center.X,bound); 94             g.DrawString(0",t_Font,Brushes.Black,new PointF(center.X + bound/)); 95             画X轴,X轴的箭头            g.Drawline(pen,left,right); 97             g.Drawline(pen,1)">new PointF(right.X - bound/),1)"> 98             g.Drawline(pen,right.Y + bound/ 99             var xname = string.IsNullOrEmpty(this._AxisX.Xname) ? " : ._AxisX.Xname;100             g.DrawString(xname,1)">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 = .Parse( xMax.ToString());104             for (var i = 0; i < xMax; i++) {105                 正刻度106                 g.Drawline(pen,1)">new PointF(center.X + (i + 1) * unit,center.Y),center.Y - 107                 g.DrawString((i + 1).ToString(),center.Y+108                 负刻度109                 g.Drawline(pen,1)">new PointF(center.X - (i + 110                 g.DrawString(-"+(i + 111 112             画Y轴,Y轴的箭头114             g.Drawline(pen,1)">new PointF(top.X - bound/115             g.Drawline(pen,1)">new PointF(top.X + bound/116             var yname = string.IsNullOrEmpty(_AxisY.Xname) ?  : _AxisY.Xname;117             g.DrawString(AxisY.Xname,1)">new PointF(top.X + 2 * bound,top.Y -118             绘制Y轴的刻度119             var yMax = Math.Floor((bottom.Y - top.Y) / (2 * unit));120             this._AxisY.Max = .Parse(yMax.ToString());121             0; i < yMax; i++122 123                 124                 g.Drawline(pen,center.Y- (i + 1) * unit),1)">new PointF(center.X+ 1) * unit ));125                 g.DrawString((i +  unit));126                 127                 g.Drawline(pen,center.Y + (i + 128                 g.DrawString(" + (i + 129 130 131 132         133          判断直线方程是否在坐标轴范围内134         135         <param name="linear"></param>136         137          ChecklineIsValID(linearEquation linear)138 139             bool flagX = 140             bool flagY = 141             var y = linear.GetValueFromX(0f);142 143             判断y坐标的值有没有越界144             if (y == .MaxValue)145 146                 表示是垂直于x轴的直线147                 var x0 = -linear.C* linear.A;148                 if (x0 >= 0 - this._AxisX.Max && x0 < ._AxisX.Max)149                 {150                     flagY = 151                 }152                 else153 154                     flagY = 155 156                 157 158             159 160                 if (y <= this._AxisY.Max && y >= ._AxisY.Max)161 162                     flagY = 163 164                 165 166                     flagY = 167 168 169             判断x坐标的值170             var x = linear.GetValueFromY(0f);171             if (x == 172 173                 var y0 = -linear.C* linear.B;174 175                 if (y0 <= this._AxisY.Max && y0 >= 176 177                     flagX = 178 179                 180 181                     flagX = 182 183 184             185 186                 if (x <= this._AxisX.Max && x >= 187 188                     flagX = 189 190                 191 192                     flagX = 193 194 195 196             return flagX && flagY;只有x,y都满足条件,才是有效的197 198 199         200          判断点是否在坐标轴范围内201         202         203          CheckPointIsValID(PointF point)204 205             206             207             if (point.X <= this._AxisX.Max && point.X >= 208 209                 flagX = 210 211             if (point.Y <= this._AxisY.Max && point.Y >= 212 213                 flagY = 214 215             return flagX && flagY;216 217 218         219          检查抛物线方程是否有效220         221         <param name="parabolic"></param>222         223          CheckParabolicIsValID(ParabolicEquation parabolic) {224             List<PointF> lstPoint = GetPointFromEquation(parabolic);225             if (lstPoint.Count > 226 227                 228 229             else {230                 231 232 233 234         235          将刻度转换成像素236         237         public List<PointF> ConvertScaletoPixls(List<PointF> lstScale)238 239             List<PointF> lstPixls = new List<PointF>();240             if (lstScale != null && lstScale.Count > 241                 var p = lstScale.Select(s => new PointF(center.X + s.X * unit,center.Y - s.Y *242                 lstPixls = p.ToList();243 244              lstPixls;245 246 247         248          转换刻度到像素249         250         <param name="s"></param>251         252          PointF ConvertScaletoPixls(PointF s)253 254              unit);255 256 257         258          生成直线259         260         261          Generatelinear(linearEquation linear) {262 263             color linecolor = color.Blue;线条的颜色264             Graphics g = .CreateGraphics();265             分别获取两个端点的值,连成线即可266             var x1 = ._AxisX.Max;267             var y2 = ._AxisY.Max;268             var x3 = 269             var y4 = 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 =  PointF(x1,y1);275             var point2 =  PointF(x2,y2);276             var point3 =  PointF(x3,y3);277             var point4 =  PointF(x4,y4);278             List<PointF> lstTmp = () { point1,point2,point3,point4 };279             List<PointF> lstPoint=280             foreach (PointF point in lstTmp)281 282                 判断点是否合理283                 if (CheckPointIsValID(point))284 285                     lstPoint.Add(point);286 287 288             if (lstPoint.Count() < 289                 如果点的个数小于2,不能绘制直线290                 291 292             将刻度点,转换成像素点293             List<PointF> lstPixlsPoint = ConvertScaletoPixls(lstPoint);294             g.Drawline(new Pen(linecolor,linewidth),lstPixlsPoint[0],1)">1]);295             g.DrawString(L{0}new PointF(lstPixlsPoint[1].X + 1].Y - 296             this.lblinfo.Text += L{0}:{1}x+{2}y+{3}=0 ; 297             index++298             299 300 301         302          生成点303         304         <param name="point"></param>305         306          GeneratePoint(PointF point)307 308             Graphics g = 309             PointF p = ConvertScaletoPixls(point);310             g.FillEllipse(Brushes.Red,p.X,p.Y,1)">4,1)">4311             g.DrawString(P{0}new PointF(p.X + 312             P{0}:({1},{2}) ; 313             index++314             315 316 317          GenerateParabolic(ParabolicEquation parabolic)318 319             List<PointF> lstPoint =320             321             List<PointF> lstPixlsPoint =322             color linecolor = color.SeaGreen;323             Graphics g = 324             g.DrawCurve( Pen(linecolor,lstPixlsPoint.ToArray());325             g.DrawString(326             P{0}:y={1}x2+{2}x+{3} ; 327             index++328             329 330 331         332          从抛物线方程中取点值333         334         335         336         public List<PointF> GetPointFromEquation(ParabolicEquation parabolic) {337             List<PointF> lstPoint = 338             从坐标轴最小值开始,隔0.5 取一个339             int j=340             float i = this._AxisX.Max; i <= this._AxisX.Max; i = i + 0.5f341 342                 PointF p =  PointF(i,parabolic.GetValueFromX(i));343                 再判断点是否在坐标轴内344                 if (CheckPointIsValID(p) && (j==0 || lstPoint[j-1].X==i-))345 346                     lstPoint.Add(p);抛物线内的点应该是连续的347                     j++348 349 350              lstPoint;351 352 353         354          清除已经画上去的线条355         356         357          Clear() {358             Graphics g = 359             g.Clear(color.White);360             this.lblinfo.Text = ""361             this.Refresh();重新刷新界面,清除已经画上去的线条362             index = 363             364 365 366 367     368      坐标轴描述369     370      Axis{371 372         373          刻度表示最大值374         375         int Max { 376 377         378          名称379         380         string Xname{get;;}381 382         // 383         // 间隔384         385         public int Interval{get;set;}386 387 }
VIEw Code

【主界面类】

 12      MainForm : Form 13  MainForm() 15  17 voID btnline_Click(object sender,EventArgs e) 20  21             if (.linearControl1.IsValID()) 22  23                 var a = .linearControl1.A; 24                 var b = .linearControl1.B; 25                 var c = .linearControl1.C; 26                 判断方程的参数,是否有效 27                 linearEquation linear = new linearEquation() { A = a,B = b,C = c }; 28                 if (!linear.IsValID()) 29  30                     MessageBox.Show(输入的方程参数无效 31                      32  33                 .axisControl1.ChecklineIsValID(linear)) 34  35                     MessageBox.Show(输入的方程不在坐标轴内 36                      38                 .axisControl1.Generatelinear(linear); 39                 flag) 41                     MessageBox.Show(生成直线失败 42                      43  44  45 voID btnClear_Click(.axisControl1.Clear(); 51  52         voID btnPoint_Click( 53  54             .pointControl1.IsValID()) 55  56                 float x = .pointControl1.X; 57                 float y = .pointControl1.Y; 58                 PointF point =  PointF(x,y); 59                 .axisControl1.CheckPointIsValID(point)) { 60                     MessageBox.Show(输入的点不在坐标轴内 61                      62  63                 .axisControl1.GeneratePoint(point); 64                  65  66                     MessageBox.Show(生成点失败 67                      70              71  72  73         voID btnParabolic_Click( 74  75             .parabolicControl1.IsValID()) 77                 .parabolicControl1.A; 78                 .parabolicControl1.B; 79                 .parabolicControl1.C; 80                  81                 ParabolicEquation parabolic = new ParabolicEquation() { A = a,1)"> 82                 parabolic.IsValID()) 84                     MessageBox.Show( 85                      86  87                 .axisControl1.CheckParabolicIsValID(parabolic)) 88  89                     MessageBox.Show( 90                      91  92                 .axisControl1.GenerateParabolic(parabolic); 93                  94  95                     MessageBox.Show(生成抛物线失败 96                      97  98 100 101 }
VIEw Code

 【扩展多边形代码】

  1    2          生成多边形  3           4         <param name="lstPoints"></param>  5           6         bool Generatepolygon(List<PointF> lstPoints,1)">bool isOriginal=  7   8             color linecolor = color.Red;  9              (isOriginal) 11                 linecolor = color.Red; 13              14                 linecolor = color.Blue; 16              17             Graphics g =  18             画点 19             foreach (var p  lstPoints) { 20                 .GeneratePoint(p); 21  22              23             List<PointF> lstPixlsPoint = ConvertScaletoPixls(lstPoints); 24             绘制多边形 25             g.Drawpolygon( 26              27  28  扩展多边形,即在现有多边形的基础上进行扩展bool GenerateExpandpolygon(List<PointF> lstPoints,PointF center,1)"> distance) { 35             1.求多边形对应的外扩平行斜线 36             List<linearEquation> lstlines = new List<linearEquation> 37             int len = lstPoints.Count();int i = 0; i < len; i++var p0 = lstPoints[i];第i个元素 40                 var p1 = lstPoints[(i + 1) % len];第i+1个元素 41                 linearEquation linearEquation =  linearEquation(); 42                 if (p0.X == p1.X) 44                     垂直于x轴,没有斜率 45                     linearEquation.A =  46                     linearEquation.B =  47                     if (p0.X > center.X)                    { 49                         linearEquation.C = -(p0.X + distance);                    } 51                      52                         linearEquation.C = -(p0.X - 54                     else if (p0.Y == p1.Y) 58                     垂直于y轴,斜率为0 59                     linearEquation.A =  60                     linearEquation.B = if (p0.Y > center.Y) 63                         linearEquation.C = -(p0.Y + 64  65                      66                         linearEquation.C = -(p0.Y - 69                  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 78                     if (b > b_center) 79  80                         如果在原点上方 81  82                         linearEquation.C =(b+(float) Math.Abs((distance/(Math.Sin(-Math.PI/2-Math.atan(k)))))); 84                      85                         如果在原点下方 86                         linearEquation.C = (b - (float)Math.Abs((distance / (Math.Sin(-Math.PI / 2 - Math.atan(k)))))); 87  89                 this.Generatelinear(linearEquation); 90                 lstlines.Add(linearEquation); 92             List<PointF> lstNewPoints = 2.求相邻外扩平行斜线的交点 94              95                 var line0 = lstlines[i]; 96                 var line1 = lstlines[(i + 1) % len]; 97                 float x =  98                 float y =  99                 if (line0.A == 101                     y = -line0.C / line0.B;102                     x= line1.GetValueFromY(y);103 104                 if (line0.B == 105 106                     x = -line0.C / line0.A;107                     y = line1.GetValueFromX(x);108 109                 if (line1.A == 111                     y = -line1.C / line1.B;112                     x = line0.GetValueFromY(y);114                 if (line1.B == 116                     x = -line1.C / line1.A;117                     y = line0.GetValueFromX(x);118 119                 120                     两个都有斜率的直线的交点121                     float k0 = -line0.A /122                     float k1 = -line1.A /123                     float b0 = -line0.C /124                     float b1 = -line1.C /125                     x = (b1 - b0) / (k0 - k1);126                     y =127 128                 lstNewPoints.Add(130             this.Generatepolygon(lstNewPoints,1)">131             132             133         }
VIEw Code

 备注:源码 点击下方链接

源码下载

总结

以上是内存溢出为你收集整理的C# 简单实现直线方程,抛物线方程全部内容,希望文章能够帮你解决C# 简单实现直线方程,抛物线方程所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1213851.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-04
下一篇 2022-06-04

发表评论

登录后才能评论

评论列表(0条)

保存