武利翻
摘 要:绘图系统主要是实现各种标准图形和任意线条图形的绘制编辑和变换,其中标准图形包括直线,多边形,椭圆,各种曲线等。要实现它们的绘制和各种基本变换(编辑功能),其中最关键的问题是曲线的多边形与曲线的拟合。
关键词:图形绘制 曲线拟合 图形编辑
中图分类号:TP31 文献标识码:A 文章编号:1674-098X(2012)12(a)-00-02
在企业计算领域,C#将会变成用于编写“下一代窗口服务”应用程序的主要语言。而GDI+是Windows 2000及以后版本的一个子系统,同原有的GDI(图形设备接口)一样,主要负责对显示器和打印机进行管理。GDI+为我们提供了在编程时使用的应用程序接口API(Application Programming Interface),通过这些API函数,GDI+让程序员在设计程序中不必考虑具体的显示器或打印机,直接使用由GDI+提供的类的方法便可以调用显示器或打印机,真正做到与设备无关。现在大家通用的绘图软件有Photoshop,CAD等。而大部分绘图软件都是用C++,VB等语言编写,而本软件将用C#和GDI+方面知识[1]。
本系统要求实现在显示设备上进行绘图操作,其中绘图操作是用代码实现的,而不是有一些预定义的控件或对话框来实现,其实这就是GDI+的实质[2]。GDI+是一个功能强大的工具,有许多.NET 基类都可用于在设备上绘图。绘图系统中要进行各种工具的选择。选择工具以及完成绘画功能如画笔,画直线、画矩形、画圆椭圆,命名与擦除都是在swich语句中进行的。这里不重点介绍,重点介绍多边形与曲线拟合。这部分实现过程比较难,这部分都用到了动态数组。
1 多边形的实现
实现绘制任意多边形的功能。选择绘图工具项中的绘制多边形,当用户在绘图区域用鼠标左键点击时,动态数组将记录各个点的位置,鼠标松开时程序判断用户输入点的数目,当输入数目大于等于两个时进行相邻两个点的连接,根据程序提示用户完成时点击鼠标右键。实现工程具体如下。
鼠标按下时添加动态数组元素,
points.Add(new Point(e.X,e.Y));
鼠标松开判断并进行绘图,算法主要用到方法如下:
g.DrawLines(new Pen(foreColor,n),pointArray);
ig.DrawLines(new Pen(foreColor,n),pointArray);
点击鼠标右键时结束绘制同时释放动态数组。
2 曲线拟合的实现
曲线拟和算法设计,是本次设计的最重要的部分,算法的主要思想如下:
要使整个曲线处处光滑,必须是所有的衔接点两侧斜率相等[3]。做法如下:首先对绘图面上三个点即点1,点2,点3用一条光滑的二次曲线进行拟和,画出点1到点3的一段曲线,并求出点3在本坐标系下的斜率。再在绘图面上再点击一个点4,并针对后三个点进行坐标变换,然后在变换的坐标系下用三次曲线进行拟和,用2,点3和点4的坐标和点3的斜率确定一条光滑的三次曲线,画出点3到点4的一段曲线,并计算出点4的斜率。再点击一个点,依照上面的方法继续进行坐标变换和三次曲线进行拟和,画出最后两点间的一段曲线,每次都要用前次的斜率并计算新加入点的斜率。重复加入新点,画出最后两点间的一段曲线,直到最后一个点[4]。
拟和部分:
已知:三点坐标(X1,Y1),(X2,Y2),(X3,Y3),Y2'
用三次曲线 A X13 + B X2 + C X + D = Y 拟和,代入三点坐标和Y2' 得:
A X13 + B X12 + C X1 + D = Y1
X23 + B X22 + C X2 + D = Y2
X33 + B X32 + C X3 + D = Y3
3 A X22 +2 B X2 + C = Y2'
以A、B、C、D为变元求解此方程组,得A、B、C、D的值,从X2到X3画出三次曲线 A X3 + B X2 + C X + D = Y,求出X3点的斜率
3 A X32 +2 B X3 + C
此部分算法主要如下:
g.DrawCurve(new Pen(foreColor,n),pointArray);
ig.DrawCurve(new Pen(foreColor,n),pointArray);
points1 = new ArrayList();
坐标变换部分:
坐标变换引入了对矩阵对象的支持,矩阵是变换的核心,在绘制图形时,定义图位置相当重要。GDI+中使用三种坐标系来表示位置信息:世界坐标、页面坐标、设备坐标。
本部分所说的坐标变换是指从页面坐标到页面坐标的变换,即重新设置页面坐标,而且坐标原点、X轴、Y轴都要变换。实现坐标变换的过程是:取数组的后两个元素,即后两个点连成一条直线且直线作为X轴,通过新加入的点向直线做垂线,并设置其交点为新的原点,垂线作为Y轴。示意图如图1。
图1 坐标变换示意图
坐标变换过程要用到平移变换和旋转变换:平移变换,假设有一个点A,其坐标为(x,y),对A点进行平移变换(以dx,dy做为在水平和垂直方向的变化量)的结果是A点的新坐标(x1,y1)为:x1=x+dx,y1=y+dy.用到的相应的变换矩阵为:
旋转变换,假设有一个点A,其坐标为(x,y),对A点进行旋转(角度为a),转换结果是,点的新坐标(x1,y1)为:
x1=x*cos(a)+y*sia(a),y1=x*sia(a)+y*cos(a).
旋转变换对应的变换矩阵为:
坐标变换的结果都体现在矩阵变换的叠加上。
主要代码如下:
Matrix myMatri = new Matrix();
myMatrix.Rotate(30.0f)//旋转30度
myMatrix.Translate(1.0f,2.0f,MatrixOrder.Append);
//垂直方向上放大两倍
…………………
myMatrix.Translate(5.0f,0.0f,MatrixOrder.Append);
//水平方向上平移5个单位
参考文献
[1] 骆开华,李绍强.在.NET中使用X mL的安全性研究[J].科技信息,2010(17).
[2] 田原.VB.NET绘图功能研究[J].软件导刊,2005(22).
[3] 王雪,晋浩.NET中绘图控件的编程技术与实现[J].电脑知识与技术(学术交流),2006(36).
[4] 王美琼.用VB编程绘制图形的方法和技巧[J].考试周刊,2009(49).