2010/01/16

[C#]角丸の矩形を描画する

このエントリーをはてなブックマークに追加

角丸の矩形を描く

角丸の矩形を描画する関数です。
GraphicsPathで角丸を作ってDrawPathで描画しています。
Form1_Clickは呼び出し側のコードです。
ソースコード
/* using System.Drawing.Drawing2D; */
private void Form1_Click(object sender, EventArgs e) {
  Graphics g = this.CreateGraphics();
  g.SmoothingMode = SmoothingMode.AntiAlias;
    
  DrawRoundRectangle(g, 40.0f, 40.0f, 200.0f, 120.0f, 16.0f, new Pen(Color.Black, 4.0f));
  g.Dispose();
}

private void DrawRoundRectangle(Graphics g, float x,float y,float w,float h, float r, Pen pen) {
  float a = (float)(4 * (1.41421356 - 1) / 3 * r);
    
  GraphicsPath path = new GraphicsPath();
  path.StartFigure();
  path.AddBezier(x, y + r, x, y + r - a, x + r - a, y, x + r, y); /* 左上 */
  path.AddBezier(x + w - r, y, x + w - r + a, y, x + w, y + r - a, x + w, y + r); /* 右上 */
  path.AddBezier(x + w, y + h - r, x + w, y + h - r + a, x + w -r + a, y + h, x + w -r, y + h); /* 右下 */
  path.AddBezier(x + r, y + h, x + r - a, y + h, x, y + h - r + a, x, y + h - r); /* 左下 */
  path.CloseFigure();
    
  g.DrawPath(pen, path);
}

実行結果

まったく同じ要領で、描画にFillPathメソッドを使うことで塗りつぶした図形を描くことができます。
AddBezierメソッドを使用した擬似円弧で描画していますが、AddArcメソッドを使うほうが簡単かもしれません。

補足:GraphicsPathの仕様について気付いたこと

最初は下記のように、角を描いて、線を描いて、角を描いて、線を描いて、とやってました。
GraphicsPath path = new GraphicsPath();
path.StartFigure();
path.AddBezier(x, y + r, x, y + r - a, x + r - a, y, x + r, y);
path.AddLine(x + r, y, x + w - r, y);
path.AddBezier(x + w - r, y, x + w - r + a, y, x + w, y + r - a, x + w, y + r);
path.AddLine(x + w, y + r, x + w, y + h - r);
path.AddBezier(x + w, y + h - r, x + w, y + h - r + a, x + w -r + a, y + h, x + w -r, y + h);
path.AddLine(x + w - r, y + h, x + r, y + h);
path.AddBezier(x + r, y + h, x + r - a, y + h, x, y + h - r + a, x, y + h - r);
path.AddLine(x, y + h - r, x, y + r);
path.CloseFigure();

これって、パーツの終点と次のパーツの始点が同じ座標点になっているので、重なり合った点が無駄にぼろぼろと出そうだなと思ったんです。
ところがデバッグしてGraphicsPathのpointsプロパティをじっくり見てみると、同じ座標点は勝手に省かれていました。このコードは上記のコードと同じ結果になります。
GraphicsPath優秀です。でも逆に考えると、Add~の指定だったら、同じ場所に点が打てないというジレンマもあるのですね…。

0 件のコメント :

コメントを投稿