System.Drawing.Drawing2D 名前空間にある GraphicsPath クラスには、マーカーを作成する SetMarkers() メソッドやマーカーを削除する ClearMarkers() メソッドが用意されています。
私の探し方が悪いのかかつてはあったのか、このマーカーについて解説した日本語資料がほとんど見当たらなかったので記事として残そうと思います。
GraphicsPath
話の前提となる GraphicsPath は、簡単に言うと図形の座標情報のあつまりです。
概要
図形を描画する場合に、基本的な方法として図形の種類に合わせた Graphics.Draw**() や Graphics.Fill**() で直接図形の輪郭線を描いたり塗りつぶしたりするものと思います。
このような場合で特に複数の図形を描画したいような場合に、座標の計算、図形の種類に合わせたメソッドの選択、図形の描画といった処理が混ざった状態で一か所に集中しがちかと思います。
GraphicsPath を利用すると、座標の計算と図形の種類に合わせたメソッドの選択によって GraphicsPath を作成しておいて、別の場所で図形の描画を行うということがやりやすくなります。
参考資料
GraphicsPath についてはここでは細かな説明は行わないので、こちらの資料をご確認ください。
GraphicsPath の使い方
GraphicsPath の内部データ的な話
GraphicsPath のマーカー
ここからがこの記事の本題です。
概要
GraphicsPath に GraphicsPath.Add**() メソッドで図形情報を追加していく途中に GraphicsPath.SetMarker() メソッドを使うことで、その位置にマーカーを追加できます。
マーカーを追加すると、始点 or 終点からマーカー、あるいはマーカーからマーカーの範囲にあるパスのみを取り出すことができるようになります。
マーカーによって区切られた部分のパスを取り出すには GraphicsPathIterator クラスの NextMarker(GraphicsPath) メソッドを使用します。引数の GraphicsPath に取り出されたパスが代入されます。
サンプルコード

丸、三角、四角の 3 つの図形とマーカーを含むパスを作成して、マーカーによってそれぞれの図形のパスを取り出して別々の色で塗りつぶし、最後に元々のパスを利用して各図形に対して同じ色で一度に輪郭線を描きます。
このサンプルコードを動かす場合、Windows フォームの OnPaint(object sender, PaintEventArgs e) イベントなどに貼り付けてみてください。
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
private void MarkerSample(object sender, PaintEventArgs e)
{
// GraphicsPath クラスを実体化
GraphicsPath myPath = new GraphicsPath();
// パスの作成
{
// 円のパスを追加
myPath.AddEllipse(new Rectangle(20, 20, 100, 100));
// マーカーを追加
// 三角形のパスを追加
myPath.SetMarkers();
Point[] myPoints = {new Point(140, 140), new Point(240, 240),
new Point(140, 240),new Point(140, 140) };
myPath.AddLines(myPoints);
// マーカーを追加
// 四角形のパスを追加
myPath.SetMarkers();
myPath.AddRectangle(new Rectangle(260, 260, 100, 100));
}
// マーカーの利用例
{
// GraphicsPathIterator クラスを実体化
// マーカーを使う際はこのクラスを利用する
GraphicsPathIterator myPathIterator = new GraphicsPathIterator(myPath);
// マーカーで区切られた部分の取り出し位置を最初の位置にリセット
// このサンプルコードではこれがなくても意図した通りに動く
// myPathIterator.Rewind();
// 取り出した部分を保持する用の GraphicsPath
GraphicsPath myPathSection = new GraphicsPath();
// パスの最初の部分(丸)を取り出し
myPathIterator.NextMarker(myPathSection);
// パスを塗りつぶす
SolidBrush myBrush = new SolidBrush(Color.Red);
e.Graphics.FillPath(myBrush, myPathSection);
// パスの次の部分(三角)を取り出して、塗りつぶす
myPathSection.Reset();
myPathIterator.NextMarker(myPathSection);
myBrush.Color = Color.Yellow;
e.Graphics.FillPath(myBrush, myPathSection);
//// パスの次の部分(四角)を取り出して、塗りつぶす
myPathSection.Reset();
myPathIterator.NextMarker(myPathSection);
myBrush.Color = Color.Green;
e.Graphics.FillPath(myBrush, myPathSection);
}
// 元々のパスで線を描画
Pen myPen = new Pen(Color.Blue, 3);
e.Graphics.DrawPath(myPen, myPath);
}
0 件のコメント:
コメントを投稿