《15天玩转WPF》—— 绘图之 Path 知识详解

路径(Path)是一种非常强大的工具,它可以完全替代其他几种图形,例如上篇的文章中,
几种图形:
直线、矩形、椭圆的各种画法

它可以将各种图形结合起来,形成更复杂的图形。它有一个属性是 Data,它的类型是Geomery(几何图形). . . 它是一个抽象类,我们不能直接使用 . . .


文章目录

  • Geometry 的子类介绍
  • 直线、矩形、椭圆几何图形的使用
  • PathGeometry的各种线段的使用
  • 路径标记语法的使用
  • 使用 Path 剪裁界面元素

.

Geometry 的子类介绍

因为Geometry是一个抽象类,所以我们不能直接使用,但我们可以使用它的子类,Geometry的子类包括:

LineGeometry直线几何图形
Reometry矩形几何图形
EllipseGeometry椭圆几何图形
PathGeometry路径几何图形(功能最强大
StreamGeometryPathGeometry的轻量级替代品,不支持 Bidning、动画等功能
CombinedGeometry多图形组合,形成单一几何几何图形
GeometryGroup多图形组合,形成几何图形组

为了我们已经有了 Line、Rectangle、Ellipse这些属性后,还要出现上面加 Geometry的类呢?

区别在于前面的对象是可以独立存在的,而后面是不能单独存在的,要结合其它几何图形 . . .


.

直线、矩形、椭圆几何图形的使用

回到我们开头所说的 Data属性,下面这个例子是简要展示各个几何图形:

  1. 直线几何图形(LineGeometry):
<Path Stroke="Black" StrokeThickness="3" Grid.Column="0" Grid.Row="0"><Path.Data><LineGeometry StartPoint="20,20" EndPoint="120,120"/></Path.Data>
</Path>

LineGeometry中的 StartPoint 和 EndPoint属性设置线的开始与结束位置 . . .

效果如下:

在这里插入图片描述

  1. 矩形几何图形(RectangleGeometry):
<Path Stroke="Red" Fill="Yellow" StrokeThickness="2" Grid.Column="1" Grid.Row="0"><Path.Data><RectangleGeometry Rect="20,20,120,120" RadiusX="30" RadiusY="30"/></Path.Data>
</Path>

Rect属性设置矩形的大小,Radiux设置矩形的圆角属性 . . .

效果如下:

在这里插入图片描述

  1. 椭圆几何图形(EllipseGeometry):
<Path Stroke="Green" Fill="LawnGreen" Grid.Column="0" Grid.Row="1"><Path.Data><EllipseGeometry Center="80,80" RadiusX="60" RadiusY="60"/></Path.Data>
</Path>

效果如下:
在这里插入图片描述

Geometry的其它几个子类,我们将在下面的例子中讲解 . . .


.

PathGeometry的各种线段的使用

PathGeometry 之所以如此重要,是因为 Path的 Figures属性可以容纳 PathFigure对象,而 PathFigure 的 Segments属性又可以容纳各种线段结合成的复杂图形。它的XAML代码结构如下所示:

<Path><Path.Data><PathGeometry><PathFigure><!--各种线段-->  </PathFigure></PathGeometry></Path.Data>
</Path>

为什么没有 Figures属性 和 Segments呢? 因为 Figures是 PathGeometry的默认内容属性,Segments是 Pathfigure的默认内容属性, 所以我们可以省略不写 . . .

了解了上面这个格式之后,我们就可以来认识一下线段都有哪些,它们是:

LineSegment直线段
ArcSegment圆弧线段
BezierSegment三次方贝塞尔曲线段
QuadraticBezierSegmnt二次方贝塞尔曲线段
PolyLineSegment多直线段
PolyBezierSegment多三次方贝塞尔曲线段
PolyQuadraticBezierSegment多二次方贝塞尔曲线段

注意一下,这些线段是没有起点,起点就是前一个线段的终点 . . .
第一个起点是 PathFigure的 StartPoint 属性. . .

下面我们来演示一下这些线段的使用,最后三个不演示(只是变得将上面的方法变得简单了):

  1. 直线段(LineSegment):
<Path Fill="Red" Margin="20"><Path.Data><PathGeometry><PathFigure IsClosed="True" StartPoint="0,0"><LineSegment Point="150,0"/><LineSegment Point="150,30"/><LineSegment Point="90,30"/><LineSegment Point="90,150"/><LineSegment Point="60,150"/><LineSegment Point="60,30"/><LineSegment Point="0,30"/></PathFigure></PathGeometry></Path.Data>
</Path>

其中,我们画了好几条线,它的效果如下:

在这里插入图片描述

  1. 圆弧线段(ArcSegment):
<Path Stroke="Red" StrokeThickness="2"><Path.Data><PathGeometry><PathFigure StartPoint="130,30"><ArcSegment Point="100,100" Size="100,100"SweepDirection="Clockwise" IsLargeArc="True"RotationAngle="-45"/></PathFigure></PathGeometry></Path.Data>
</Path>

其中,我们为 ArcSegment设置许多属性,它们分别是:

  • Point:指明圆弧连接的终点
  • Size:指明完整椭圆的横轴半径和纵轴半径
  • IsLargeArc:指明是否使用大弧去连接 . . .
  • SweepDirection :指明圆弧是顺时针方向还是逆时针方向
  • RotationAngle:指明圆弧椭圆的旋转角度

效果如下:

在这里插入图片描述
通过对 IsLargeArc 的修改,我们可以得到如下效果:

在这里插入图片描述

ArcSegment 的几个属性变化时的效果对比:

在这里插入图片描述

.

  1. 贝塞尔曲线(BezierSegment):

贝塞尔曲线由 4 个点决定:

  • (1)起点:前一线段的终点 或者 PathFigure 的 StartPoint
  • (2)终点:Point3 属性,即曲线的终点位置
  • (3)两个控制点:Point1 和 Point2 属性

例一,简单的一个三次方贝塞尔曲线:

<Path Stroke="Black" StrokeThickness="2" Margin="30"><Path.Data><PathGeometry><PathFigure StartPoint="0,0"><BezierSegment Point1="250,0" Point2="50,200" Point3="300,200"/></PathFigure></PathGeometry></Path.Data>
</Path>

效果如下:

在这里插入图片描述

二次方贝塞尔曲线和三次方差不多,只不过由 3 个点决定了而已,可以查看相关文档测试 . . .

.

例二,用 GeometryGroup 将多个贝塞尔曲线组合在一起 形成更复杂的图形:

<Path Stroke="Black" Fill="LightBlue" StrokeThickness="1"><Path.Data><GeometryGroup><PathGeometry><PathFigure StartPoint="0,0"><BezierSegment Point1="250,0" Point2="50,200" Point3 ="300,200"/></PathFigure></PathGeometry><PathGeometry><PathFigure StartPoint="0,0"><BezierSegment Point1="230,0" Point2="50,200" Point3 ="300,200"/></PathFigure></PathGeometry><PathGeometry><PathFigure StartPoint="0,0"><BezierSegment Point1="210,0" Point2="50,200" Point3 ="300,200"/></PathFigure></PathGeometry><PathGeometry><PathFigure StartPoint="0,0"><BezierSegment Point1="190,0" Point2="50,200" Point3 ="300,200"/></PathFigure></PathGeometry><PathGeometry><PathFigure StartPoint="0,0"><BezierSegment Point1="170,0" Point2="50,200" Point3 ="300,200"/></PathFigure></PathGeometry><PathGeometry><PathFigure StartPoint="0,0"><BezierSegment Point1="150,0" Point2="50,200" Point3 ="300,200"/></PathFigure></PathGeometry><PathGeometry><PathFigure StartPoint="0,0"><BezierSegment Point1="130,0" Point2="50,200" Point3 ="300,200"/></PathFigure></PathGeometry></GeometryGroup></Path.Data>
</Path>

其中大部分代码都是一样的,只不过我们改变了 Point1的值而已 . . .
他们都放在了 GeometryGroup 之中 . . .

效果如下:

在这里插入图片描述


.

路径标记语法的使用

Path非常的强大,但有一个大缺点,我们在上面的例子中就可以看出来,随便画出一个图形就要那么多的代码,这使程序变得繁琐起来,一个标签占一行 . . .

这个时候我们的 Path之中的 路径标记语法 就登上场了 . . .

.
常用路径标记语法的总结:

在这里插入图片描述在这里插入图片描述

这里说明一下 平滑三次 / 二次贝塞尔曲线,其实本身意义并不是太大,但是和一般的贝塞尔曲线还是有那么一点小差别的 . . . 相关可查阅文档 . . .

我们用路径标记语法来完成一下上面那种复杂的例子:

<Path Stroke="Black" Fill="LightBlue"Data="m 0,0 c 250,0 50,200 300,200 z c 230,0 50,200 300,200 z c 210,0 50,200 300,200 zc 190,0 50,200 300,200 zc 170,0 50,200 300,200 zc 150,0 50,200 300,200 zc 130,0 50,200 300,200 z"/>

这个差别是不是非常大呢? 熟练掌握这种方式,可以减少程序的复杂度,^ _ ^

效果如下:

在这里插入图片描述


.

使用 Path 剪裁界面元素

我们可以通过 Clip属性来进行剪裁,这个属性在 UIElement中 . . .

  1. 首先我们准备一组 Path的Data数据:
<Path x:Name="clipPath" Data="M207.8,247.6 C156.69189,236.24264 128.85058,228.91323 95.8,187.6 80.151239,168.0390572.633042,166.98724 67.8,139.6 62.427492,109.15579 43.298718,63.814835 90.466667,43.6 121.60677,30.254242 138.46312,26.266667 174.46667,26.266667 206.23818,26.266667 230.46667,17.612716 230.46667,75.6 231.35556,75.6 232.24444,75.6 233.13333,75.6 240.66455,30.412715 252.51955,30.266667 313.13333,30.266667 354.02313,30.266667 351.94642,54.325233&#xD;&#xA;385.13333,67.6 390.86143,79.056186 397.1166,91.955214 399.8,106.26667 402.2953,119.57492 401.53487,135.63777 398.46667,148.93333 390.18711,184.81142 378.03164,189.46102 341.13333,211.6 300.05452,236.24729 252.36196,230.04529 207.8,247.6 z"/>

这组数据是什么呢? 下面我们就知道了...

  1. 准备一个 Button,当我们点击时,开始剪裁:
<Button Margin="-100, -50, 0, 0" Content="Click Me" Width="120" Height="30"Click="Button_Click"/>
  1. 设置窗体的两个属性:
AllowsTransparency="True" 
WindowStyle="None"

可以透明,窗体风格为空 . . .

  1. 设置事件处理器,设置Clip的值:
private void Button_Click(object sender, RoutedEventArgs e)
{this.Clip = this.clipPath.Data;
}
  1. 效果动态图如下:

在这里插入图片描述

我们发现Data数据表示的是一个 爱心,虽然这有点丑 . . .

这组数据是我从 Blend中画出来的 ^ - ^ . . .

.


作者:浪子花梦


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部