翼度科技»论坛 编程开发 .net 查看内容

不可不知的WPF几何图形(Geometry)

6

主题

6

帖子

18

积分

新手上路

Rank: 1

积分
18
在软件行业,经常会听到一句话“文不如表,表不如图”说明了图形在软件应用中的重要性。同样在WPF开发中,为了程序美观或者业务需要,经常会用到各种个样的图形。今天以一些简单的小例子,简述WPF开发中几何图形(Geometry)相关内容,仅供学习分享使用,如有不足之处,还请指正。
 
什么是几何图形(Geometry)

 
几何图形可以随意和进行缩放而不变形,这是和位图最大的差异。Geometry类及其派生类(PathGeometry,EllipseGeometry,CombinedGeometry)可以用于描述2D形状的几何图形。Geometry对象可以是矩形和椭圆形等简单图形,也可以是由两个或者多个几何对象创建的复合图形,如:PathGeometry和StreamGeometry等,可以用于绘制曲线或其他复杂图形。Geometry类继承自Freezable类,因此可以声明为资源,对象之间共享,变为只读提高性能,或者克隆及线程安全等。具体可了解Freezable相关知识。
 
几何图形与形状的区别

 
上一篇文章了解了Shape类也是在页面绘制图形,那Shape和Geometry有什么区别和联系呢?
首先Geometry和Shape类都是用于描述2D形状(如:EllipseGeometry和Ellipse),但它们之间存在一些重要的区别。具体如下:

  • Geometry继承自Freezable类,而Shape继承自FrameworkElement。所以Shape及其派生类可以在UI页面中独立存在并参与页面布局,而Geometry及其派生类则不能。
  • 由于Shape类是UI无素,所以Shape类比Geometry更易于使用,但是Geometry却更通用,Shape用于呈现2D图形,但是Geometry可用于定义2D图形的几何区域,定义裁剪的区域或命中测试区域等。
  • Shape派生类Path的Data属性,就是Geometry类型。所以可以理解为Shape是外在呈现形状,而Geometry是其内容,而Fill和Stroke属性,则对应画笔。
 
简单的几何图形

 
Geometry是abstract修饰的抽象类,所以只能使用其派生类进行绘制几何图形,而Geometry的派生类可以分为三个类别:简单几何,路径几何,复合几何。
简单几何图形,WPF系统自带了几个默认的几何图形,如LineGeometry,RectangleGeometry,和 EllipseGeometry,用于创建基本的几何图形,如:线条,矩形,椭圆等。

  • LineGeometry,通过指定直线的起点和终点来定义线条。
  • RectangleGeometry使有Rect结构来定义,指定矩形的相对位置,及高度和宽度。也可以使用RadiusX,RadiusY属性来创建圆角矩形。
  • EllipseGeometry由中心点,x轴半径,y轴半径来创建椭圆,如果x轴半径和y轴半径相等,则为圆形。
虽然PathGeometry也能实现基本的几何图形,但是用WPF默认提供的类,则更简单,也方便理解。
 
LineGeometry

 
由于Geometry不是UI元素,不能独立进行自我绘制并呈现 ,所以使用Path形状来呈现。LineGeometry通过设置起始点坐标(StartPoint)和结束坐标(EndPoint)来定义直线。
如下所示:
  1. <Path Stroke="Black" StrokeThickness="1" >
  2.     <Path.Data>
  3.         <LineGeometry StartPoint="10,20" EndPoint="100,130" />
  4.     </Path.Data>
  5. </Path>
复制代码
上述代码通过C#代码实现,如下所示:
  1. LineGeometry lineGeometry = new LineGeometry();
  2. lineGeometry.StartPoint = new Point(10, 20);
  3. lineGeometry.EndPoint = new Point(100, 130);
  4. Path path = new Path();
  5. path.Stroke = Brushes.Black;
  6. path.StrokeThickness = 1;
  7. path.Data = lineGeometry;
复制代码
通过LineGeometry实现直线,效果如下所示:

 
EllipseGeometry

 
EllipseGeometry通过设置中心点的坐标(Center)和x半径(RadiusX),y轴半径(RadiusY)来绘制椭圆。
绘制一个坐标相等的圆,如下所示:
  1. <Path Stroke="Black" StrokeThickness="1" >
  2.     <Path.Data>
  3.         <LineGeometry StartPoint="10,20" EndPoint="100,130" />
  4.     </Path.Data>
  5. </Path>
复制代码
上述代码通过C#代码实现,如下所示:
  1. EllipseGeometry ellipseGeometry = new EllipseGeometry();
  2. ellipseGeometry.Center = new Point(50, 50);
  3. ellipseGeometry.RadiusX = 50;
  4. ellipseGeometry.RadiusY = 50;
  5. Path path = new Path();
  6. path.Fill = Brushes.Gold;
  7. path.Stroke = Brushes.Black;
  8. path.StrokeThickness = 1;
  9. path.Data = ellipseGeometry;
复制代码
通过EllipseGeometry绘制圆,示例如下所示:

 
RectangleGeometry

 
RectangleGeometry通会Rect结构来描述矩形,分别是起始坐标和宽度,高度来定义矩形,如下所示:
  1. <Path Stroke="Black" StrokeThickness="1" >
  2.     <Path.Data>
  3.         <LineGeometry StartPoint="10,20" EndPoint="100,130" />
  4.     </Path.Data>
  5. </Path>
复制代码
上述代码用C#实现,如下所示:
  1. RectangleGeometry rectangleGeometry = new RectangleGeometry();
  2. rectangleGeometry.Rect = new Rect(50, 50, 100, 60);
  3. Path path = new Path();
  4. path.Fill = Brushes.LemonChiffon;
  5. path.Stroke = Brushes.Black;
  6. path.StrokeThickness = 1;
  7. path.Data = rectangleGeometry;
复制代码
通过RectangleGeometry绘制矩形,示例如下所示:

 
图像裁剪

 
通过将Geometry应用到Image的Clip属性,可以实现图像的裁剪功能,如下所示:
  1. <Path Stroke="Black" StrokeThickness="1" >
  2.     <Path.Data>
  3.         <LineGeometry StartPoint="10,20" EndPoint="100,130" />
  4.     </Path.Data>
  5. </Path><Path Stroke="Black" StrokeThickness="1" >
  6.     <Path.Data>
  7.         <LineGeometry StartPoint="10,20" EndPoint="100,130" />
  8.     </Path.Data>
  9. </Path><Path Stroke="Black" StrokeThickness="1" >
  10.     <Path.Data>
  11.         <LineGeometry StartPoint="10,20" EndPoint="100,130" />
  12.     </Path.Data>
  13. </Path>   
复制代码
上述代码用C#实现如下所示:
  1. Image image = new Image();
  2. Uri imageUri = new Uri(@"imgs\bingdundun.jpeg", UriKind.RelativeOrAbsolute);
  3. image.Source = new BitmapImage(imageUri);
  4. image.Width = 300;
  5. image.Height = 200;
  6. image.HorizontalAlignment = HorizontalAlignment.Left;
  7. // 用椭圆定义裁剪区域.
  8. EllipseGeometry ellipseGeometry = new EllipseGeometry();
  9. ellipseGeometry.Center = new Point(150, 10);
  10. ellipseGeometry.RadiusX = 130;
  11. ellipseGeometry.RadiusY = 80;
  12. image.Clip = ellipseGeometry;
复制代码
通过Geometry实现图像裁剪,示例如下所示:

 
路径几何

 
PathGeometry类及其轻型等效项(StreamGeometry类)主要用于描述弧线,曲线,直线组成的多个复杂图形的方法。PathGeometry的核心是PathFigure对你的集合。每一个PathFigure本身由一个或多个PathSegment对象组成,每一个PathSegment描述图形的一个小部分。常见的PathSegment主要有以下几种:

  • ArcSegment,表示两点之间创建一条椭圆弧。
  • BezierSegment,表示两个点之间的三次方贝塞尔曲线。
  • LineSegment,表示两个点之间的直线。
  • PolyBezierSegment,表示创建一系列的三次方贝塞尔曲线。
  • PolyLineSegment,表示创建一系列直线。
  • PolyQuadraticBezierSegment ,表示创建一系列二次贝塞尔曲线。
  • QuadraticBezierSegment,表示创建一条贝塞尔曲线。
关于PathFigure有以下几点说明:

  • PathFigure内的多个线段组合成单个几何形状,每个线段的终点,就是下一个线段的起点。
  • PathFigure的StartPoint属性指定绘制第一个线段的起点。
  • 每一个线段都从上一个线段的终点开始。
关于PathGeometry的示例代码如下所示:
  1. <Path Stroke="Black" StrokeThickness="1" >
  2.     <Path.Data>
  3.         <LineGeometry StartPoint="10,20" EndPoint="100,130" />
  4.     </Path.Data>
  5. </Path><Path Stroke="Black" StrokeThickness="1" >
  6.     <Path.Data>
  7.         <LineGeometry StartPoint="10,20" EndPoint="100,130" />
  8.     </Path.Data>
  9. </Path><Path Stroke="Black" StrokeThickness="1" >
  10.     <Path.Data>
  11.         <LineGeometry StartPoint="10,20" EndPoint="100,130" />
  12.     </Path.Data>
  13. </Path><Path Stroke="Black" StrokeThickness="1" >
  14.     <Path.Data>
  15.         <LineGeometry StartPoint="10,20" EndPoint="100,130" />
  16.     </Path.Data>
  17. </Path><Path Stroke="Black" StrokeThickness="1" >
  18.     <Path.Data>
  19.         <LineGeometry StartPoint="10,20" EndPoint="100,130" />
  20.     </Path.Data>
  21. </Path><Path Stroke="Black" StrokeThickness="1" >
  22.     <Path.Data>
  23.         <LineGeometry StartPoint="10,20" EndPoint="100,130" />
  24.     </Path.Data>
  25. </Path><Path Stroke="Black" StrokeThickness="1" >
  26.     <Path.Data>
  27.         <LineGeometry StartPoint="10,20" EndPoint="100,130" />
  28.     </Path.Data>
  29. </Path><Path Stroke="Black" StrokeThickness="1" >
  30.     <Path.Data>
  31.         <LineGeometry StartPoint="10,20" EndPoint="100,130" />
  32.     </Path.Data>
  33. </Path><Path Stroke="Black" StrokeThickness="1" >
  34.     <Path.Data>
  35.         <LineGeometry StartPoint="10,20" EndPoint="100,130" />
  36.     </Path.Data>
  37. </Path><Path Stroke="Black" StrokeThickness="1" >
  38.     <Path.Data>
  39.         <LineGeometry StartPoint="10,20" EndPoint="100,130" />
  40.     </Path.Data>
  41. </Path><Path Stroke="Black" StrokeThickness="1" >
  42.     <Path.Data>
  43.         <LineGeometry StartPoint="10,20" EndPoint="100,130" />
  44.     </Path.Data>
  45. </Path><Path Stroke="Black" StrokeThickness="1" >
  46.     <Path.Data>
  47.         <LineGeometry StartPoint="10,20" EndPoint="100,130" />
  48.     </Path.Data>
  49. </Path>
复制代码
上述XAML代码用C#实现,如下所示:
  1. PathFigure pathFigure = new PathFigure();
  2. pathFigure.StartPoint = new Point(10, 50);
  3. pathFigure.Segments.Add(
  4.     new BezierSegment(
  5.         new Point(100, 0),
  6.         new Point(200, 200),
  7.         new Point(300, 100),
  8.         true /* IsStroked */  ));
  9. pathFigure.Segments.Add(
  10.     new LineSegment(
  11.         new Point(400, 100),
  12.         true /* IsStroked */ ));
  13. pathFigure.Segments.Add(
  14.     new ArcSegment(
  15.         new Point(200, 100),
  16.         new Size(50, 50),
  17.         45,
  18.         true, /* IsLargeArc */
  19.         SweepDirection.Clockwise,
  20.         true /* IsStroked */ ));
  21. /// Create a PathGeometry to contain the figure.
  22. PathGeometry pathGeometry = new PathGeometry();
  23. pathGeometry.Figures.Add(pathFigure);
  24. // Display the PathGeometry.
  25. Path path = new Path();
  26. path.Stroke = Brushes.Black;
  27. path.StrokeThickness = 1;
  28. path.Data = pathGeometry;
复制代码
上述代码创建的形状如下所示:

与 PathGeometry 类一样,StreamGeometry 定义可能包含曲线、弧线和直线的复杂几何形状。 与 PathGeometry 不同,StreamGeometry 的内容不支持数据绑定、动画或修改。 当需要描述复杂几何图形,但又不希望产生支持数据绑定、动画或修改的开销时,请使用 StreamGeometry。 由于 StreamGeometry 类的高效性,该类是描述装饰器的不错选择。
 
复合几何

 
使用 GeometryGroup、CombinedGeometry 或通过调用静态 Geometry 方法 Combine,可以创建复合几何对象。两者之间的差异如下:

  • CombinedGeometry 对象和 Combine 方法执行布尔运算,以合并由两个几何图形定义的面积。 没有面积的 Geometry 对象将被放弃。 只能合并两个 Geometry 对象(尽管这两个几何图形也可能是复合几何)。
  • GeometryGroup 类创建其包含的 Geometry 对象的合并,而不合并其面积。 可以将任意数量的 Geometry 对象添加到 GeometryGroup。由于它们不执行合并操作,因此使用 GeometryGroup 对象的性能比使用 CombinedGeometry 对象或 Combine 方法的性能高。
简单点来说:GeometryGroup是进行对象的合并,CombinedGeometry是进行合并对象的布尔运算。
下面示例CombinedGeometry的“并集”,如下所示:
  1. <Path Stroke="Black" StrokeThickness="1" >
  2.     <Path.Data>
  3.         <LineGeometry StartPoint="10,20" EndPoint="100,130" />
  4.     </Path.Data>
  5. </Path><Path Stroke="Black" StrokeThickness="1" >
  6.     <Path.Data>
  7.         <LineGeometry StartPoint="10,20" EndPoint="100,130" />
  8.     </Path.Data>
  9. </Path><Path Stroke="Black" StrokeThickness="1" >
  10.     <Path.Data>
  11.         <LineGeometry StartPoint="10,20" EndPoint="100,130" />
  12.     </Path.Data>
  13. </Path><Path Stroke="Black" StrokeThickness="1" >
  14.     <Path.Data>
  15.         <LineGeometry StartPoint="10,20" EndPoint="100,130" />
  16.     </Path.Data>
  17. </Path><Path Stroke="Black" StrokeThickness="1" >
  18.     <Path.Data>
  19.         <LineGeometry StartPoint="10,20" EndPoint="100,130" />
  20.     </Path.Data>
  21. </Path><Path Stroke="Black" StrokeThickness="1" >
  22.     <Path.Data>
  23.         <LineGeometry StartPoint="10,20" EndPoint="100,130" />
  24.     </Path.Data>
  25. </Path>        
复制代码
 
CombinedGeometry并集示例如下所示:

以上就是《不可不知的WPF几何图形(Geometry)》的全部内容,旨在抛砖引玉,一起学习,共同进步。

来源:https://www.cnblogs.com/hsiang/p/18401958
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具