基于GDI+的绘图控件开发

基于GDI+的绘图控件开发

GDI+绘图控件的一些绘图函数包括绘制直线、曲线、圆弧、文本函数等,一些主要功能有缩放、移动和坐标变换(如图1所示)。绘制基本函数并不复杂,有一点GDI+基础就可以轻松编写这些函数,但是对于如何进行缩放和平移等操作,以及屏幕坐标(又称设备坐标)和绘图坐标(又称页面坐标)的变换则存在一定的难度和必须注意的事项。基本绘图函数在这里就不在讲解,下面主要讲述一下所用到的关键方法和注意事项。


绘图控件首先要解决的问题就是坐标的变换,在GDI+的坐标系统中坐标的类型有三种,即全局坐标、页面坐标和设备坐标。我们用鼠标点击获取的未经变换的坐标即为设备的坐标,而我们模型的绘制空间的坐标为全局坐标。我们要想当鼠标移动到绘图区域时,显示当前的绘图坐标(注意不应该是设备坐标),这个时候就需要进行坐标的变换了。而在GDI+中已经提供了这样的函数,在这里我们应注意,我们需要是把全局坐标转换到设备坐标的系统中,不要转错了哦!(1)坐标变换

实现方法:在控件里的picturebox控件的_MouseMove事件中添加如下代码即可,

points = newPointF[1];
points[0].X = (float)e.X;
points[0].Y = (float)e.Y;
graphics.TransformPoints(CoordinateSpace.World, CoordinateSpace.Device,points);
points[0].Y = -points[0].Y;
pointsText.Text = "x="+ points[0].X.ToString() + "," + "y=" + points[0].Y.ToString();

其中,graphics.TransformPoints()函数用于将坐标的变换。如图1的左下角所示。但是我们通常所用的坐标原点一般在左下角,而系统的默认坐标却在左上角,因此还需要进行原点坐标的平移变换(将在下面讲解)。

(2)缩放和平移

大家都知道在GDI+中为我们提供了图形的缩放(ScaleTransform())和平移(TranslateTransform())的函数。他们要求图形的绘制必须和缩放、平移在同函数下进行绘制。

因此,我们简单的在控件中简单的写几个绘制图形的函数,然后在控件以外调用这个函数,是不能实现图形的缩放和平移操作的。

所以,我们需要在控件中给各个图形定义一个结构或类来存储图形的属性信息,然后在每次绘制的过程中,用一个动态数组存储对应的图形信息即可,如下绘制直线的定义方法:

首先定义直线类,

public class LineObject
{
    public double StartX;
    public double StartY;
    public double EndX;
    public double EndY;
    public Color Color;
    public float LineWidth;
}

然后,定义绘制直线的函数,

/// <summary>
/// 绘制直线
/// </summary>
/// <paramname="color">直线颜色</param>
/// <paramname="width">直线宽度</param>
/// <paramname="x1">第一个点x值</param>
/// <paramname="y1">第一个点y值</param>
/// <paramname="x2">第二个点x值</param>
/// <paramname="y2">第二个点y值</param>
public void DrawLine( Colorcolor,double width,doublex1, double y1,doublex2,double y2)
{
    LineObjecttempLine = new LineObject();
    tempLine.Color = color;
    tempLine.LineWidth =(float) width;
    tempLine.StartY = x1;
    tempLine.StartY = y1;
    tempLine.EndX = x2;
    tempLine.EndY = y2;
    LinesArray.Add(tempLine);
    Render();
}

最后,在render()函数中添加绘制直线的代码和图形缩放代码如下

graphics.ScaleTransform(scaleFactor,scaleFactor);//缩放
graphics.TranslateTransform(originXY.X,originXY.Y);//移动
//绘制直线
if (LinesArray.Count > 0)
{
    PenlinePen;
    foreach (LineObject tempLine inLinesArray)
    {
        linePen = newPen(tempLine.Color, tempLine.LineWidth);
        graphics.DrawLine(linePen, (float)tempLine.StartX,
            - (float)tempLine.StartY,(float)tempLine.EndX ,  - (float)tempLine.EndY);
    }                  
}

外部进行绘图的时候,直接调用DrawLine()即可,通过这种方式定义不仅方便进行缩放和平移,更方便图形的输出。

(3)坐标原点设置

坐标原点的设置在知道缩放和平移的原理后,坐标原点的设置就比较简单了。坐标原点的设置可以理解为把坐标原点从左上角移动到一个我们想要的位置(本文移动到左下角(10,10))的位置,通过平移函数即可,但是我们应注意平移函数要放在缩放函数的前面,不然当缩放的时候缩放点还是以左上角进行缩放,同样还要注意假如y轴的方向翻转时(例如本控件中y向上)在写各个图形的代码时,y值要进行相应的改为负值。

在render函数中添加如下代码即可,

graphics.TranslateTransform(OpointF.X,OpointF.Y);

(4)平移时闪动问题

 

本文是总结自己在写控件过程中遇到的一些问题,仅此帮助那些像自己不懂的童鞋们学习和参考。因为书写比较仓促和限于本人水平有限,错误之处恳请指出。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
大学生参加学科竞赛有着诸多好处,不仅有助于个人综合素质的提升,还能为未来职业发展奠定良好基础。以下是一些分析: 首先,学科竞赛是提高专业知识和技能水平的有效途径。通过参与竞赛,学生不仅能够深入学习相关专业知识,还能够接触到最新的科研成果和技术发展趋势。这有助于拓展学生的学科视野,使其对专业领域有更深刻的理解。在竞赛过程中,学生通常需要解决实际问题,这锻炼了他们独立思考和解决问题的能力。 其次,学科竞赛培养了学生的团队合作精神。许多竞赛项目需要团队协作来完成,这促使学生学会有效地与他人合作、协调分工。在团队合作中,学生们能够学到如何有效沟通、共同制定目标和分工合作,这对于日后进入职场具有重要意义。 此外,学科竞赛是提高学生综合能力的一种途径。竞赛项目通常会涉及到理论知识、实际操作和创新思维等多个方面,要求参赛者具备全面的素质。在竞赛过程中,学生不仅需要展现自己的专业知识,还需要具备创新意识和解决问题的能力。这种全面的综合能力培养对于未来从事各类职业都具有积极作用。 此外,学科竞赛可以为学生提供展示自我、树立信心的机会。通过比赛的舞台,学生有机会展现自己在专业领域的优势,得到他人的认可和赞誉。这对于培养学生的自信心和自我价值感非常重要,有助于他们更加积极主动地投入学习和未来的职业生涯。 最后,学科竞赛对于个人职业发展具有积极的助推作用。在竞赛中脱颖而出的学生通常能够引起企业、研究机构等用人单位的关注。获得竞赛奖项不仅可以作为个人履历的亮点,还可以为进入理想的工作岗位提供有力的支持。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值