Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >【愚公系列】2024年01月 GDI+绘图专题 GraphicsPath

【愚公系列】2024年01月 GDI+绘图专题 GraphicsPath

原创
作者头像
愚公搬代码
发布于 2024-01-04 06:08:12
发布于 2024-01-04 06:08:12
4070
举报
文章被收录于专栏:历史专栏历史专栏

🏆 作者简介,愚公搬代码 🏆《头衔》:华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,阿里云专家博主,腾讯云优秀博主,掘金优秀博主,51CTO博客专家等。 🏆《近期荣誉》:2022年CSDN博客之星TOP2,2022年华为云十佳博主等。

🏆《博客内容》:.NET、Java、Python、Go、Node、前端、IOS、Android、鸿蒙、Linux、联网、络安全、数据、工智能、U3D游戏、小程序等相关领域知识。

🏆🎉欢迎 👍点赞✍评论⭐收藏

🚀前言

GraphicsPath类是在WinForm中用于绘制自定义形状的类,它表示由一系列路径段和连接线段组成的形状。

GraphicsPath类可以用于创建和编辑几何路径,以便在图形设备上渲染复杂的形状。 GraphicsPath类提供了一系列方法,如AddLine、AddRectangle、AddEllipse等,用于向路径中添加线段、矩形、椭圆等几何形状。

GraphicsPath类还可以进行路径操作,如平移、旋转、缩放、联合、剪切、差异等,以创建更复杂的形状。例如,应用一个旋转变换可以在GraphicsPath中旋转图形,而将一个路径添加到另一个路径可以将两个形状组合成更复杂的形状。

GraphicsPath类可以用于绘制线条、多边形、曲线和文本等复杂形状,使得在WinForm应用程序中实现高级绘图功能变得更为容易。

🚀一、GraphicsPath

🔎1.属性

🦋1.1 FillMode属性

FillMode属性指定如何填充GraphicsPath对象的内部区域。它的值是FillMode枚举类型之一:Alternate和Winding。

  • Alternate表示交替填充图形内部的每个区域。具体来说,它会跳过每隔图形内部有一个交叉点时的绘制。这意味着如果两个区域重叠,则只绘制其中一个区域。
  • Winding表示按照顺时针或逆时针方向绘制GraphicsPath对象内部区域。如果两个区域重叠,则会绘制交叉区域的顶点。

以下是使用FillMode属性绘制两个图形的示例:

代码语言:csharp
AI代码解释
复制
//创建两个GraphicsPath对象,一个矩形和一个三角形
GraphicsPath path1 = new GraphicsPath();
path1.AddRectangle(new Rectangle(100, 100, 100, 100));

GraphicsPath path2 = new GraphicsPath();
path2.AddPolygon(new Point[] { new Point(50, 200), new Point(200, 200), new Point(125, 50) });

//设置FillMode属性为Alternate并绘制
path1.FillMode = FillMode.Alternate;
e.Graphics.FillPath(Brushes.Red, path1);

//设置FillMode属性为Winding并绘制
path2.FillMode = FillMode.Winding;
e.Graphics.FillPath(Brushes.Blue, path2);

🦋1.2 PathData属性

PathData属性返回一个PathData对象,该对象包含了GraphicsPath对象的几何形状数据。具体来说,PathData对象包含了一个PathPoints数组和一个PathTypes数组,分别用于存储路径的顶点和线段类型。

以下是路径数据的示例:

代码语言:csharp
AI代码解释
复制
//创建GraphicsPath对象和PathData对象
GraphicsPath path = new GraphicsPath();
path.AddEllipse(new Rectangle(100, 100, 100, 50));

PathData pathData = path.PathData;

//获取顶点数据并输出
PointF[] points = pathData.Points;
foreach (PointF point in points)
{
    Console.WriteLine("({0}, {1})", point.X, point.Y);
}

//获取线段类型数据并输出
byte[] types = pathData.Types;
foreach (byte type in types)
{
    Console.WriteLine(type);
}

🦋1.3 PathPoints属性

PathPoints属性是一个PointF数组,用于获取或设置GraphicsPath对象的所有顶点。这可以用于修改或者处理路径的顶点数据。

以下是修改顶点数据并重新绘制GraphicsPath对象的示例:

代码语言:c#
AI代码解释
复制
//创建一个GraphicsPath对象和一个Brush对象
GraphicsPath path = new GraphicsPath();
path.AddRectangle(new Rectangle(100, 100, 100, 100));

SolidBrush brush = new SolidBrush(Color.Red);

//绘制原始矩形
e.Graphics.FillPath(brush, path);

//修改顶点数据并重新绘制
PointF[] points = path.PathPoints;
for (int i = 0; i < points.Length; i++)
{
    points[i].Y += 50;
}

e.Graphics.FillPath(brush, path);

🦋1.4 PathTypes属性

PathTypes属性是一个byte数组,用于获取或设置GraphicsPath对象的所有线段类型。线段类型可以是线段、曲线、角等等。

以下是修改线段类型数据并重新绘制GraphicsPath对象的示例:

代码语言:c#
AI代码解释
复制
//创建一个GraphicsPath对象和一个Brush对象
GraphicsPath path = new GraphicsPath();
path.AddRectangle(new Rectangle(100, 100, 100, 100));

SolidBrush brush = new SolidBrush(Color.Red);

//绘制原始矩形
e.Graphics.FillPath(brush, path);

//修改线段类型数据并重新绘制
byte[] types = path.PathTypes;
for (int i = 0; i < types.Length; i++)
{
    if (types[i] == (byte)PathPointType.Line)
    {
        types[i] = (byte)PathPointType.Bezier3;
    }
}

e.Graphics.FillPath(brush, path);

FillMode、PathData、PathPoints和PathTypes属性可以用于操作和处理GraphicsPath对象的几何形状数据,从而实现更加复杂的图形绘制和处理。

🔎2.方法

🦋2.1 IsOutlineVisible

IsOutlineVisible是GraphicsPath类的一个方法,用于检查路径是否被指定的画笔和区域所覆盖。

该方法有两个重载:

  1. IsOutlineVisible(PointF point, Pen pen):判断指定的点是否在路径的边缘范围内,如果点在路径的边缘范围内,则返回True,否则返回False。
  2. IsOutlineVisible(PointF point, Pen pen, Graphics graphics):与第一个重载不同的是,需要传递一个Graphics对象,该对象用于指定路径的坐标系统。

示例代码:

代码语言:csharp
AI代码解释
复制
GraphicsPath path = new GraphicsPath();
path.AddRectangle(new Rectangle(10, 10, 100, 100));
Pen pen = new Pen(Color.Blue, 2);

// 判断指定点是否在路径的边缘范围内
bool isOutlineVisible = path.IsOutlineVisible(new PointF(10, 10), pen);
Debug.WriteLine(isOutlineVisible); // True

// 在指定的Graphics对象中绘制路径
using (Graphics g = this.CreateGraphics())
{
    g.DrawPath(pen, path);
}

// 使用Graphics对象判断指定点是否在路径的边缘范围内
bool isOutlineVisible1 = path.IsOutlineVisible(new PointF(120, 120), pen, this.CreateGraphics());
Debug.WriteLine(isOutlineVisible1); // False

在上面的代码中,我创建了一个矩形路径,并使用蓝色画笔在窗体中绘制出来。然后,我使用IsOutlineVisible方法检查两个点是否在路径的边缘范围内,并输出结果,其中第一个点在路径的边缘范围内,第二个点不在范围内。

需要注意的是,IsOutlineVisible方法只能检查点是否在路径的边缘范围内,如果需要检查点是否在路径内部,则需要使用IsVisible方法。同时,如果路径中存在多个子路径,则需要使用IsVisible方法的重载版本。

🦋2.2 IsVisible

在使用GraphicsPath的IsVisible方法时,需要提供一个Point对象作为参数,方法会返回一个bool值,表示该点是否在GraphicsPath中可见。

例如,以下代码创建了一个GraphicsPath对象,并使用IsVisible方法检查指定的点是否在路径中可见:

代码语言:csharp
AI代码解释
复制
GraphicsPath path = new GraphicsPath();
path.AddEllipse(0, 0, 100, 100);
bool isVisible = path.IsVisible(50, 50);
Debug.WriteLine(isVisible); // true

上述代码会创建一个椭圆形的GraphicsPath对象,并使用IsVisible方法检查指定的点(50,50)是否在路径中可见。

需要注意的是,IsVisible方法是针对路径的形状进行判断的,而不是路径的颜色或填充。如果路径已经被填充了,那么仍然可以使用IsVisible方法来判断填充区域的可见性。

🦋2.3 StartFigure

在使用GraphicsPath绘制图形时,StartFigure方法用于开始一个新的图形子路径。这个方法在绘制多个图形时非常有用,因为它可以帮助我们创建独立的图形,而不会互相影响。

例如,如果我们要绘制一个由两个矩形组成的图形,我们可以使用以下代码:

代码语言:csharp
AI代码解释
复制
GraphicsPath path = new GraphicsPath();
path.AddRectangle(new Rectangle(10, 10, 50, 50));
path.StartFigure();
path.AddRectangle(new Rectangle(70, 10, 50, 50));
Pen pen = new Pen(Color.Black, 2);
e.Graphics.DrawPath(pen, path);

在上面的代码中,我们首先创建了一个GraphicsPath对象,并使用AddRectangle方法添加了第一个矩形,然后调用StartFigure方法开始一个新的图形子路径,最后再添加第二个矩形。这样,我们就创建了两个独立的矩形,它们不会相互连接。

另外,StartFigure方法还可以用于创建空的图形子路径,如下所示:

代码语言:csharp
AI代码解释
复制
GraphicsPath path = new GraphicsPath();
path.StartFigure();
path.AddLine(new Point(10, 10), new Point(50, 50));
Pen pen = new Pen(Color.Black, 2);
e.Graphics.DrawPath(pen, path);

在上面的代码中,我们创建了一个空的图形子路径,并使用AddLine方法添加了一条线段。这种方法可以让我们在不同的位置创建不同的图形,而不会互相干扰。

🦋2.4 CloseFigure

GraphicsPath是一个用于创建和管理图形路径的类,它允许您定义一个形状并在其中添加线条、曲线和其他图形元素。

CloseFigure是GraphicsPath中的一个方法,它可用于将当前路径的最后一个点与路径的起始点连接起来,形成一个封闭的形状。当您需要创建具有填充和边框的封闭形状时,CloseFigure非常有用。

下面是一个示例,展示了如何使用CloseFigure来创建一个简单的封闭路径:

代码语言:csharp
AI代码解释
复制
GraphicsPath path = new GraphicsPath();
path.AddLine(10, 10, 50, 50);
path.AddLine(50, 50, 10, 90);
path.AddLine(10, 90, 10, 10);
path.CloseFigure();

Pen pen = new Pen(Color.Black, 2);
e.Graphics.DrawPath(pen, path);

在这个示例中,我们使用AddLine方法添加三条线条来创建一个三角形路径。然后,我们使用CloseFigure方法将路径封闭起来。最后,我们使用DrawPath方法将路径绘制在Graphics对象上。

请注意,如果您想绘制填充的形状,您需要使用Graphics对象的FillPath方法而不是DrawPath方法。

🦋2.5 CloseAllFigures

GraphicsPath是C#中的一个类,用于表示一个二维图形的路径,包括曲线和直线等。CloseAllFigures是其中的一个方法,它的作用是关闭所有的子路径,使其成为一个完整的图形路径。

具体来说,当我们使用GraphicsPath类的AddXXX方法添加多条路径时,这些路径会被视为子路径,而CloseAllFigures方法可以将这些子路径连接起来,形成一个闭合的路径,使其成为一个完整的图形。

例如,下面的代码创建了一个GraphicsPath对象,并添加了两条直线和一条曲线。在调用CloseAllFigures方法后,这些路径就会被连接成一个封闭的路径。

代码语言:csharp
AI代码解释
复制
GraphicsPath path = new GraphicsPath();
path.AddLine(0, 0, 50, 50);
path.AddLine(50, 50, 100, 0);
path.AddBezier(100, 0, 150, 50, 200, -50, 250, 0);
path.CloseAllFigures();

Pen pen = new Pen(Color.Black, 2);
e.Graphics.DrawPath(pen, path);

注意,如果使用CloseFigure方法只会关闭当前路径,而不会影响其他子路径。因此,如果需要完全闭合整个图形路径,应该使用CloseAllFigures方法。


原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Python笔记(十):正则表达式
正则表达式对比工具 https://pan.baidu.com/s/1XIPyF1vFSj5PACPx9zW8_g (一)      正则表达式符号和特殊字符 符号 说明 示例 | 或 re1|re2,匹配re1或re2 . 匹配任何字符(\n除外) ^ 匹配字符串开始部分 ^ab.* 以ab开始的字符串,匹配ab123、ababc等等 $ 匹配字符串结束部分 .*123$ 以123结束的字
free赖权华
2018/04/27
7060
Python笔记(十):正则表达式
正则表达式获取一串网址的域名段代码
比如:http://www.baidu.com/aaaa/bbb/cccc.html
小小鱼儿小小林
2024/05/25
1720
正则表达式获取一串网址的域名段代码
常用的正则表达式
. 匹配除回车(\r)、换行(\n) 、行分隔符(\u2028) 和 段分隔符(\u2029) 以外的所有字符
用户3880999
2023/04/13
1K0
常用的正则表达式
每周学点测试小知识-正则表达式
好久不见的每周学点测试小知识,在上周的课堂上芒果给大家介绍了正则表达式,在这里我们简单的复习一下,认识一下正则表达式,并且学习一些常用的元字符:
TestOps
2022/04/07
3950
使用正则表达式
正则表达式相关知识 在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要,正则表达式就是用于描述这些规则的工具,换句话说正则表达式是一种工具,它定义了字符串的匹配模式(如何检查一
用户8442333
2021/05/19
6820
Python 正则表达式:split
本文以 提取URL的地址与参数 为例,介绍re模块的split的用法: 返回值 -> 列表
py3study
2020/01/14
2K0
Linux||正则表达式及grep命令
正则表达式(Regular Expression)是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符及这些字符的特定组合,组成一个“规则字符串”,这个字符串用来表达对字符串的一种过滤逻辑。
小汪Waud
2023/02/03
1.6K0
Linux||正则表达式及grep命令
正则表达式之入门篇
本文主要通过对正则表达式的语法进行一些简单的介绍,从而让没有接触过或者想学习正则表达式的同学有一个基础的了解,从而能够看懂和编写使用一般的正则表达式。
黄Java
2018/11/01
4670
正则表达式
1.17 正则的引用 所在的位置就看左侧的"("所在的位置,在第一个就是\1,第二个就是\2,嵌套引用也是这个道理
张琳兮
2018/09/10
8460
正则表达式
1、正则表达式
前端往往有大量的表单数据校验的工作,采用正则表达式会使得数据校验的工作量大大减轻,如邮箱验证,手机号码,等等。比起用字符串的函数来判断简单,易用。
Daotin
2022/11/28
5540
正则表达式教程
http://regex.larsolavtorvik.com/ http://tool.oschina.net/regex http://www.rubular.com/ http://zhengze.51240.com/ http://www.kingshang.com/ http://zhengze.51240.com/
老高的技术博客
2022/12/24
1.9K0
C++正则表达式攻略:从基础到高级应用
正则表达式是一种用于匹配、搜索和编辑文本的字符串模式。它由一系列字符和特殊符号构成,可以灵活地表达文本的模式、结构和特征。正则表达式在各种编程语言和应用程序中广泛应用,包括C++。它可以用来在文本中查找特定模式的字符串、验证输入的格式、提取信息和进行文本替换等操作。
Lion Long
2025/01/19
2270
C++正则表达式攻略:从基础到高级应用
正则表达式
正则表达式( Regular Expression )是用于匹配字符串中字符组合的模式。在JavaScript中,正则表达式也是对象。
星辰_大海
2020/10/26
9710
正则表达式
分分钟使用正则表达式 原
        从概念上来说,正则表达式也是一门小巧而精炼的语言,它可以用来简化检索特定的字符串,替换特定字符等功能,有许多开发语言工具,都内嵌支持正则表达式。那么一个正则表达式,究竟是什么?其实它就是一个字符串,但这个字符串具有特定含义。
珲少
2018/08/15
6030
Python3中正则表达式使用方法
崔庆才,Python技术控,爬虫博文访问量已过百万。喜欢钻研,热爱生活,乐于分享。
生信宝典
2019/10/14
6910
正则表达式
一、概述 正则表达式(regular expression)是一种表达文本模式(即字符串结构)的方法,有点像字符串的模板,常常用作按照“给定模式”匹配文本的工具。正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。 JavaScript通过内置对象RegExp支持正则表达式,有两种方式创建正则表达式对象。例如,如果我们想匹配字符串中所有"at"的实例,可以这么写: 第一种:使用字面量,以斜杠表示开始和结束。 var
小胖
2018/06/27
5580
正则表达式介绍
Regex(英语:Regular Expression,在代码中常简写为 regex 、 regexp 或 RE ),又称正规表示式、正規表示法、正規運算式、規則運算式、常規表示法,是计算机科学的一个概念 ,正则表达式是一种编写匹配字符串的模式的方法。通常这些模式可用于搜索特定事物的字符串,或搜索然后替换某些事物等。正则表达式非常适合字符串操作!
iOSDevLog
2019/04/18
5K0
正则表达式介绍
正则表达式
很多人觉得正则很难,在我看来,这些人一定是没有用心。其实正则很简单,根据二八原则,我们只需要懂 20% 的内容就可以解决 80% 的问题了。我曾经有几年几乎每天都跟正则打交道,刚接手项目的时候我对正则也是一无所知,花半小时百度了一下,然后写了几个 demo,就开始正式接手了。三年多时间,我用到的正则鲜有超出我最初半小时百度到的知识的。
Crossin先生
2019/09/05
5080
正则表达式
学会正则表达式,玩弄文本于股掌之中
由于微信不允许外部链接,你需要点击页尾左下角的“阅读原文”,才能访问文中的链接。
somenzz
2020/12/10
7530
学会正则表达式,玩弄文本于股掌之中
Linux通配符和正则表达式通配符 区别_linux正则表达式语法
通配符是shell在做PathnameExpansion时用到的。说白了一般只用于文件名匹配,它是由shell解析的,比如find,ls,cp,mv等。
全栈程序员站长
2022/10/02
5.2K0
Linux通配符和正则表达式通配符 区别_linux正则表达式语法
相关推荐
Python笔记(十):正则表达式
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档