ジオメトリの概要
更新 : 2007 年 11 月
ここでは、Windows Presentation Foundation (WPF) の Geometry クラスを使用して図形を記述する方法を説明します。また、Geometry オブジェクトと Shape 要素の違いも示します。
このトピックには次のセクションが含まれています。
- ジオメトリとは
- ジオメトリと図形
- ジオメトリを使用する一般的なプロパティ
- 単純なジオメトリの種類
- パス ジオメトリ
- 複合ジオメトリ
- 結合したジオメトリ
- Freezable の機能
- その他のジオメトリ機能
- 関連トピック
ジオメトリとは
Geometry クラス、および EllipseGeometry、PathGeometry、CombinedGeometry などの派生クラスを使用すると、2-D 図形のジオメトリを記述できます。これらの幾何学的な記述には、画面を塗りつぶす図形を定義したり、ヒット テストやクリップ領域を定義するなど、多くの用途があります。ジオメトリを使用して、アニメーション パスを定義することもできます。
Geometry オブジェクトは、四角形や円などの単純なものにすることも、2 つ以上のジオメトリ オブジェクトから作成された複合的なものにすることもできます。PathGeometry クラスや StreamGeometry クラスなど、円弧や曲線を記述できるクラスを使用すると、さらに複雑なジオメトリを作成することができます。
Geometry は Freezable オブジェクトの一種であるため、Geometry オブジェクトにはいくつかの特殊な機能があります。具体的には、リソースとしての宣言、複数オブジェクトでの共有、読み取り専用に設定することによるパフォーマンスの向上、複製、スレッド セーフの設定などです。Freezable オブジェクトのさまざまな機能の詳細については、「Freezable オブジェクトの概要」を参照してください。
ジオメトリと図形
Geometry クラスと Shape クラスは、両方とも 2-D 図形を記述するという点で似ていますが (EllipseGeometry と Ellipse を比較した場合など)、重要な違いがあります。
その 1 つは、Geometry クラスが Freezable クラスを継承するのに対し、Shape クラスは FrameworkElement を継承するという点です。これらは要素であるため、Shape オブジェクトは自身をレンダリングしたり、レイアウト システムに参加することができますが、Geometry オブジェクトはそのような動作を実行できません。
Shape オブジェクトは、Geometry オブジェクトよりも簡単に使用できますが、Geometry オブジェクトは、より幅広い用途で使用できます。Shape オブジェクトは、2-D グラフィックスのレンダリングに使用されますが、Geometry オブジェクトは、2-D グラフィックスの幾何学領域を定義したり、クリップ用の領域を定義したり、ヒット テスト用の領域を定義するなどに使用されます。
パス図形
Shape の 1 つである Path クラスは、実際には Geometry を使用してそのコンテンツを記述します。Geometry で Path の Data プロパティを設定し、その Fill プロパティと Stroke プロパティを設定することにより、Geometry をレンダリングできます。
ジオメトリを使用する一般的なプロパティ
前のセクションでは、ジオメトリ オブジェクトを他のオブジェクトと共にさまざまな目的で (図形の描画、アニメーション、クリッピングなど) 使用できることを説明しました。Geometry オブジェクトを使用するプロパティを持ついくつかのクラスを次の表に示します。
型 |
プロパティ |
---|---|
単純なジオメトリの種類
すべてのジオメトリの基本クラスは、抽象クラス Geometry です。Geometry クラスの派生クラスは大きく 3 つのカテゴリに分類されます。単純なジオメトリ、パス ジオメトリ、および複合ジオメトリです。
単純なジオメトリ クラスには、LineGeometry、RectangleGeometry、および EllipseGeometry があり、線、四角形、円などの基本的な幾何学図形を作成するために使用されます。
LineGeometry は、行の始点と終点を指定して定義します。
RectangleGeometry は、その相対位置、および高さと幅を指定する Rect 構造体を使用して定義されます。RadiusX プロパティと RadiusY プロパティを設定して、丸みのある四角形を作成できます。
EllipseGeometry は、中心点、x 半径、および y 半径で定義されます。レンダリングおよびクリッピング用の単純なジオメトリの作成方法を次の例に示します。
PathGeometry を使用するか、ジオメトリ オブジェクトを結合する方法でも、これらと同じ図形や、さらに複雑な図形を作成することができます。ただし、これらのクラスを使用すると、このような基本的な幾何学図形を簡単に生成できます。
LineGeometry オブジェクトを作成してレンダリングする方法の例を次に示します。前に述べたように、Geometry オブジェクトは自身を描画できないため、この例では Path 図形を使用して線をレンダリングします。線には領域がないため、Path の Fill プロパティを設定しても無効です。代わりに、Stroke プロパティと StrokeThickness プロパティだけを指定します。この例からの出力を次の図に示します。
(10,20) から (100,130) まで描画された LineGeometry
<Path Stroke="Black" StrokeThickness="1" >
<Path.Data>
<LineGeometry StartPoint="10,20" EndPoint="100,130" />
</Path.Data>
</Path>
LineGeometry myLineGeometry = new LineGeometry();
myLineGeometry.StartPoint = new Point(10,20);
myLineGeometry.EndPoint = new Point(100,130);
Path myPath = new Path();
myPath.Stroke = Brushes.Black;
myPath.StrokeThickness = 1;
myPath.Data = myLineGeometry;
次の例は、EllipseGeometry を作成してレンダリングする方法を示しています。この例では、EllipseGeometry の Center を点 50,50 に設定し、x 半径と y 半径を両方とも 50 に設定して、直径が 100 の円を作成します。楕円の内部は、値 (この例では Gold) を Path 要素の Fill プロパティに割り当てることによって塗りつぶします。この例からの出力を次の図に示します。
(50,50) に描画された EllipseGeometry
<Path Fill="Gold" Stroke="Black" StrokeThickness="1">
<Path.Data>
<EllipseGeometry Center="50,50" RadiusX="50" RadiusY="50" />
</Path.Data>
</Path>
EllipseGeometry myEllipseGeometry = new EllipseGeometry();
myEllipseGeometry.Center = new Point(50, 50);
myEllipseGeometry.RadiusX = 50;
myEllipseGeometry.RadiusY = 50;
Path myPath = new Path();
myPath.Fill = Brushes.Gold;
myPath.Stroke = Brushes.Black;
myPath.StrokeThickness = 1;
myPath.Data = myEllipseGeometry;
RectangleGeometry オブジェクトを作成してレンダリングする方法の例を次に示します。四角形の位置およびサイズは、Rect 構造体によって定義されます。位置は 50,50、高さと幅は両方とも 25 で、正方形が作成されます。この例からの出力を次の図に示します。
50,50 に描画された RectangleGeometry
<Path Fill="LemonChiffon" Stroke="Black" StrokeThickness="1">
<Path.Data>
<RectangleGeometry Rect="50,50,25,25" />
</Path.Data>
</Path>
RectangleGeometry myRectangleGeometry = new RectangleGeometry();
myRectangleGeometry.Rect = new Rect(50,50,25,25);
Path myPath = new Path();
myPath.Fill = Brushes.LemonChiffon;
myPath.Stroke = Brushes.Black;
myPath.StrokeThickness = 1;
myPath.Data = myRectangleGeometry;
EllipseGeometry をイメージのクリップ領域として使用する方法を次の例に示します。Image オブジェクトは、Width を 200、Height を 150 として定義されます。RadiusX 値が 100、RadiusY 値が 75、および Center 値が 100,75 に指定された EllipseGeometry が、イメージの Clip プロパティに設定されます。イメージの楕円の領域内の部分だけが表示されます。この例からの出力を次の図に示します。
イメージ コントロールのクリップに使用される EllipseGeometry
<Image
Source="sampleImages\Waterlilies.jpg"
Width="200" Height="150" HorizontalAlignment="Left">
<Image.Clip>
<EllipseGeometry
RadiusX="100"
RadiusY="75"
Center="100,75"/>
</Image.Clip>
</Image>
// Create the image to clip.
Image myImage = new Image();
Uri imageUri =
new Uri(@"C:\\Documents and Settings\\All Users\\Documents\My Pictures\\Sample Pictures\\Water lilies.jpg", UriKind.Relative);
myImage.Source = new BitmapImage(imageUri);
myImage.Width = 200;
myImage.Height = 150;
myImage.HorizontalAlignment = HorizontalAlignment.Left;
// Use an EllipseGeometry to define the clip region.
EllipseGeometry myEllipseGeometry = new EllipseGeometry();
myEllipseGeometry.Center = new Point(100, 75);
myEllipseGeometry.RadiusX = 100;
myEllipseGeometry.RadiusY = 75;
myImage.Clip = myEllipseGeometry;
パス ジオメトリ
PathGeometry クラスとその軽量等価クラスの StreamGeometry を使用すると、円弧、曲線、および線で構成される複数の複雑な図形を記述できます。
PathGeometry の中核は、PathFigure オブジェクトのコレクションです。各図形が PathGeometry の個々の図形を記述しているため、この名前が付いています。各 PathFigure 自体は 1 つ以上の PathSegment オブジェクトで構成されており、これらの各オブジェクトは図形のセグメントを記述します。
次のように、多くの種類のセグメントがあります。
セグメントの種類 |
説明 |
例 |
---|---|---|
2 つの点の間の楕円の円弧を作成します。 |
||
2 つの点の間の 3 次ベジエ曲線を作成します。 |
||
2 つの点の間の直線を作成します。 |
||
一連の 3 次ベジエ曲線を作成します。 |
PolyBezierSegment の種類のページを参照してください。 |
|
一連の直線を作成します。 |
PolyLineSegment の種類のページを参照してください。 |
|
一連の 2 次ベジエ曲線を作成します。 |
PolyQuadraticBezierSegment のページを参照してください。 |
|
2 次ベジエ曲線を作成します。 |
PathFigure 内のセグメントは 1 つの幾何学図形に結合されて、各セグメントの終点が次のセグメントの始点になります。PathFigure の StartPoint プロパティは、最初のセグメントが描画される始点を指定します。後続の各セグメントは、前のセグメントの終点から開始します。たとえば、10,50 から 10,150 までの縦線を定義するには、StartPoint プロパティを 10,50 に設定し、Point プロパティを 10,150 に設定した LineSegment を作成します。
LineSegment を使用して、単一の PathFigure で構成される単純な PathGeometry を作成し、Path 要素を使用してそれを表示する例を次に示します。PathFigure オブジェクトの StartPoint は 10,20 に設定され、LineSegment の終点は 100,130 で定義されます。この例で作成した PathGeometry を次の図に示します。
単一の LineSegment を含む PathGeometry
<Path Stroke="Black" StrokeThickness="1">
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigure StartPoint="10,20">
<PathFigure.Segments>
<LineSegment Point="100,130"/>
</PathFigure.Segments>
</PathFigure>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>
// Create a figure that describes a
// line from (10,20) to (100,130).
PathFigure myPathFigure = new PathFigure();
myPathFigure.StartPoint = new Point(10,20);
myPathFigure.Segments.Add(
new LineSegment(new Point(100,130),
true /* IsStroked */ ));
/// Create a PathGeometry to contain the figure.
PathGeometry myPathGeometry = new PathGeometry();
myPathGeometry.Figures.Add(myPathFigure);
// Display the PathGeometry.
Path myPath = new Path();
myPath.Stroke = Brushes.Black;
myPath.StrokeThickness = 1;
myPath.Data = myPathGeometry;
この例と、前の LineGeometry 例を比較してみてください。PathGeometry に使用されている構文は、単純な LineGeometry に使用されている構文よりもかなり詳細です。この例では LineGeometry クラスを使用する方が合理的ですが、PathGeometry の詳細な構文を使用すると、非常に複雑な幾何学領域を作成できます。
より複雑なジオメトリを作成するには、PathSegment オブジェクトを組み合わせて使用します。
次の例では、BezierSegment、LineSegment、および ArcSegment を使用して図形を作成します。この例では、最初に、始点 (前のセグメントの終点)、終点 (Point3)、および 2 つの制御点 (Point1 および Point2) の 4 つの点を定義して 3 次ベジェ曲線を作成します。3 次ベジエ曲線の 2 つの制御点は磁石のような働きをします。本来は直線になる部分を制御点の方へ引き寄せ、曲線を生成します。1 つ目の制御点である Point1 は、曲線の開始部分に影響します。2 つ目の制御点である Point2 は、曲線の終了部分に影響します。
次に、LineSegment を追加します。これは、その前にある BezierSegment の終点からその LineSegment プロパティで指定された点までの間に描画されます。
次に、ArcSegment を追加します。これは、その前の LineSegment の終点からその Point プロパティで指定された点までの間に描画されます。また、円弧の x 半径と y 半径 (Size)、回転角度 (RotationAngle)、結果の円弧の角度の大きさを示すフラグ (IsLargeArc)、および円弧が描画される方向を示す値 (SweepDirection) も指定します。この例で作成した図形を次の図に示します。
PathGeometry
<Path Stroke="Black" StrokeThickness="1" >
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigure StartPoint="10,50">
<PathFigure.Segments>
<BezierSegment
Point1="100,0"
Point2="200,200"
Point3="300,100"/>
<LineSegment Point="400,100" />
<ArcSegment
Size="50,50" RotationAngle="45"
IsLargeArc="True" SweepDirection="Clockwise"
Point="200,100"/>
</PathFigure.Segments>
</PathFigure>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>
// Create a figure.
PathFigure myPathFigure = new PathFigure();
myPathFigure.StartPoint = new Point(10,50);
myPathFigure.Segments.Add(
new BezierSegment(
new Point(100,0),
new Point(200,200),
new Point(300,100),
true /* IsStroked */ ));
myPathFigure.Segments.Add(
new LineSegment(
new Point(400,100),
true /* IsStroked */ ));
myPathFigure.Segments.Add(
new ArcSegment(
new Point(200,100),
new Size(50,50),
45,
true, /* IsLargeArc */
SweepDirection.Clockwise,
true /* IsStroked */ ));
/// Create a PathGeometry to contain the figure.
PathGeometry myPathGeometry = new PathGeometry();
myPathGeometry.Figures.Add(myPathFigure);
// Display the PathGeometry.
Path myPath = new Path();
myPath.Stroke = Brushes.Black;
myPath.StrokeThickness = 1;
myPath.Data = myPathGeometry;
さらに複雑なジオメトリを作成するには、PathGeometry 内で複数の PathFigure オブジェクトを使用します。
2 つの PathFigure オブジェクトを使用して PathGeometry を作成する例を次に示します。各オブジェクトには、複数の PathSegment オブジェクトが含まれます。上記の例の PathFigure と、PolyLineSegment および QuadraticBezierSegment による PathFigure が使用されています。PolyLineSegment は点の配列を使用して定義され、QuadraticBezierSegment は制御点と終点を使用して定義されます。この例で作成した図形を次の図に示します。
複数の図形を使用する PathGeometry
<Path Stroke="Black" StrokeThickness="1" >
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigure StartPoint="10,50">
<PathFigure.Segments>
<BezierSegment
Point1="100,0"
Point2="200,200"
Point3="300,100"/>
<LineSegment Point="400,100" />
<ArcSegment
Size="50,50" RotationAngle="45"
IsLargeArc="True" SweepDirection="Clockwise"
Point="200,100"/>
</PathFigure.Segments>
</PathFigure>
<PathFigure StartPoint="10,100">
<PathFigure.Segments>
<PolyLineSegment Points="50,100 50,150" />
<QuadraticBezierSegment Point1="200,200" Point2="300,100"/>
</PathFigure.Segments>
</PathFigure>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>
PathGeometry myPathGeometry = new PathGeometry();
// Create a figure.
PathFigure pathFigure1 = new PathFigure();
pathFigure1.StartPoint = new Point(10,50);
pathFigure1.Segments.Add(
new BezierSegment(
new Point(100,0),
new Point(200,200),
new Point(300,100),
true /* IsStroked */ ));
pathFigure1.Segments.Add(
new LineSegment(
new Point(400,100),
true /* IsStroked */ ));
pathFigure1.Segments.Add(
new ArcSegment(
new Point(200,100),
new Size(50,50),
45,
true, /* IsLargeArc */
SweepDirection.Clockwise,
true /* IsStroked */ ));
myPathGeometry.Figures.Add(pathFigure1);
// Create another figure.
PathFigure pathFigure2 = new PathFigure();
pathFigure2.StartPoint = new Point(10,100);
Point[] polyLinePointArray =
new Point[]{ new Point(50, 100), new Point(50, 150)};
PolyLineSegment myPolyLineSegment = new PolyLineSegment();
myPolyLineSegment.Points =
new PointCollection(polyLinePointArray);
pathFigure2.Segments.Add(myPolyLineSegment);
pathFigure2.Segments.Add(
new QuadraticBezierSegment(
new Point(200,200),
new Point(300,100),
true /* IsStroked */ ));
myPathGeometry.Figures.Add(pathFigure2);
// Display the PathGeometry.
Path myPath = new Path();
myPath.Stroke = Brushes.Black;
myPath.StrokeThickness = 1;
myPath.Data = myPathGeometry;
StreamGeometry
PathGeometry クラスと同様に、StreamGeometry は、曲線、円弧、および線を含む複雑な幾何学図形を定義することができます。PathGeometry とは異なり、StreamGeometry のコンテンツは、データ バインディング、アニメーション、変更をサポートしません。複雑なジオメトリを作成する必要があるが、データ バインディング、アニメーション、または変更をサポートするためのオーバーヘッドが望ましくない場合は、StreamGeometry を使用します。StreamGeometry クラスは効率的であるため、装飾の表現に適しています。
例については、「方法 : StreamGeometry を使用して図形を作成する」を参照してください。
パス マークアップ構文
PathGeometry と StreamGeometry は、特殊な一連の移動および描画コマンドを使用して Extensible Application Markup Language (XAML) 属性構文をサポートします。詳細については、「パス マークアップ構文」を参照してください。
複合ジオメトリ
複合ジオメトリ オブジェクトは、GeometryGroup または CombinedGeometry を使用するか、Geometry の静的メソッドである Combine を呼び出すことによって作成できます。
CombinedGeometry オブジェクトおよび Combine メソッドはブール演算を実行して、2 つのジオメトリで定義されている領域を結合します。領域を持たない Geometry オブジェクトは破棄されます。結合できるのは、2 つの Geometry オブジェクトだけです。ただし、この 2 つのジオメトリに複合ジオメトリを使用することもできます。
GeometryGroup クラスは、そのクラスに含まれる Geometry オブジェクトについて、その領域を結合することなく混合を作成します。Geometry オブジェクトはいくつでも GeometryGroup に追加できます。例については、「方法 : 複合図形を作成する」を参照してください。
結合操作を実行しないため、GeometryGroup オブジェクトを使用した方が、CombinedGeometry オブジェクトまたは Combine メソッドを使用するよりもパフォーマンスが向上します。
結合したジオメトリ
前のセクションでは、CombinedGeometry オブジェクトと Combine メソッドが、それらに含まれるジオメトリで定義された領域を結合することを説明しました。GeometryCombineMode 列挙体は、ジオメトリを結合する方法を指定します。GeometryCombineMode プロパティに指定できる値は、Union、Intersect、Exclude、および Xor です。
次の例では、CombinedGeometry が和集合の結合モードで定義されています。Geometry1 および Geometry2 は同じ半径の円として定義されていますが、中心は 50 ずれています。
<Path Stroke="Black" StrokeThickness="1" Fill="#CCCCFF">
<Path.Data>
<!-- Combines two geometries using the union combine mode. -->
<CombinedGeometry GeometryCombineMode="Union">
<CombinedGeometry.Geometry1>
<EllipseGeometry RadiusX="50" RadiusY="50" Center="75,75" />
</CombinedGeometry.Geometry1>
<CombinedGeometry.Geometry2>
<EllipseGeometry RadiusX="50" RadiusY="50" Center="125,75" />
</CombinedGeometry.Geometry2>
</CombinedGeometry>
</Path.Data>
</Path>
次の例では、CombinedGeometry が Xor の結合モードで定義されています。Geometry1 および Geometry2 は同じ半径の円として定義されていますが、中心は 50 ずれています。
<Path Stroke="Black" StrokeThickness="1" Fill="#CCCCFF">
<Path.Data>
<!-- Combines two geometries using the XOR combine mode. -->
<CombinedGeometry GeometryCombineMode="Xor">
<CombinedGeometry.Geometry1>
<EllipseGeometry RadiusX="50" RadiusY="50" Center="75,75" />
</CombinedGeometry.Geometry1>
<CombinedGeometry.Geometry2>
<EllipseGeometry RadiusX="50" RadiusY="50" Center="125,75" />
</CombinedGeometry.Geometry2>
</CombinedGeometry>
</Path.Data>
</Path>
その他の例については、「方法 : 複合図形を作成する」と「方法 : 結合したジオメトリを作成する」を参照してください。
Freezable の機能
Geometry クラスは Freezable クラスを継承しているため、いくつかの特殊な機能を備えています。つまり、Geometry オブジェクトをリソースの概要として宣言したり、複数のオブジェクト間で共有したり、読み取り専用にしてパフォーマンスを高めたり、複製したり、スレッド セーフにしたりできます。Freezable オブジェクトのさまざまな機能の詳細については、「Freezable オブジェクトの概要」を参照してください。
その他のジオメトリ機能
Geometry クラスは、次のような便利なユーティリティ メソッドも提供します。
FillContains - ジオメトリに別の Geometry が含まれているかどうかを判断します。
StrokeContains - 指定した点が Geometry のストロークに含まれているかどうかを判断します。
メソッドの完全な一覧については、Geometry クラスを参照してください。
参照
概念
パフォーマンスの最適化 : 2D グラフィックスとイメージング