WisdomSoft - for your serial experiences.

2.11 リージョン

長方形ではない複雑な範囲はリージョンと呼ばれる領域オブジェクトで表現できます。領域は描画に利用できるだけではなく、範囲を指定するためなどにも用いられます。

2.11.1 領域の表現

GraphicsPath は形状を保存するためのクラスでしたが、これと関連して領域を保存するリージョンと呼ばれる情報が存在します。リージョンSystem.Drawing.Region クラスで表され、Region クラスは複雑な形状の領域を表現することができます。矩形以外の、複雑な形の領域を表現するにはリージョンが必要になります。

System.Drawing.Region クラス
System.Object
    System.MarshalByRefObject
        System.Drawing.Region
[ComVisible(false)]
public sealed class Region : MarshalByRefObject, IDisposable

単純な矩形を領域とする場合は Rectangle オブジェクトを、より複雑な形を領域とするには GraphicsPath オブジェクトや Region の組み合わせなどで実現します。

Region クラスのコンストラクタ
public Region()
public Region(GraphicsPath path)
public Region(Rectangle rect)

パラメータを省略した場合は無制限のリージョンが作成されます。無制限とは、すべてを有効な領域として設定されているリージョンのことです。path を設定した場合は、グラフィックスパスで定義されている形状を領域として設定します。rect には、領域を表す矩形を設定します。

作成した Region オブジェクトは Graphics クラスの FillRegion() メソッドで描画することができます。リージョンは形状ではなく領域なので、閉じた図形としか扱えないため DrawRegion() というメソッドは存在しません。

Graphics クラス FillRegion() メソッド
public void FillRegion(Brush brush, Region region)

brush には領域を塗りつぶすブラシを、region には塗りつぶす領域を表すリージョンオブジェクトを指定します。

コード1
using System.Drawing;
using System.Windows.Forms;

public class Test : Form
{
	protected override void OnPaint(PaintEventArgs e) 
	{
		base.OnPaint(e);
		Rectangle rect = new Rectangle(10, 10, 200, 100);
		Region region = new Region(rect);
		Brush brush = new SolidBrush(Color.Black);
		e.Graphics.FillRegion(brush, region);
	}
	static void Main() 
	{
		Application.Run(new Test());
	}
}
実行結果
コード1 実行結果

コード1は、単純な矩形を領域とする Region オブジェクトを作成して、これを FillRegion() メソッドで描画しています。定義した領域が黒く塗りつぶされていることを確認できます。

これだけでは FillRectangle() メソッドを使って描画した方が簡単なのですが、リージョンにはグラフィックスパスを領域として設定したり、リージョンを組み合わせてより複雑なリージョンを作ることができるというメリットがあります。

Region クラスのコンストラクタで GraphicsPath オブジェクトを設定する以外にも、Region クラスの Union() メソッドで、矩形やグラフィックスパス、リージョンを組み合わせることができます。

Region クラス Union() メソッド
public void Union(GraphicsPath path)
public void Union(Rectangle rect); 
public void Union(Region region);

path には領域に追加する GraphicsPath オブジェクトを、rect には領域に追加する矩形を、region には領域に追加する他のリージョンを指定します。これらはすべてが和集合で組み合わされるため、交差する内部が塗りつぶされない GraphicsPath の形状とは異なります。

領域の組み合わせで交差する内部を領域から外したい場合は Xor() メソッドを使います。

Region クラス Xor() メソッド
public void Xor(GraphicsPath path)
public void Xor(Rectangle rect)
public void Xor(Region region)

Xor() メソッドは Union() と同じ使い方ですが、交差する領域は領域から差し引いて組み合わせます。

コード2
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

public class Test : Form
{
	protected override void OnPaint(PaintEventArgs e) 
	{
		base.OnPaint(e);
		GraphicsPath path = new GraphicsPath();
		path.AddEllipse(110, 110, 200, 200);

		Rectangle rect1 = new Rectangle(10, 185, 400, 50);
		Rectangle rect2 = new Rectangle(185, 10, 50, 400);
		Region region = new Region(rect1);
		region.Union(rect2);
		region.Xor(path);

		Brush brush = new SolidBrush(Color.Black);
		e.Graphics.FillRegion(brush, region);
	}
	static void Main() 
	{
		Application.Run(new Test());
	}
}
実行結果
コード2 実行結果

コード2は、リージョンに対して矩形を Union() メソッドで追加して、さらに Xor() メソッドで円を表す GraphicsPath オブジェクトを追加しています。Xor() メソッドは重なる領域を差し引くため、円が矩形に重なる一部を領域から解除してしまいます。