WPF之⼏何图形Geometry
在WPF的DrawingContext对象中,提供了基本的绘制椭圆和矩形的API:DrawEllipse和DrawRectangle。但是,这些是远远不够⽤的,我们在⽇常应⽤中,更多的是使⽤DrawGeometry函数,它可以绘制更多复杂的⼏何图形,并且提供了许多强⼤⽽易⽤的函数,在⼤多数场景下,甚⾄可以取代DrawEllipse和DrawRectangle函数。
在WPF图形体系中,Geometry类表⽰⼏何图形的基类,使⽤的时候是实例化它的⼀些⼦类,具体的有:
基本⼏何图形
线段:
矩形:
椭圆:
⼏何图形集合
路径集合图形⾥可以包含⼀系列⼏何图形集合,常见的有:
线段:
弧:
贝塞尔曲线:贝塞尔曲线系列还⽐较多,具体有如下⼏种:
1. :在两个点之间创建⼀条三次⽅贝塞尔曲线。
2. :创建⼀系列三次⽅贝塞尔曲线。
3. :创建⼀系列⼆次贝塞尔曲线。
4. :创建⼀条⼆次贝塞尔曲线。
除了这种组合的⽅式之外,系统还提供了⼀个通过⼀系列API来绘制的。它不⽀持绑定,动画,相应也更加灵活⽽⾼效。
StreamGeometry geometry = new StreamGeometry;
using (StreamGeometryContext ctx = geometry.Open())
{
ctx.BeginFigure(new Point(10, 100), true , true);
ctx.LineTo(new Point(100, 100), true , false);
ctx.LineTo(new Point(100, 50), true, false);
}
复合⼏何图形使⽤ 、 或者通过调⽤静态的 ⽅法 ,可以创建复合⼏何图形对象。它们主要的区别是: 对⼦图形进⾏叠加操作,没有⾯积的⼦图形将被丢弃。只能组合两个⼦图形(但是这两个⼦图形也可以是复合⼏何图形)。
只进⾏组合,⽽不进⾏⾯积叠加。可以添加多个⼦图形。有关⽰例,请参见 。的叠加⽅式有四种:、、 和 ,它们的效果为:
这些在我们的⽇常应⽤中是⾮常有⽤的,具体⽰例请参看MSDN⽂章: 和。
常⽤⽅法Geometry对象中本⾝还包含了⼀系列⾮常有⽤的⽅法,如: - 获取 的⾯积。 - 确定是否包含其他 。 - 确定是否包含指定的点。
Bounds:获取外接矩形
这些都是⾮常常⽤的⽅法,例如FillContains,StrokeContains⽤于⿏标命中测试是⾮常⽅便的。
呈现⽅式
Geometry对象并不能作为图像独⽴呈现出来,它⼀般有如下⼏种呈现⽅式:
在Path中呈现:
可以作为GeometryDrawing.Geometry的参数呈现为Path对象
<Path Stroke="Black" StrokeThickness="1" >
<Path.Data>
<LineGeometry StartPoint="10,20" EndPoint="100,130" />
</Path.Data>
</Path>
这种⽅式下写⼀些简单的⼏何图形还⾏,但对于PathGeometry来说有些冗繁,因此XAML采⽤了⼀种简单的来简化这⼀过程,
<Path Stroke="Black" Fill="Gray">
<Path.Data>
<PathGeometry Figures="M 10,100 C 10,300 300,-200 300,100" />
</Path.Data>
</Path>
甚⾄可以直接简化为:
<Path Stroke="Black" Fill="Gray" Data="M 10,100 C 10,300 300,-200 300,100" />
这种语法在⼀些第三⽅⽮量图转换过来的⽂件中⾮常常见,如果能熟练掌握的话,写⼀些简单的⼏何图形也是⾮常⽅便的。
在DrawingContext中呈现
可以作为DrawingContext. DrawGeometry的参数呈现,这种⽅式后⾯的⽂章中做会更多的说明,这⾥就不多介绍了。
在GeometryDrawing中呈现
可以作为GeometryDrawing.Geometry的参数呈现为Drawing对象
<GeometryDrawing Brush="MediumBlue">
<GeometryDrawing.Geometry>
<GeometryGroup>
<EllipseGeometry RadiusX="20" RadiusY="45" Center="50,50" />
<EllipseGeometry RadiusX="45" RadiusY="20" Center="50,50" />
</GeometryGroup>
</GeometryDrawing.Geometry>
</GeometryDrawing>
当然,Drawing对象也不能独⽴呈现,⼀般是作为DrawingBrush或作为DrawingContext.DrawDrawing的参数来使⽤的
其它⽤途:
作为UIElement.Clip参数裁剪控件
<Image Source="sampleImages\Waterlilies.jpg" Width="200" Height="150" HorizontalAlignment="Left">
<Image.Clip>
<EllipseGeometry RadiusX="100" RadiusY="75" Center="100,75"/>
</Image.Clip>
</Image>
另外,也常⽤在DrawingGroup.ClipGeometry和DrawingContext.PushClip中裁剪图像。
作为DoubleAnimationUsingPath. PathGeometry属性⽣成路径动画
可以将 对象定义的⼏何路径旋转(转动)对象的路径。
PathGeometry⽤法
WPF提供两个类来描述路径数据:⼀个是StreamGeometry,另⼀个是PathFigureCollection。
类似:<Path Stroke="Black" Data="M 100,240 C 510,300 80,100 300,160 H40 v80" />的形式是StreamGeometry的XAML代码表⽰形式,也是最简洁的表⽰形式。
⽽类似:
<Path Stroke="Black" StrokeThickness="1" Fill="#CCCCFF">
<Path.Data>
<PathGeometry Figures="M 10,100 C 10,300 300,-160 300,100" />
</Path.Data>
</Path>
这样的⽅式是使⽤PathFigureCollection的XAML代码表⽰⽅式。
这两种⽅式都可以达⾄同⼀种显⽰效果,那么,什么时候使⽤StreamGeometry,什么时候使⽤PathFigureCollection⽅式呢?
⼀般地,当你建⽴路径后,不再需要修改时,可使⽤StreamGeometry⽅式,如果还需要对路径数值进⾏修改,则使⽤PathFigureCollection⽅式(这⾥就是PathGeometry)。
Data属性的表⽰语法:
(1)StreamGeometry⽅式: [填充规则] 外形描述[外形描述]*
(2)PathFigureCollection⽅式: 外形描述[外形描述]*
注:
(1)上⾯语法中,[...]表⽰可选,*代表任意个。
(2)“填充规则”中,有EvenOdd和Nonzero两种。XAML中为了简洁,使⽤“F0”表⽰EvenOdd,“F1”表⽰Nonzero。
(3)“外形描述”的语法:moveCommand drawCommands [closeCommand]
其中:移动指令(moveCommand),绘制指令(drawCommands),关闭指令(closeCommand)。
(4)moveCommand指定起始点,使⽤⼀个drawingCommand描述外形轮廓的内容描述,closeCommand⽤来关闭路径。
如下图:
(图2)
下⾯来解释⼀下“M 100,240 C510,300 80,100 300,160 H40 v80”这样字符串的意义。
分为四种情况来解释:
1. 移动指令:Move Command(M):M 起始点 或者:m 起始点
⽐如:M 100,240或m 100,240
使⽤⼤写M时,表⽰绝对值; 使⽤⼩写m时; 表⽰相对于前⼀点的值,如果前⼀点没有指定,则使⽤(0,0)。
2. 绘制指令(Draw Command):
我们可以绘制以下形状:
(1) 直线:Line(L)
(2) ⽔平直线: Horizontal line(H)
(3) 垂直直线: Vertical line(V)
(4) 三次⽅程式贝塞尔曲线: Cubic Bezier curve(C)
(5) ⼆次⽅程式贝塞尔曲线: Quadratic Bezier curve(Q)
(6) 平滑三次⽅程式贝塞尔曲线: Smooth cubic Bezier curve(S)
(7) 平滑⼆次⽅程式贝塞尔曲线: smooth quadratic Bezier curve(T)
(8) 椭圆圆弧: elliptical Arc(A)
上⾯每种形状后⽤括号括起的英⽂字母为命令简写的⼤写形式,但你也可以使⽤⼩写。使⽤⼤写与⼩写的区别是:⼤写是绝对值,⼩写是相对值。
⽐如:L 100, 200 L 300,400表⽰从绝对坐标点(100,200)到另⼀绝对坐标点(300,400)的⼀条直线。⽽l 100, 200 l 300,400则表⽰相对上⼀点(如果未指定,则默认为(0,0)坐标点)开始计算的坐标点(100,200)到坐标点为(300,400)的⼀条直线。
当我们重复使⽤同⼀种类型时,就可以省略前⾯的命令。⽐如:L 100, 200 L 300,400简写为:L 100, 200 300,400。
下图是以下XAML代码的绘制效果(为了⽅便你⽐较,我加了背景格⼦,每⼩格为10像素):
XAML(代码B):
<Path Stroke="Black" StrokeThickness="1" Data="M 10,100 L 100,100 100,50 Z M 10,10 100,10 100,40 Z" />
(图3)svg图形
细⼼的读者可能会发现,有点怪怪的感觉,因为我故意将下⾯的三⾓形的代码放在前⾯了,这样,似乎不太符合习惯。事实上,上⾯的代码与这个结果完全⼀样:
<Path Stroke="Black" StrokeThickness="1" Data="M 10,10 100,10 100,40 Z M 10,100 L 100,100 100,
50 Z" />
这⾥有⼀个你暂时还没见过的Z指令,它就是⼀个关闭指令(close Command),表⽰封闭指定形状,即将⾸尾点连接起来形成封闭的区域。
绘制指令格式语法:
(1) 直线:Line(L)
格式:L 结束点坐标 或: l 结束点坐标。
⽐如:L 100,100 或 l 100 100。坐标值可以使⽤x,y(中间⽤英⽂逗号隔开)或x y(中间⽤半⾓空格隔开)的形式。
(2) ⽔平直线 Horizontal line(H):绘制从当前点到指定x坐标的直线。
格式:H x值 或 h x值(x为System.Double类型的值)
⽐如:H 100或h 100,也可以是:H 100.00或h 100.00等形式。
(3) 垂直直线 Vertical line(V):绘制从当前点到指定y坐标的直线。
格式:V y值 或 v y值(y为System.Double类型的值)
⽐如:V 100或y 100,也可以是:V 100.00或v 100.00等形式。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论