Path と Geometry

Geometry は形状の情報のみを持ち,PathはGeometryの他に,Stroke, Fill プロパティ やイベントを持つ。
Path の Dataプロパティに Geometry を指定することにより,Pathは一人前のコントロールになる。

Geometryの種類
 LineGeometry これらは,ShapeのLine, Rectangle, Ellipse と同様の形状を表す。
ただし,Shapeは,Pathと同様に,Stroke, Fill, Margin などの
プロパティを持つが,Geometryは形状の情報を持つだけである。   
 RectangleGeometry
 EllipseGeometry
 GeometryGroup 複数の Geometry を合わせた Geometry を与える。
 CombinedGeometry 2つの Geometry を演算して,新しい Geometry を与える。
 PathGeometry 複数の任意図形(PathFigure)で Geometry を与える。
 StreamGeomerty ミニ言語を使用して Geometry を与える。

Line/Rectangle/EllipseGeometry

Line/Rectangle/EllipseGeometry と Shape の比較
 Line  Shape
<Line Stroke="Red" X1="0" Y1="0" X2="200" Y2="100"></Line>
 Geometry
<Path Stroke="Red">
    <Path.Data>
        <LineGeometry StartPoint="0,0" EndPoint="200,100"></LineGeometry>
</Path.Data> </Path>
 Rectangle   Shape
<Rectangle Stroke="Red" Fill="Beige" Width="200"
      Height="100" ></Rectangle>
 Geometry
<Path Stroke="Red" Fill="Beige">
    <Path.Data>
        <RectangleGeometry Rect="0,0,200,100"></RectangleGeometry>
    </Path.Data>
</Path>
 Ellipse   Shape
<Ellipse Stroke="Red" Fill="Beige" Width="200" Height="100" ></Ellipse>
 Geometry
・・・
        <EllipseGeometry RadiusX="100" RadiusY="50" Center="100,50"></EllipseGeometry>
・・・

これら3つのGeomertyは,単独ならShapeを使えばよいが,以下のように組み合わせて使う場合に意味がある。


GeometryGroup

<Path Stroke="Orange" Fill="Beige" Margin="10">
    <Path.Data>
        <GeometryGroup>
            <RectangleGeometry Rect="0,0,200,100"></RectangleGeometry>
            <EllipseGeometry RadiusX="50" RadiusY="30" Center="100,50"></EllipseGeometry>
        </GeometryGroup>
    </Path.Data>
</Path>

GeometryGroup の既定の FillRuleプロパティは EvenOdd であり,楕円の内部は透明である。
<GeometryGroup FillRule="Nonzero"> とすると,下図右のようになる。

GeometryGroup は,任意の個数のGeometryをグループ化することができる。

GeometryGroupの作成をコード(C#)で行うには,以下のように書く。

GeometryGroup gg = new GeometryGroup();
gg.Children.Add(
    new EllipseGeometry(new Point(100, 50), 50, 30)
);

GeometryGroupを Windows.Resources に登録しておき,Path.Data でその名前を指定するすることにより,任意の場所で何度でも使用することもできる。

<Window ・・ >
    <Window.Resources>
        <GeometryGroup x:Key="Geometry1">・・</GeometryGroup>
    </Window.Resources>
    ・・・
        <Canvas>
            <Path Stroke="Blue" ・・ Data="{StaticResource Geometry1}"></Path>
        </Canvas>         

CombinedGeometry

CombinedGeometry は,2つのGeometry (Geometry1Geometry2 プロパティ)に対して,以下のいずれかの演算を行ったGeometryを与える。

GeometryCombineMode
 Union  2つのGeometryの和 (G1 OR G2)
 Intersect  2つのGeometryの共通部分 (G1 AND G2)
 Xor  2つのGeometryのXOR (G1 XOR G2)
 Exclude  2つのGeometryの差 (G1 - G2)
<Path Stroke="Orange" Fill="Beige" Margin="10">
    <Path.Data>
        <CombinedGeometry GeometryCombineMode="Union">
            <CombinedGeometry.Geometry1>
                <RectangleGeometry Rect="0,0,50,50"/>
            </CombinedGeometry.Geometry1>
            <CombinedGeometry.Geometry2>
                <EllipseGeometry RadiusX="25" RadiusY="25" Center="50,25"></EllipseGeometry>
            </CombinedGeometry.Geometry2>
        </CombinedGeometry>
    </Path.Data>
</Path>

3つ以上のGeometryを結合するには,Geometry1 に CombinedGeometry を指定するといった形にすればよい。


PathGeometry

PathGeometry は,任意の数の多角形,折れ線,閉曲線,開曲線の集まりで定義される。
この中の1つである非連結な図形を PathFigure といい,PathGeometry は PathFigure の集合で定義される。

上記すべてのGeomertyは,PathGeometryで表すこともできるので,PathGeometry が最も汎用性がある。

PathFigure は,始点とセグメントから定義され,次の4つの必須プロパティがある。

PathFigure の必須プロパティ
 StartPoint  始点を示す。StartPoint="10, 50"
 Segments  一般には複数のPathSegment (LineSegment, ArcSegment など)のコレクション。
 IsClosed  true なら,最後のPathSegment の点と StartPoint を結ぶSegmentが追加される。
 IsFilled  true なら,Path の Fill ブラシで塗りつぶされる。

PathSegmentを連続した場合,直前に指定された点が次の始点となる。
新しいPathFigureを追加すると,前のPathFigureとは非連結な図形を指定することになり,これは新しいStartPointから始まる。
PathSegment の種類
 LineSegment  終点(Point)を指定した直線。IsStrokedプロパティで線を引くか否かを指定できる。
 ArcSegment  終点(Point)と楕円のSize(Xradius, Yradius) を与えた楕円の弧
 BezierSegmnet,
 QuadraticBezierSegmnet
 Bezier曲線。始点の制御点,終点の制御点,終点の3点を与える。
 Quadratic(2次式)の方は,制御点と終点の2点を与える。
 PolyLineSegment,
 PolyBezierSegmnet,
 PolyQuadraticBezierSegmnet
 連続したLineSegment, BezierSegmnet などを,よりコンパクトに表現する。

LineSegment

以下は,(50, 0), (0, 100), (100, 100) の3点からなる二等辺三角形を描く例である。(ただし,Margin は 10)

<Path Stroke="Orange" Fill="Beige" Margin="10">
    <Path.Data>
        <PathGeometry>
            <PathFigure IsClosed="True" StartPoint="50,0">
                <LineSegment Point="0,100" />
                <LineSegment Point="100,100" />
            </PathFigure>
        </PathGeometry>
    </Path.Data>
</Path>

ArcSegment

始点(PathFigure.StartPoint),終点(ArcGeometry.Point) と 楕円のサイズ Size=(Xradius, Yradius) を与えても,一般には右図のように4つの弧がある。
これらのうちいずれであるかを指定するために,ArcSegmentには以下の2つのプロパティがある。

 IsLargeArc  True または False(既定)
 SweepDirection  Counterclockwise(既定) または Clockwise

    

以下は,半径50 の円の左上4分の1の部分を表すPathGeometryである。

<PathGeometry>
    <PathFigure StartPoint="0,100">
        <ArcSegment Point="100,0" Size="100,100" SweepDirection="Clockwise"></ArcSegment>
    </PathFigure>
</PathGeometry>

BezierSegment

2点間にベジェ曲線を引くには,始点,終点の他に始点用,終点用の制御点が必要で,合計4つの点を指定することになる。

BezierSegment のプロパティ Point1には始点用の制御点,Point2には終点用の制御点,Point3には終点を指定する。

<PathGeometry>
    <PathFigure StartPoint="0,0">
        <BezierSegment Point1="0,50" Point2="150,50" Point3="100,100"></BezierSegment>
    </PathFigure>
</PathGeometry>

実際には,このようなコードを書いて使用することは滅多にないだろう。

なお,ベジェ曲線は通常3次式のパラメータ表示で与えられるが,QuadraticBezierSegmnet は2次式を使うもので,
制御点と終点を Point1, Point2 を指定する。この制御点は,始点と終点の傾きを指定することになる。


StreamGeometry

PathGeometry による Path は,ミニ言語を使って簡単に書ける。

例えば,上のLineSegmentを使った10行の例は次の1行になる。

<Path Stroke="Orange" Fill="Beige" Margin="10" Data="M 50,0 L 0,100 L 100,100 Z" />

スペースやカンマを省略して,Data="M50 0 L0 100 L100 100 Z" と書くこともできる。

このように,ミニ言語で作ったGeometryが StreamGeometry であり,これを直接 Path.Data に与えることができる。

Geometry Mini-Language
 コマンド  意味
 F 0 or 1  FillRule プロパティ。書く場合は先頭に書く。0 は EvenOdd, 1 は NonZero の意。
 M x,y  新しいPathFigureを作り,StartPointを(x,y)にする。(M は Move の意)
 L x,y  点(x,y)へのLineSegment
 H x,  x までの水平線(横線)
 V y  y までの垂直線(縦線)
 A rX, rY, degree, IsLargeArc, Clockwise, x,y  点(x,y)へのArcSegment。楕円のサイズ,楕円の回転角,0 または1,0 または1
 C x1,y1,x2,y2,x,y  点(x,y)へのBezierSegmnet。
 Q x1,y1,x,y  点(x,y)へのQuadraticBezierSegmnet。
 S x2,y2,x,y  点(x,y)への滑らかな(smooth) BezierSegmnet。始点は,直前のベジェ曲線の終点が使われる。したがって,前のセグメントは C または S でなくてはならない。
 Z  PathFigureを終了し,IsClosedをTrueにする。
(閉じないで次のPathFigureを作るときは,Zなしで,M から書けばよい。)

※コマンドを小文字で書くと,座標値は絶対値ではなく,相対値になる。 (例) h 100 → 始点から右へ100移動した点へのLineSegment

(参考)Path.Data ではなく,PathGeometry.Figures をミニ言語で書くこともできる。

Geometryをコードで書く方法はこちら


Clip プロパティ

さまざまな要素の Clip プロパティに Geometry を指定すると,その要素の外枠がGeometryの形状になる。