VC.NET的GDI+编程入门教程之图形
来源:互联网 发布:mac os x 10.11 镜像 编辑:程序博客网 时间:2024/06/14 02:15
一、等边图形
(一)长方形和正方形
长方形是由四条边组成的具有四个直角的几何图形,为了绘制一个长方形,可以定义围成长方形的矩形值,或定义它的位置和尺寸。为了画一个矩形围成的长方形,可以使用Graphics::DrawRectangle()方法。
类似的长方形可以按照如下说明:
![VC.NET的GDI+编程入门教程之图形(图一)](http://www.itfensi.com/d/file/exploit/NET/vcnet/2007-03-15/1b3624e2bded7d7842a38a213eacaa69.gif)
图一、长方形说明图示
定义过一个矩形变量后,可以将它传递给上述的方法,例子代码如下:
System::Windows::Forms::PaintEventArgs * e)
{
Pen *penCurrent = new Pen(Color::Red);
Rectangle Rect(20, 20, 248, 162);
e->Graphics->DrawRectangle(penCurrent, Rect);
}
需要注意的是,也可以在方法的括号内定义画笔或矩形对象。
System::Windows::Forms::PaintEventArgs * e)
{
e->Graphics->DrawRectangle(new Pen(Color::Red), Rectangle(20, 20, 248, 162));
}
这将产生如下效果图:
![VC.NET的GDI+编程入门教程之图形(图二)](http://www.itfensi.com/d/file/exploit/NET/vcnet/2007-03-15/7dd4e510a81060c06c861583bb3a2e57.gif)
图二、绘制的长方形效果图
一定要记住,矩形对象的第三个参数代表的是矩形的宽度,第四个参数代表的矩形的高度,这对于那些使用过GDI编程的人来说是容易混淆的一点。GDI+定义的矩形对象与GDI定义的矩形对象是有区别的。实际上,为了定义所要画的长方形的位置和尺寸,Graphics类提供了如下版本的DrawRectangle()方法:
public: void DrawRectangle(Pen *pen, float x, float y, float width, float height);
这次,长方形对象用一个定位点和它的宽度、高度来表示。这可以用如下的Windows坐标系统进行说明。
![VC.NET的GDI+编程入门教程之图形(图三)](http://www.itfensi.com/d/file/exploit/NET/vcnet/2007-03-15/d983b7e7330b12aea735fc43274ddf60.gif)
图三、Windows坐标系统
在此基础上,上述的长方形可以按照如下方法进行绘制:
System::Windows::Forms::PaintEventArgs * e)
{
e->Graphics->DrawRectangle(new Pen(Color::Red), 20, 20, 248, 162);
}
正方形是四个边都相等的长方形,是长方形的特例。
(二)一系列的长方形
DrawRectangle()方法用于绘制一个长方形,如果打算绘制很多的矩形的话,你可以向前一步地,用Graphics::DrawRectangles()方法,它有两个版本,语法如下:
public: void DrawRectangles(Pen *pen, RectangleF rects[]);
这个方法需要一个Rectangle 或 RectangleF数组。它根据数组的不同的成员值绘制不同的长方形。下面是一个例子代码:
System::Windows::Forms::PaintEventArgs * e)
{
Pen *penCurrent = new Pen(Color::Red);
Rectangle Rect[] = { Rectangle(20, 20, 120, 20),
Rectangle(20, 50, 120, 30),
Rectangle(20, 90, 120, 40),
Rectangle(20, 140, 120, 60) };
e->Graphics->DrawRectangles(penCurrent, Rect);
}
上述代码产生如下的效果:
图四、一系列长方形效果图
二、线条
(一)一条直线
直线连接了两个点,这意味着直线有起点和终点。
![VC.NET的GDI+编程入门教程之图形(图五)](http://www.itfensi.com/d/file/exploit/NET/vcnet/2007-03-15/05b3f3ec480cf43756dbb069bcb0c6f8.gif)
图五、直线示意图
起点和终点是截然不同的两个点,正是基于这一点,直线也可以用两个点(Ponit)来表示,或者用笛卡尔坐标系中的四个坐标数值表示。Graphics提供了以下重载的DrawLine()方法来绘制一条直线,:
public: void DrawLine(Pen *pen, Point pt1, Point pt2);
public: void DrawLine(Pen *pen, PointF pt1, PointF pt2);
public: void DrawLine(Pen *pen, int x1, int y1, int x2, int y2);
public: void DrawLine(Pen *pen, float x1, float y1, float x2, float y2);
如果直线用自然数表示,它的起点可以用pt1表示,终点用点pt2表示,如果直线用实数绘制,它在PointF pt1处开始,在PointF pt2处结束。或者,可以用坐标(x1, y1)来表示起点,用坐标(x2, y2)表示终点。同样类型的直线可以用十进制数从点(x1, y1) 处到点 (x2, y2).处。
下面的代码画了三条直线:
private: System::Void Form1_Paint(System::Object * sender,
System::Windows::Forms::PaintEventArgs * e)
{
Pen *penCurrent = new Pen(Color::Red);
e->Graphics->DrawLine(penCurrent, 20, 20, 205, 20);
penCurrent = new Pen(Color::Green);
e->Graphics->DrawLine(penCurrent, 40, 40, 225, 40);
penCurrent = new Pen(Color::Blue);
e->Graphics->DrawLine(penCurrent, 30, 60, 215, 60);
}
![VC.NET的GDI+编程入门教程之图形(图六)](http://www.itfensi.com/d/file/exploit/NET/vcnet/2007-03-15/ffb20177f51cf8e2b5b40076d03b1e64.gif)
图六:绘制三条直线
(二)一系列直线
上述的DrawLine()方法用来画一条直线,如果打算一次画一组直线的话,可以使用Graphics::DrawLines()方法,它重载了两个版本:
public: void DrawLines(Pen *pen, Point points[]);
public: void DrawLines(Pen *pen, PointF points[]);
为了使用这种方法,需要使用代表笛卡尔坐标的自然数定义Point数组,或只用实数定义PointF数组,例子代码如下:
private: System::Void Form1_Paint(System::Object * sender,
System::Windows::Forms::PaintEventArgs * e)
{
Point Coordinates[] = { Point(20, 10), Point(205, 20),
Point(40, 40), Point(225, 60),
Point(30, 80), Point(215, 100) };
Pen *penCurrent = new Pen(Color::Red);
e->Graphics->DrawLines(penCurrent, Coordinates);
}
这将产生如下的效果:
图七、系列直线效果图
三、多边形
多边形是如若干个直线互联所围成的图形,换句话说,多边形有多个直线定义,除了第一根直线外,所有直线的起点都是前一根直线的终点,最后一根直线的终点是第一根直线的起点。
为了画多边形,可以使用Graphics::Polygon()方法,它重载了两个版本:
public: void DrawPolygon(Pen *pen, PointF points[]);
使用这个方法时,首先声明一个Point 或 PointF类型的数组,并将它传递给函数的第二个参数。下面是一个例子的代码:
private: System::Void Form1_Paint(System::Object * sender,
System::Windows::Forms::PaintEventArgs * e)
{
Point Pt[] = { Point(20, 50), Point(180, 50), Point(180, 20),
Point(230, 70), Point(180, 120), Point(180, 90),
Point(20, 90) };
Pen *penCurrent = new Pen(Color::Red);
e->Graphics->DrawPolygon(penCurrent, Pt);
}
这个将产生如下效果:
图八、多边形效果图
于圆的图形
一、椭圆与圆
连续弯曲的线条围成了椭圆。椭圆上的每一个点都相对于中心点来说都存在一个对称点,下图对它进行了说明:
![VC.NET的GDI+编程入门教程之图形(图九)](http://www.itfensi.com/d/file/exploit/NET/vcnet/2007-03-15/f9498e34727a4f70673542336d9ddfaa.gif)
图九、椭圆示意图
因为一个椭圆可以放入到一个矩形中,所以在GDI+编程中,椭圆用它的外接矩形来定义。为了画一个椭圆,可以使用Graphics::DrawEllipse()方法,这个方法有四个版本:
public: void DrawEllipse(Pen *pen, Rectangle rect);
public: void DrawEllipse(Pen *pen, RectangleF rect);
public: void DrawEllipse(Pen *pen, int x, int y, int width, int height);
public: void DrawEllipse(Pen *pen, float x, float y, float width, float height);
![VC.NET的GDI+编程入门教程之图形(图十)](http://www.itfensi.com/d/file/exploit/NET/vcnet/2007-03-15/40abbafb6ceff32a94b72789462c5721.gif)
图十、函数参数示意图
这种方法参数的含义与Graphics::DrawRectangle()方法参数的含义是一样的。
这里是一个例子:
private: System::Void Form1_Paint(System::Object * sender,
System::Windows::Forms::PaintEventArgs * e)
{
Pen *penCurrent = new Pen(Color::Red);
e->Graphics->DrawEllipse(penCurrent, Rectangle(20, 20, 226, 144));
}
![VC.NET的GDI+编程入门教程之图形(图十)](http://www.itfensi.com/d/file/exploit/NET/vcnet/2007-03-15/372cffa8b909724c08ff67e0d37f2bb2.gif)
图十一、代码运行效果图
二、饼图
饼图是用一个起始角度和终止角度定位的椭圆的一部分,示意图如下:
![VC.NET的GDI+编程入门教程之图形(图十二)](http://www.itfensi.com/d/file/exploit/NET/vcnet/2007-03-15/bed7b1ef6fb4a20ffb32a917bd8a099c.gif)
图十二、饼图示意图
为了画一个饼图,可以用Graphics::DrawPie()方法,它有下列的几个版本:
public: void DrawPie(Pen *pen, Rectangle rect,float startAngle,float sweepAngle);
public: void DrawPie(Pen *pen, RectangleF rect, float startAngle,float sweepAngle);
public: void DrawPie(Pen *pen,int x,int y,int width,int height, int startAngle, int sweepAngle);
public: void DrawPie(Pen *pen, float x, float y, float width, float height, float startAngle, float sweepAngle);
饼图是基于椭圆的,椭圆所外接的矩形将作为rect参数传递,矩形也可以用定位点和尺寸来定义。
对于所要绘制的椭圆的外接矩形中,可以设定一个起始角度,这个角度是按照顺时针方向从0度开始计算的(就象一个模拟钟一样)。这意味着90度在6点钟方向而不是在12点钟方向。这个开始的角度作为startAngle参数来传递。
定义过起始角度后,还要定义饼图所覆盖的角度,这也是按照顺时针计算的。这个值使用sweepAngle参数来传递。
下面有个例子:
private: System::Void Form1_Paint(System::Object * sender,
System::Windows::Forms::PaintEventArgs * e)
{
Pen *penCurrent = new Pen(Color::Red);
e->Graphics->DrawPie(penCurrent, 20, 20, 200, 100, 45, 255);
}
代码运行效果如下:
![VC.NET的GDI+编程入门教程之图形(图十三)](http://www.itfensi.com/d/file/exploit/NET/vcnet/2007-03-15/90cc2b4c20fae545e96aa14d1cc61e9d.gif)
图十三、饼图效果三、弧线
弧线是椭圆的一部分,这意味着弧线是一个非封闭的椭圆。尽管饼图是一个封闭的图形,但弧线不是。它仅仅是定义椭圆的边线部分。因为弧线必须与椭圆一致,它被定义为适应外接矩形,这可以用下图来说明:
![VC.NET的GDI+编程入门教程之图形(图十四)](http://www.itfensi.com/d/file/exploit/NET/vcnet/2007-03-15/0962b227b37ff810d3d2e0311ccf5aa1.gif)
图十四、弧线示意图
为了支持弧线,Graphics 类提供了DrawArc()方法,这个方法定义了四个版本:
public: void DrawArc(Pen *pen, Rectangle rect, float startAngle, float sweepAngle);
public: void DrawArc(Pen *pen, RectangleF rect, float startAngle, float sweepAngle);
public: void DrawArc(Pen *pen, int x, int y, int width, int height, int startAngle, int sweepAngle);
public: void DrawArc(Pen *pen, float x, float y, float width, float height, float startAngle, float sweepAngle);
含有弧线的椭圆必须在Rectangle或 RectangleF矩形内进行绘制,也可以用外接矩形的坐标、尺寸来定义椭圆,弧线必须与外接矩形相匹配外,还必须定义起始角度(起始点与X轴的顺时针角度)。弧线还要定义从起始点顺时针所扫过的角度,这两个值与Graphics::Pie()方法中的值含义一样 ,下面是例子代码:
private: System::Void Form1_Paint(System::Object * sender,
System::Windows::Forms::PaintEventArgs * e)
{
Pen *penCurrent = new Pen(Color::Red);
e->Graphics->DrawArc(penCurrent, 20, 20, 200, 150, 225, 200);
}
![VC.NET的GDI+编程入门教程之图形(图十五)](http://www.itfensi.com/d/file/exploit/NET/vcnet/2007-03-15/4f769c0893e5ed3734f823c4a9b2613e.gif)
图十五、程序效果图 基于曲线的图形
一、曲线
曲线是连接两点或多点的线条,如果仅仅涉及两个点,线条将把它们连接在一起,但这个线条不是直的。如果有三个点A、B、C,这条线将从A点开始,穿过B点,结束于C点。如果多于三个点,这条线将起始与第一个点,依次穿过中间的若干点,结束于最后的点。曲线中的点不必排成一条直线,实际上,绘制曲线的整体思想是用非直的线条连接不在一条直线上的点,下图的C 1、C2、C3可以说明这一点:
![VC.NET的GDI+编程入门教程之图形(图十六)](http://www.itfensi.com/d/file/exploit/NET/vcnet/2007-03-15/a2a2532f1f594c878020a9f7c4a93a54.gif)
图十六、曲线示意图
曲线C1包括两个点,曲线C2包括3个点,曲线C3包括4个点。
两点间的部分称为线段。这也意味着曲线可以由包含的线段的个数来进行区分。如果一个曲线仅仅由两个点构成,这意味着它只有一个线段,连接着第一、第二个点,如果一个曲线包括三个点,它有两个线段,第一个线段跨越第一、第二个点,第二个线段跨越第二、第三个点。综上所述,曲线的线段数等于点数减去一。
GDI+中使用Graphics::DrawCurve()方法画曲线,在画一个曲线时,必须说明所涉及到的点数,这意味着首先要声明一个Point 或PointF数组,正是考虑到这一点,Graphics类定义的DrawCurve()的方法如下:
public: void DrawCurve(Pen *pen, Point points[]);
public: void DrawCurve(Pen *pen, PointF points[]);
这个版本的方法使用了Point 或 PointF值作为参数,数组的成员数由你规定,这里有一个例子使用四个点来绘制一个含有三个线段的曲线:
private: System::Void Form1_Paint(System::Object * sender,
System::Windows::Forms::PaintEventArgs * e)
{
Pen *penCurrent = new Pen(Color::Blue);
Point pt[] = { Point( 40, 42), Point(188, 246),
Point(484, 192), Point(350, 48) };
e->Graphics->DrawCurve(penCurrent, pt);
}
它的效果图如下所示:
![VC.NET的GDI+编程入门教程之图形(图十七)](http://www.itfensi.com/d/file/exploit/NET/vcnet/2007-03-15/f29afb43b25f1e0e1e58399d7f6678cb.gif)
图十七、曲线效果图
正如你所见到的,当画一个曲线时,一个弯曲的线条穿越起始点和终点之间的中间点,为了使线条是非直的,编译器使用一个称为张力的值来弯曲线条,这个张力值可以通过定义弯曲系数的形式来修改,为了这么做,使用下列版本的DrawCurve()方法:
public: void DrawCurve(Pen *pen, Point points[], float tension);
public: void DrawCurve(Pen *pen, PointF points[], float tension);
弯曲程度由张力参数决定,它可以是大于等于0.00的十进制数,如果该值等于0.00,将画一个直线。下面是一个例子:
private: System::Void Form1_Paint(System::Object * sender,
System::Windows::Forms::PaintEventArgs * e)
{
Pen *penCurrent = new Pen(Color::Blue);
Point pt[] = { Point(40, 42), Point(188, 246),Point(484, 192), Point(350, 48) };
e->Graphics->DrawCurve(penCurrent, pt, 0.00F);
}
![VC.NET的GDI+编程入门教程之图形(图十八)](http://www.itfensi.com/d/file/exploit/NET/vcnet/2007-03-15/74d9479bc24245376dd63701a0c4fcc4.gif)
图十八、代码运行效果图
这意味着,如果想画一个真正的曲线,或者是不传递张力参数,使用这个方法的第一个版本,或者是传递的张力的参数值大于0.00。这里有个例子:
private: System::Void Form1_Paint(System::Object * sender,
System::Windows::Forms::PaintEventArgs * e)
{
Pen *penCurrent = new Pen(Color::Blue);
Point pt[] = { Point(40, 42), Point(188, 246),Point(484, 192), Point(350, 48) };
e->Graphics->DrawCurve(penCurrent, pt, 2.15F);
}
这将产生如下效果:
![VC.NET的GDI+编程入门教程之图形(图十九)](http://www.itfensi.com/d/file/exploit/NET/vcnet/2007-03-15/1888cecd5374dbd76eda92e58c675650.gif)
图十九、代码运行效果图
DrawCurve()方法的两个版本准许在开始的第一个点绘制曲线,下面的例子使用了5个点,产生了4个线段:
private: System::Void Form1_Paint(System::Object * sender,
System::Windows::Forms::PaintEventArgs * e)
{
Pen *penCurrent = new Pen(Color::Blue);
PointF pt[] = { PointF(20.00F, 322.00F), PointF(124, 24),PointF(214, 242), PointF(275, 28),
PointF(380.00F, 322.00F) };
e->Graphics->DrawCurve(penCurrent, pt);
}
效果如图所示:
![VC.NET的GDI+编程入门教程之图形(图二十)](http://www.itfensi.com/d/file/exploit/NET/vcnet/2007-03-15/6fb6f7f6149645998529daff0076b557.gif)
图二十、代码运行效果图
如果需要的话,可以随意在任意一个点开始曲线,为了支持这一点,Graphics类提供了以下版本的DrawCurve()方法:
public: void DrawCurve(Pen *pen, PointF[] points, int offset, int numberOfSegments);
offset参数用来规定在开始绘制之前跳需要跃过的点数,首先需要决定的就是offset参数必须设置为0或者更高的数,如果将这个参数设置为0,曲线将从第一个点开始绘制。如果这个参数设置为1,第一个点将不包含在曲线之内。这意味着曲线从第二个点开始绘制,以此类推。如果设置为2,第一和第二个点都不在曲线内,曲线从第三个点开始。
通过offset参数规定曲线的起点后,然后就需要设定曲线的段数,这个段数必须要小于可用的段数,它等于所有段落数减去offset值。下面是一个例子:
private: System::Void Form1_Paint(System::Object * sender,
System::Windows::Forms::PaintEventArgs * e)
{
Pen *penCurrent = new Pen(Color::Blue);
PointF pt[] = { PointF(20.00F, 322.00F), PointF(124, 24),PointF(214, 242), PointF(275, 28),
PointF(380.00F, 322.00F) };
e->Graphics->DrawCurve(penCurrent, pt, 1, 2);
}
效果图如下:
![VC.NET的GDI+编程入门教程之图形(图二十)](http://www.itfensi.com/d/file/exploit/NET/vcnet/2007-03-15/d2916bde751dc59ecf2620e7cb59845c.gif)
图二十一、代码运行效果图
再一次,编译器在绘制曲线时需要申请张力,如果愿意使用一个直线段或使用一个不同于默认值的张力的话,可以使用下列版本的Graphics::DrawCurve()方�%
- VC.NET的GDI+编程入门教程之图形
- VC.NET的GDI+编程入门教程之图形
- 基于VC.NET的GDI+编程之CImage方案
- 基于VC.NET的GDI+编程之CImage方案
- 基于VC.NET的GDI 编程之CImage方案
- 基于VC.NET的GDI+编程之CImage
- 基于VC.NET的GDI+编程之CImage(VC图像处理新招)
- GDI编程之七、图形编程实例
- 有关c#高级编程之---图形编程GDI+
- VC.net中使用GDI+的方法
- VC.net中使用GDI+的方法
- 基于VC.NET的GDI+图像处理
- 图形之GDI
- VC++ gdi+编程的基本代码
- C#学习之GDI + 图形编程基础(一)
- C#学习之GDI + 图形编程基础(二)
- VC GDI编程
- VC GDI编程
- mmap driver
- Web系统中的数据库系统
- 論網路信任 – 我怎麼知道網路那頭的人會不會騙我?
- pku1149
- 字符串
- VC.NET的GDI+编程入门教程之图形
- error C2036:'void *' : unknown size void*和void**的区别
- 请没有买房和买车的朋友一定认真的看一下(转)
- sql server 还原数据库失败
- vs2008 制作安装包
- 卡尔曼(Kalman)滤波简介~
- linux sed 批量替换多个文件中的字符串
- pku 1422 Air Raid 最小路径覆盖图 解题报告
- Nimbuzz使用心得