WPFのCombinedGeometryを使って複数の図形を演算する
WPFではベクターグラフィックスが利用できて、便利です。RectangleやEllipseのような簡単な図形はいいですが、ちょっと凝った図形はPathで作ります。今回は左図の“マルi”マークのような演算を含むマークを描いてみます。
Pathの場合、ジオメトリと呼ばれる直線や曲線のデータを集めたものをPath.Dataに設定することで、図形を画面に描画します。Geometry自体は画面に線や塗りを描画することはできません。
PathとGeometryの詳細はMSDNを参照してください。
WPF での図形と基本描画の概要 パスとジオメトリの使用 – MSDN
作っていく方針としては、“●(丸)”から“i”の字を抜けばいいわけです。単純に“●(丸)”に背景色と同じ色の“i”の字を重ねてもよさそうですが、背景が図形の場合など、“i”の字を透過したい場合はやはりくり抜きたいのです。
CombinedGeometryでジオメトリを演算
そこで登場するのがCombinedGeometryクラスです。
このようにCombinedGeometryクラスを使うと2つの図形の間で結合したり、差し引いたりして複雑な図形を表現することができます。そのモードはUnion(結合)、Intersect(交差)、Exclude(除外、型抜き)、Xor(排他的論理和、中マド)から選べます。ちなみに単純な結合の場合はGeometryGroupクラスを用いたほうが処理が速く、複数の(3つ以上の)図形でもOKなので便利です。
作り方
“i”を作る
ここでは“i”の字は丸と角丸四角形の組み合わせで作ります。まずこれをGeometryGroupで作ります。
1 2 3 4 |
<GeometryGroup> <RectangleGeometry RadiusX="2" RadiusY="2" Rect="8,9,4,8" /> <EllipseGeometry RadiusX="2" RadiusY="2" Center="10,5.5" /> </GeometryGroup> |
RectangleGeometryは四角形のGeometryです。RadiusXとRadiusYに指定すると角丸にもできます。めっちゃべんり。Rectプロパティの中は “X座標,Y座標,幅,高さ” です。
EllipseGeometryは楕円のGeometryです。Centerプロパティで中心座標を指定して、RadiusXとRadiusYで半径を指定します。RadiusX=RadiusYなら正円になります。
“i”で“●”を型抜き
次にCombinedGeometryで“●(丸)”から今作った“i”を型抜きします。
1 2 3 4 5 6 7 8 9 10 11 |
<CombinedGeometry GeometryCombineMode="Exclude"> <CombinedGeometry.Geometry1> <EllipseGeometry RadiusX="10" RadiusY="10" Center="10,10" /> </CombinedGeometry.Geometry1> <CombinedGeometry.Geometry2> <GeometryGroup> <RectangleGeometry RadiusX="2" RadiusY="2" Rect="8,9,4,8" /> <EllipseGeometry RadiusX="2" RadiusY="2" Center="10,5.5" /> </GeometryGroup> </CombinedGeometry.Geometry2> </CombinedGeometry> |
このようにCombinedGeometryのGeometryCombineModeプロパティにExcludeを設定して、Geometry1にベースとなるジオメトリ、Geometry2に演算するジオメトリを設定します。一番上の例で言えば、青の円がGeometry1、黄色い四角がGeometry2です。
ちなみに今回の場合、Geometry2がGeometry1の内側に完全に入っているので、モードはExcludeでもXorでもかまいません。なお、Adobe IllustratorのパスファインダーではXorは中マド、Excludeは型抜き、と呼ばれています。
パスに設定して画面に表示
この作成したジオメトリを画面に表示するため、CombinedGeometryをPath.Dataに設定してやりましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<Path Name="infoIcon" Stroke="Transparent" StrokeThickness="1" Fill="White" Margin="8"> <Path.Data> <CombinedGeometry GeometryCombineMode="Xor"> <CombinedGeometry.Geometry1> <EllipseGeometry RadiusX="10" RadiusY="10" Center="10,10" /> </CombinedGeometry.Geometry1> <CombinedGeometry.Geometry2> <GeometryGroup> <RectangleGeometry RadiusX="2" RadiusY="2" Rect="8,9,4,8" /> <EllipseGeometry RadiusX="2" RadiusY="2" Center="10,5.5" /> </GeometryGroup> </CombinedGeometry.Geometry2> </CombinedGeometry> </Path.Data> <Path.Effect> <DropShadowEffect BlurRadius="5" Direction="315" Opacity="0.8" ShadowDepth="2" Color="Black"/> </Path.Effect> </Path> |
Path.Effectはわかりやすいようにつけた影のエフェクトです。これでこんな感じになるはずです。
最後までお読みいただきありがとうございました m(_ _)m