DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

曲線を描く

注意:画像の表示方法が分からないという方は、まず「コントロールやフォームに画像を表示する」をご覧ください。また、線の描画の基本については「線を描く」をご覧ください。

ここでは、様々な種類の曲線の引き方を紹介します。なお円や楕円、または円弧を描画する方法は「長方形、多角形、楕円、円弧、扇形を描く」で説明しています。

カーディナルスプラインの描画

まずはGraphics.DrawCurveメソッドを使ってカーディナルスプラインを描画しましょう。指定した点を通る滑らかな曲線を描画することが出来ます。「滑らかさ」はテンションとして指定でき、通常0〜1の値で指定します。デフォルトは0.5です。

また、Graphics.DrawClosedCurveメソッドを使うと、閉じたカーディナルスプラインを描画することができます。

下記の例でDrawCurveメソッドの使い方を確かめてください。

VB.NET
コードを隠すコードを選択
'Imports System.Drawing
'Imports System.Drawing.Drawing2D
'がソースファイルの一番上に書かれているものとする

'描画先とするImageオブジェクトを作成する
Dim canvas As New Bitmap(PictureBox1.Width, PictureBox1.Height)
'ImageオブジェクトのGraphicsオブジェクトを作成する
Dim g As Graphics = Graphics.FromImage(canvas)

'曲線が通過する点の配列を作成する。最低でも3つ以上の点が必要。
Dim point1 As New Point(30, 20)
Dim point2 As New Point(60, 150)
Dim point3 As New Point(120, 30)
Dim point4 As New Point(200, 140)
Dim point5 As New Point(220, 100)
Dim point6 As New Point(190, 60)
Dim curvePoints As Point() = {point1, point2, point3, point4, point5, point6}

'幅3の青色のPenオブジェクトを作成
Dim bluePen As New Pen(Color.Blue, 3)
'テンション0.5(既定値)のカーディナルスプラインを描画
g.DrawCurve(bluePen, curvePoints, 0.5F)

'幅3の赤色のPenオブジェクトを作成
Dim redPen As New Pen(Color.Red, 3)
'テンション1のカーディナルスプラインを描画
g.DrawCurve(redPen, curvePoints, 1)

'幅3の緑色のPenオブジェクトを作成
Dim greenPen As New Pen(Color.Green, 3)
'テンション0のカーディナルスプライン(直線となる)を描画
g.DrawCurve(greenPen, curvePoints, 0)

'幅1の黄色のPenオブジェクトを作成
Dim yellowPen As New Pen(Color.Yellow, 1)
'2番目の点から5番目の点までを通過するカーディナルスプラインを描画
g.DrawCurve(yellowPen, curvePoints, 1, 3, 0.5F)

'幅1の黒色のPenオブジェクトを作成
Dim blackPen As New Pen(Color.Black, 1)
'テンション1の閉じたカーディナルスプラインを描画
g.DrawClosedCurve(blackPen, curvePoints, 1, FillMode.Alternate)

'リソースを解放する
bluePen.Dispose()
redPen.Dispose()
greenPen.Dispose()
yellowPen.Dispose()
blackPen.Dispose()
g.Dispose()

'PictureBox1に表示する
PictureBox1.Image = canvas
C#
コードを隠すコードを選択
//using System.Drawing;
//using System.Drawing.Drawing2D;
//がソースファイルの一番上に書かれているものとする

//描画先とするImageオブジェクトを作成する
Bitmap canvas = new Bitmap(PictureBox1.Width, PictureBox1.Height);
//ImageオブジェクトのGraphicsオブジェクトを作成する
Graphics g = Graphics.FromImage(canvas);

//曲線が通過する点の配列を作成する。最低でも3つ以上の点が必要。
Point point1 = new Point(30, 20);
Point point2 = new Point(60, 150);
Point point3 = new Point(120, 30);
Point point4 = new Point(200, 140);
Point point5 = new Point(220, 100);
Point point6 = new Point(190, 60);
Point[] curvePoints = { point1, point2, point3, point4, point5, point6 };

//幅3の青色のPenオブジェクトを作成
Pen bluePen = new Pen(Color.Blue, 3);
//テンション0.5(既定値)のカーディナルスプラインを描画
g.DrawCurve(bluePen, curvePoints, 0.5F);

//幅3の赤色のPenオブジェクトを作成
Pen redPen = new Pen(Color.Red, 3);
//テンション1のカーディナルスプラインを描画
g.DrawCurve(redPen, curvePoints, 1);

//幅3の緑色のPenオブジェクトを作成
Pen greenPen = new Pen(Color.Green, 3);
//テンション0のカーディナルスプライン(直線となる)を描画
g.DrawCurve(greenPen, curvePoints, 0);

//幅1の黄色のPenオブジェクトを作成
Pen yellowPen = new Pen(Color.Yellow, 1);
//2番目の点から5番目の点までを通過するカーディナルスプラインを描画
g.DrawCurve(yellowPen, curvePoints, 1, 3, 0.5F);

//幅1の黒色のPenオブジェクトを作成
Pen blackPen = new Pen(Color.Black, 1);
//テンション1の閉じたカーディナルスプラインを描画
g.DrawClosedCurve(blackPen, curvePoints, 1, FillMode.Alternate);

//リソースを解放する
bluePen.Dispose();
redPen.Dispose();
greenPen.Dispose();
yellowPen.Dispose();
blackPen.Dispose();
g.Dispose();

//PictureBox1に表示する
PictureBox1.Image = canvas;

ベジエ曲線の描画

ベジエ曲線(ベジエスプライン)を描くには、DrawBezierメソッドを使います。DrawBezierメソッドでは4つの点を指定しますが、これら4つの点はベジエスプラインの形を決める2本の線と方向を示します。次の例によりご確認ください。

VB.NET
コードを隠すコードを選択
'Imports System.Drawing
'Imports System.Drawing.Drawing2D
'がソースファイルの一番上に書かれているものとする

'描画先とするImageオブジェクトを作成する
Dim canvas As New Bitmap(PictureBox1.Width, PictureBox1.Height)
'ImageオブジェクトのGraphicsオブジェクトを作成する
Dim g As Graphics = Graphics.FromImage(canvas)

'ベジエ曲線の形状を決定する4つの点
Dim point1 As New Point(30, 20)
Dim point2 As New Point(120, 40)
Dim point3 As New Point(60, 120)
Dim point4 As New Point(150, 100)

'幅1の黒色のPenオブジェクトを作成する
Dim blackPen As New Pen(Color.Black, 1)
'矢印を付ける
blackPen.EndCap = LineCap.ArrowAnchor
'ベジエ曲線に接する二本の直線を引く
g.DrawLine(blackPen, point1, point2)
g.DrawLine(blackPen, point3, point4)

'幅1の青色のPenオブジェクトを作成する
Dim bluePen As New Pen(Color.Blue, 1)
'ベジエスプラインを描画する
g.DrawBezier(bluePen, point1, point2, point3, point4)

'リソースを解放する
bluePen.Dispose()
blackPen.Dispose()
g.Dispose()

'PictureBox1に表示する
PictureBox1.Image = canvas
C#
コードを隠すコードを選択
//using System.Drawing;
//using System.Drawing.Drawing2D;
//がソースファイルの一番上に書かれているものとする

//描画先とするImageオブジェクトを作成する
Bitmap canvas = new Bitmap(PictureBox1.Width, PictureBox1.Height);
//ImageオブジェクトのGraphicsオブジェクトを作成する
Graphics g = Graphics.FromImage(canvas);

//ベジエ曲線の形状を決定する4つの点
Point point1 = new Point(30, 20);
Point point2 = new Point(120, 40);
Point point3 = new Point(60, 120);
Point point4 = new Point(150, 100);

//幅1の黒色のPenオブジェクトを作成する
Pen blackPen = new Pen(Color.Black, 1);
//矢印を付ける
blackPen.EndCap = LineCap.ArrowAnchor;
//ベジエ曲線に接する二本の直線を引く
g.DrawLine(blackPen, point1, point2);
g.DrawLine(blackPen, point3, point4);

//幅1の青色のPenオブジェクトを作成する
Pen bluePen = new Pen(Color.Blue, 1);
//ベジエスプラインを描画する
g.DrawBezier(bluePen, point1, point2, point3, point4);

//リソースを解放する
bluePen.Dispose();
blackPen.Dispose();
g.Dispose();

//PictureBox1に表示する
PictureBox1.Image = canvas;

複数のベジエ曲線の描画

連続した複数のベジエ曲線を描画する方法として、DrawBeziersメソッドがあります。次のその例を示します。

VB.NET
コードを隠すコードを選択
'Imports System.Drawing
'Imports System.Drawing.Drawing2D
'がソースファイルの一番上に書かれているものとする

'描画先とするImageオブジェクトを作成する
Dim canvas As New Bitmap(PictureBox1.Width, PictureBox1.Height)
'ImageオブジェクトのGraphicsオブジェクトを作成する
Dim g As Graphics = Graphics.FromImage(canvas)

'ベジエ曲線の形状を決定する点
Dim start As New Point(10, 70)
Dim control1 As New Point(50, 10)
Dim control2 As New Point(80, 30)
Dim end1 As New Point(130, 60)
Dim control3 As New Point(190, 70)
Dim control4 As New Point(200, 120)
Dim end2 As New Point(170, 160)
Dim bezierPoints As Point() = {start, control1, control2, end1, _
                               control3, control4, end2}

'幅1の黒色のPenオブジェクトを作成
Dim blackPen As New Pen(Color.Black, 1)
'矢印をつける
blackPen.EndCap = LineCap.ArrowAnchor
'ベジエ曲線に接する直線を描画
g.DrawLine(blackPen, start, control1)
g.DrawLine(blackPen, control2, end1)
g.DrawLine(blackPen, end1, control3)
g.DrawLine(blackPen, control4, end2)

'幅1の青色のPenオブジェクトを作成
Dim bluePen As New Pen(Color.Blue, 1)
'ベジエスプラインを描画する
g.DrawBeziers(bluePen, bezierPoints)

'リソースを解放する
blackPen.Dispose()
bluePen.Dispose()
g.Dispose()

'PictureBox1に表示する
PictureBox1.Image = canvas
C#
コードを隠すコードを選択
//using System.Drawing;
//using System.Drawing.Drawing2D;
//がソースファイルの一番上に書かれているものとする

//描画先とするImageオブジェクトを作成する
Bitmap canvas = new Bitmap(PictureBox1.Width, PictureBox1.Height);
//ImageオブジェクトのGraphicsオブジェクトを作成する
Graphics g = Graphics.FromImage(canvas);

//ベジエ曲線の形状を決定する点
Point start = new Point(10, 70);
Point control1 = new Point(50, 10);
Point control2 = new Point(80, 30);
Point end1 = new Point(130, 60);
Point control3 = new Point(190, 70);
Point control4 = new Point(200, 120);
Point end2 = new Point(170, 160);
Point[] bezierPoints = { start, control1, control2, end1,
                           control3, control4, end2 };

//幅1の黒色のPenオブジェクトを作成
Pen blackPen = new Pen(Color.Black, 1);
//矢印をつける
blackPen.EndCap = LineCap.ArrowAnchor;
//ベジエ曲線に接する直線を描画
g.DrawLine(blackPen, start, control1);
g.DrawLine(blackPen, control2, end1);
g.DrawLine(blackPen, end1, control3);
g.DrawLine(blackPen, control4, end2);

//幅1の青色のPenオブジェクトを作成
Pen bluePen = new Pen(Color.Blue, 1);
//ベジエスプラインを描画する
g.DrawBeziers(bluePen, bezierPoints);

//リソースを解放する
blackPen.Dispose();
bluePen.Dispose();
g.Dispose();

//PictureBox1に表示する
PictureBox1.Image = canvas;
  • 履歴:
  • 2012/8/3 表示する方法を、PictureBox.Imageプロパティを使った方法に変更。

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • このサイトで紹介されているコードの多くは、例外処理が省略されています。例外処理については、こちらをご覧ください。
  • コードの先頭に記述されている「Imports ??? がソースファイルの一番上に書かれているものとする」(C#では、「using ???; がソースファイルの一番上に書かれているものとする」)の意味が分からないという方は、こちらをご覧ください。
  • .NET Tipsをご利用いただく際は、注意事項をお守りください。