C# winform中有绘图的函数,所以想到做一个绘制基本初等函数图像的小程序,既学习了编程,又对函数有了更深的了解。
学习高等数学的时候,对基本初等函数有些生疏,而且高中时也没学过反函数,所以只好自学了一段时间。但是对函数图像并不是有很深的印象。正好学到了C# ,编写桌面程序特别简单,控件拖动就出来了。满足了C语言不能很好地搭建界面的需求。下面对winform绘制函数作一个简要的说明。
C# 中提供了一个类:Graphics
这个类可以绘制很多图像,像点、线、矩形、圆、椭圆等等都可以绘制。
它就像一个画板一样,所以要有画笔才行。C# 中有一个画笔类:Pen
它可以对画笔进行设置大小,颜色等等。
有了工具之后,就可以着手进行程序的开发了。
按照步骤来,首先需求分析:
绘制各种函数图像。
OK,可以开始着手做了。
首先新建项目、在窗体上放上这些按钮和一些设置参数的文本框等等。下图是具体的布局。
其次将窗体属性设置为全屏。要绘制函数,肯定要有坐标系,打算将窗体中心作为坐标系的中心。所以在类中定义一些字段作为坐标系的原点、坐标系的精度、绘制的曲线的精度等等。还要讲画板和画笔也定义好,这样所有的工具就有了。
下面就可以开始正式绘制了。
变量定义好了之后,我们就开始操作。
首先在窗体的加载事件中进行前期初始化。
private void Form1_Load(object sender, EventArgs e)
{
//获得窗体中心点作为坐标系中心
beginPointX = (this.Width / 2);
beginPointY = (this.Height / 2);
//创建画板
gra = this.CreateGraphics();
//初始化坐标系
zuobiaoxi();
}
初始化坐标系函数:
private void zuobiaoxi()
{
try
{
//从文本框中获得坐标系精度参数
KEDU = Convert.ToInt32(textBox1.Text.Trim());
//从文本框中获得曲线精度
LINEJD = Convert.ToDouble(textBox2.Text.Trim());
//从文本框中获得曲线宽度
PointSize = Convert.ToInt32(textBox3.Text.Trim());
}
catch
{
}
Inittools();//画板、画笔工具初始化
//初始化X轴
InitX(new Point(0, beginPointY), new Point(this.Width, beginPointY));
//初始化Y轴
InitY(new Point(beginPointX, 0), new Point(beginPointX, this.Height));
}
画板、画笔初始化函数:
private void Inittools()
{
//用指定的颜色清除画板上的内容
gra.Clear(Color.FromArgb(253,241,219));
//指定绘制模式 消除锯齿
gra.SmoothingMode = SmoothingMode.AntiAlias;
//创建画笔对象
pen = new Pen(Color.Green);
//指定画笔的宽度
pen.Width = KEDU/20;
}
初始化X轴函数:
private void InitX(Point a,Point b)
{
gra.DrawLine(pen, a, b);
a.Y = beginPointY;
b.Y = beginPointY - KEDU/4;
for (int i = 0; i < (this.Width / 2)/this.KEDU; i++)
{
a.X = beginPointX - this.KEDU*i;
b.X = beginPointX - this.KEDU*i;
gra.DrawLine(pen, a, b);
a.X = beginPointX + this.KEDU * i;
b.X = beginPointX + this.KEDU * i;
gra.DrawLine(pen, a, b);
}
}
初始化Y轴函数:
private void InitY(Point a, Point b)
{
gra.DrawLine(pen, a, b);
a.X = beginPointX;
b.X = beginPointX + KEDU/4;
for (int i = 0; i < (this.Height / 2) / this.KEDU; i++)
{
a.Y = beginPointY - this.KEDU * i;
b.Y = beginPointY - this.KEDU * i;
gra.DrawLine(pen, a, b);
a.Y = beginPointY + this.KEDU * i;
b.Y = beginPointY + this.KEDU * i;
gra.DrawLine(pen, a, b);
}
}
这个时候,窗体加载完坐标系就搭建好了。界面如下图所示。
接下来是绘制各个函数了。
绘制正弦函数:
private void button1_Click(object sender, EventArgs e)
{
if(flag == 1)
{
sign = 1;
new Thread(huizhi).Start();
}
}
所有的函数封装代码都放在“huizhi”函数中了。
绘制图像的函数:
private void huizhi()
{
try
{
flag = 0;
zeroX = beginPointX;
zeroY = beginPointY;
Random r = new Random();
pen.Color = Color.FromArgb(r.Next(0,255), r.Next(0,255), r.Next(0,255));
realX = -Width;
while (realX < Width)
{
switch (sign)
{
//每一个case就是一种函数图像
case 1:
realY = Math.Sin(realX / KEDU) * KEDU;
break;
case 2:
realY = Math.Asin(realX / KEDU) * KEDU;
break;
case 3:
realY = Math.Cos(realX / KEDU) * KEDU;
break;
case 4:
realY = Math.Acos(realX / KEDU) * KEDU;
break;
case 5:
realY = Math.Tan(realX / KEDU) * KEDU;
break;
case 6:
realY = Math.Atan(realX / KEDU) * KEDU;
break;
case 7:
realY = (Math.Cos(realX / KEDU) * KEDU) / (Math.Sin(realX / KEDU));
break;
case 8:
realY = (Math.PI / 2) * KEDU - (Math.Atan(realX / KEDU) * KEDU);
break;
case 9:
realY = (1 * KEDU) / (Math.Cos(realX / KEDU));
break;
case 10:
realY = (1 * KEDU) / (Math.Sin(realX / KEDU));
break;
case 11:
realY = realX * realX / KEDU;
break;
case 12:
realY = (realX * realX * realX) / (KEDU * KEDU);
break;
case 13:
realY = 1 * KEDU * KEDU / realX;
break;
case 14:
realY = Math.Log(realX / KEDU) * KEDU;
break;
case 15:
realY = realX;
break;
}
try
{
//画指定矩形的内切圆 其实函数图像就是由一个个小圆点组成的
gra.FillEllipse(pen.Brush, (float)(zeroX + realX - 1), (float)(zeroY - realY - 1), PointSize, PointSize);
}
catch
{
}
//按照刻度从左至右依次绘制
realX = realX + LINEJD;
}
flag = 1;
}
catch
{
}
}
好了,写完了这些就大功告成了。其实最关键的部分就是每一个图像的X点和Y点的位置,选定了X、Y的值,然后在那个位置画个圆点就行了。
介绍一下参数:坐标轴精度就是每个刻度多长,就像放大缩小图像一样。曲线精度就是绘制出的线条的细致程度,越小越好,但是小就绘制的慢。如果设置为0.01就特别慢,可以试试挺好玩的。曲线宽度就是绘制出的线条宽度。
前台在绘制的时候会卡死,所以用了多线程,一次只能绘制一种图像,但是可以覆盖绘制。
还有就是画的函数多了要点击“初始化”按钮清屏。
下面贴出一些效果,特别棒,而且根据不同的参数还有意想不到的图像。
将坐标轴精度变得很小的时候,绘制正割、余割函数会出现很漂亮的另外的曲线,它们上方的点阵又组成了另外的函数。
最后贴上源码地址:GDI绘制函数图像
本文系网站原创,转载请注明文章链接地址