注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

信息 灵感 创新

I? =Information,Inspiration,Innovation

 
 
 

日志

 
 
关于我

we are 5. Mathematics, Computation, Programming, Engineering, and Making fun of life.

网易考拉推荐

GDI+路径(1)  

2011-07-25 21:01:50|  分类: C# & .NET |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

路径表示一系列相互连接的直线和曲线,它使得GDI+中的几何图形的连接显得更加自然,应用程序通过路径实现绘制形状的轮廓、填充形状内部和创建剪辑区域等操作。

路径的创建

GDI+中使用GraphicsPath类表示路径,路径可以通过下列六个构造函数来创建:

public GraphicsPath ();

Alternate FillMode 值初始化 GraphicsPath 类的新实例。

public GraphicsPath (FillMode fillMode);

使用指定的 FillMode 枚举初始化 GraphicsPath 类的新实例。

public GraphicsPath (Point[] pts,byte[] types);

使用指定的 PathPointType Point 数组初始化 GraphicsPath 类的新实例

public GraphicsPath (PointF[] pts,byte[] types);

使用指定的 PathPointType PointF 数组初始化 GraphicsPath 数组的新实例。

public GraphicsPath (Point[] pts,byte[] types,FillMode fillMode)      ;

使用指定的 PathPointType Point 数组以及指定的 FillMode 枚举元素初始化 GraphicsPath 类的新实例。

public GraphicsPath (PointF[] pts,byte[] types,FillMode fillMode);

使用指定的 PathPointType PointF 数组以及指定的 FillMode 枚举元素初始化 GraphicsPath 数组的新实例。

参数说明如下:

PtsPoint或者PointF 结构的数组,它定义组成此 GraphicsPath 的点的坐标。

TypesPathPointType 枚举元素的数组,它指定 pts 数组中各相应点的类型。可用的成员如下表:

成员名称

说明

Bezier

3

默认贝塞尔曲线

Bezier3

3

立体贝塞尔曲线

CloseSubpath

128

子路径的终结点

DashMode

16

对应线段为虚线

Line

1

连线线段

PathMarker

32

路径标记

PathTypeMask

7

遮盖点

Start

0

GraphicsPath 对象的起始点

GraphicsPath 对象中的每一点都具有与其关联的类型,该类型确定使用该点来绘制路径的方式。构成形状的点类型包括起始点、终结点和贝塞尔曲线点。类型还包括标记,这允许路径和掩码的简易遍历以显示或隐藏点。Line 类型以及任何贝塞尔曲线类型都可以与 CloseSubpath 结合使用(通过使用按位运算符 OR),以指示对应点是图形中的最后一个点并且该图形应闭合。

fillMode :一个 FillMode 枚举,它,该模式指定此 GraphicsPath 中的形状的内部如何填充。 可用的成员如下表:

成员每次

说明

Alternate  

指定交替填充模式

Winding

指定环绕填充模式

默认模式是 Alternate,即在交替模式中确定闭合图形的内部,绘制一条从路径中的任意起始点到明显位于路径外的某一点的直线。如果该直线跨过奇数个路径段,则起始点位于闭合区域内并且因此是填充或剪辑区域的一部分。如果该直线跨过偶数个路径段,则表明该起始点不位于要被填充或剪辑的区域内。通过使用直线将最后一点与图形的第一点相连接,填充或剪辑开放的图形。

Winding 模式考虑路径段在每个交叉处的方向。它为每一顺时针交叉加一,为每一逆时针交叉减一。如果结果非零,则认为该点在填充或剪辑区域的内部。计数为零意味着该点在填充或剪辑区域的外部。

下面是一个简单使用路径的例子,其中使用路径的填充。

private void button1_Click(object sender, EventArgs e)

{

    Graphics gp = this.CreateGraphics();

    PointF[] pts = PolygonPoints(5, new PointF(200, 200), 150, true);

    foreach(PointF pf in pts)

    {

        gp.FillEllipse(new SolidBrush(Color.Red),new RectangleF(pf.X-5,pf.Y-5,10,10));

    }

    byte[] types = new byte[]

    {

        (byte)PathPointType.Line,

        (byte)PathPointType.Bezier3,

        (byte)PathPointType.Bezier3,

        (byte)PathPointType.Bezier3,

        (byte)PathPointType.Line

    };

    GraphicsPath gpath = new GraphicsPath(pts, types);

    gp.FillPath(new SolidBrush(Color.Blue), gpath);        

}

/// <summary>

/// 返回标示一个正多边形的点的数组

/// </summary>

/// <param name="n">正多边形的边数</param>

/// <param name="Center">正多边形的中心</param>

/// <param name="Radius">正多边形内切或者外接圆的半径</param>

/// <param name="CircleType">true:外接圆半径,false:内切圆半径</param>

/// <returns>标示正多边形的数组</returns>

private PointF[] PolygonPoints(int n, PointF Center, double Radius, bool CircleType)

{

    PointF[] ret = new PointF[n];

    double r;

    PointF p;

    if (CircleType)

        r = Radius;

    else

        r = Radius / Math.Cos(Math.PI / n);

    for (int i = 0; i < n; i++)

    {

        p = new PointF();

        p.X = Center.X + (float)(r * Math.Cos(i * Math.PI * 2 / n));

        p.Y = Center.Y + (float)(r * Math.Sin(i * Math.PI * 2 / n));

        ret[i] = p;

    }

    return ret;

}

程序运行效果如下:

GDI+路径(1) - Castor - 趁年轻,多折腾~~

注意红色的点是控制点,弧线形状是由于PathPointType指定的贝赛尔曲线类型所造成的。

向路径中添加几何图形

       除了使用点定义轮廓外,还可以使用向路径中添加基本的几何图形,GraphicsPath类提供了许多方法,可用的如下表:

方法名

说明

AddArc

向当前图形追加一段椭圆弧

AddBezier

在当前图形中添加一段立方贝塞尔曲线

AddBeziers

在当前图形中添加一系列相互连接的立方贝塞尔曲线

AddClosedCurve

向此路径添加一个闭合曲线。由于曲线经过数组中的每个点,因此使用基数样条曲线

AddCurve

向当前图形添加一段样条曲线。由于曲线经过数组中的每个点,因此使用基数样条曲线

AddEllipse

向当前路径添加一个椭圆

AddLine

向此GraphicsPath 追加一条线段

AddLines

向此GraphicsPath 末尾追加一系列相互连接的线段

AddPath

将指定的GraphicsPath 追加到该路径

AddPie

向此路径添加一个扇形轮廓

AddPolygon

向此路径添加多边形

AddRectangle

向此路径添加一个矩形

AddRectangles

向此路径添加一系列矩形

AddString

向此路径添加文本字符串

下面是一个简单的例子:

private void button1_Click(object sender, EventArgs e)

{

    Graphics gp = this.CreateGraphics();

    GraphicsPath gpath = new GraphicsPath();

    Font f = new Font("Arial", 15);

    Point p1 = new Point(100, 100);

    Point p2 = new Point(200, 200);

    gpath.AddLine(p1, p2);

    gp.DrawString("p1",f,new SolidBrush(Color.Blue),p1);

    gp.DrawString("p2", f, new SolidBrush(Color.Blue), p2);

    Point p3 = new Point(250, 300);

    Point p4 = new Point(400, 50);

    gpath.AddLine(p3, p4);

    gp.DrawString("p3", f, new SolidBrush(Color.Blue), p3);

    gp.DrawString("p4", f, new SolidBrush(Color.Blue), p4);

    gp.DrawPath(new Pen(Color.Red, 2f), gpath);

}

程序运行效果如下:

GDI+路径(1) - Castor - 趁年轻,多折腾~~
 这里有一个问题。程序只是在路径中添加了两条直线,但是会多出一条直线(p2p3),这个是怎么来的呢?原来,路径要求保持连续,当下一个添加的图形的起点和上一个图形的终点不重合时,GraphicsPath会自动的添加一条直线将其连接起来。其他基本图形的添加类似。

开放路径和封闭路径

如上例中所见到的,这是一个开放的路径,即路径并没有封闭,事实上GraphicsPath提供的方法CloseFigure能够完成路径的自动封闭(当然就是在中点和起点之间添加一条直线)。如果在上例中最后一句DrawPath前加上语句:

gpath.CloseFigure();

则程序运行效果如下:

GDI+路径(1) - Castor - 趁年轻,多折腾~~
        自动完成了图形的封闭。

路径的填充

       DrawPath方法完成路径的绘制类似,Graphics类的方法FillPath完成路径的填充,虽然我们自然的认为填充的路径必须是一个封闭的路径,但是GDI+中也能对非封闭的路径进行填充,实际就是在非封闭的路径的终点自动的添加一条直线,完成路径的封闭,还是上面的一个例子:

private void button1_Click(object sender, EventArgs e)

{

    Graphics gp = this.CreateGraphics();

    GraphicsPath gpath = new GraphicsPath();

    Font f = new Font("Arial", 15);

    Point p1 = new Point(100, 100);

    Point p2 = new Point(200, 200);

    gpath.AddLine(p1, p2);

    gp.DrawString("p1",f,new SolidBrush(Color.Blue),p1);

    gp.DrawString("p2", f, new SolidBrush(Color.Blue), p2);

    Point p3 = new Point(250, 300);

    Point p4 = new Point(400, 50);

    gpath.AddLine(p3, p4);

    gp.DrawString("p3", f, new SolidBrush(Color.Blue), p3);

    gp.DrawString("p4", f, new SolidBrush(Color.Blue), p4);

    gp.FillPath(new SolidBrush(Color.FromArgb(150,0,255,0)), gpath);

}

程序运行效果如下:

GDI+路径(1) - Castor - 趁年轻,多折腾~~
 可见开放路径的填充并无异常。

  评论这张
 
阅读(3684)| 评论(2)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016