C# サンプル集 |
Visual Basic 中学校 > C# サンプル集 > C# サンプル集目次 > Windowsフォーム >
多角形を描画する
2020/12/20
このページで紹介するサンプルは Windowsフォームアプリケーションを前提にしています。
サンプルの pictureBox1_Paint は PictureBox の Paint イベントの発生時に呼び出される前提です。そうなるようにするにはたとえば、プロパティーウィンドウでPaintイベントをダブルクリックします。
描画するタイミングについては下記にサンプルを参照してください。
赤い五角形
private void
pictureBox1_Paint(object
sender,
PaintEventArgs e) { //五角形の頂点の座標 Point p1 = new Point(105, 10); Point p2 = new Point(10, 79); Point p3 = new Point(46, 191); Point p4 = new Point(164, 191); Point p5 = new Point(200, 79); //頂点を結んでできるパス(≒図形)を定義 var polygon = new System.Drawing.Drawing2D.GraphicsPath(); polygon.AddPolygon(new Point[] {p1, p2, p3, p4, p5}); //パスを描画 e.Graphics.DrawPath(Pens.Red, polygon); } |
実行結果
青く塗りつぶした六角形
private void
pictureBox1_Paint(object
sender,
PaintEventArgs e) { //六角形の頂点の座標 Point p1 = new Point(97, 10); Point p2 = new Point(10, 60); Point p3 = new Point(10, 160); Point p4 = new Point(97, 210); Point p5 = new Point(184, 160); Point p6 = new Point(184, 60); //頂点を結んでできるパス(≒図形)を定義 var polygon = new System.Drawing.Drawing2D.GraphicsPath(); polygon.AddPolygon(new Point[] {p1, p2, p3, p4, p5, p6}); //パスを描画 e.Graphics.FillPath(Brushes.Blue, polygon); } |
実行結果
太い黒い枠線の七角形
private void
pictureBox1_Paint(object
sender,
PaintEventArgs e) { //七角形の頂点の座標 Point p1 = new Point(107, 10); Point p2 = new Point(29, 48); Point p3 = new Point(10, 132); Point p4 = new Point(64, 200); Point p5 = new Point(150, 200); Point p6 = new Point(204, 132); Point p7 = new Point(185, 48); //頂点を結んでできるパス(≒図形)を定義 var polygon = new System.Drawing.Drawing2D.GraphicsPath(); polygon.AddPolygon(new Point[] {p1, p2, p3, p4, p5, p6, p7}); //パスを描画 Pen pen = new Pen(Color.Black, 8); //太さ8の黒いペン e.Graphics.DrawPath(pen, polygon); } |
実行結果
線形のグラデーションで塗りつぶされた八角形
private void
pictureBox1_Paint(object
sender,
PaintEventArgs e) { //八角形の頂点の座標 Point p1 = new Point(110, 10); Point p2 = new Point(39, 39); Point p3 = new Point(10, 110); Point p4 = new Point(39, 181); Point p5 = new Point(110, 210); Point p6 = new Point(181, 181); Point p7 = new Point(210, 110); Point p8 = new Point(181, 39); //頂点を結んでできるパス(≒図形)を定義 var polygon = new System.Drawing.Drawing2D.GraphicsPath(); polygon.AddPolygon(new Point[] {p1, p2, p3, p4, p5, p6, p7, p8}); //頂点1(p1)を青、頂点4(p4)を赤として、徐々に変化する色で塗りつぶすブラシを作成 var gradientBrush = new System.Drawing.Drawing2D.LinearGradientBrush( p1, p4, Color.Blue, Color.Red); //塗りつぶした八角形を描画 e.Graphics.FillPath(gradientBrush, polygon); } |
実行結果
正n角形
この例の DrawPolygon メソッドは引数で指定した n角形を描画します。
このサンプルでは 12 を指定して12角形を描画します。
private void
pictureBox1_Paint(object
sender,
PaintEventArgs e) { //サイズ100の正12角形を描画します。 DrawPolygon(12, 100, e.Graphics); } /// <summary> /// 正多角形を描画します。 /// </summary> /// <param name="index">角の数。六角形の場合6。</param> /// <param name="size">大きさ。この多角形の外接円の半径。</param> /// <param name="g">この図形を描画するGraphicsオブジェクト。Paintイベント内でe.Graphicsなどで取得できます。</param> private void DrawPolygon(int index, int size, Graphics g) { //▼各頂点の座標を算出 //原点を中心としたときの各頂点の座標を算出します。 //中心角(360度)をn等分したときの1角あたりの角度(単位はラジアン) double degree = (Math.PI * 2) / index; var points = new List<Point>(); for (int i = 0; i < index; i++) { //点0から点iの角度(角 点1-O-点iの角度)に180度加えたもの。単位はラジアン。 //180度 = Math.PIラジアン //180度加えなくても良いのですが、学校数学とy軸の方向が逆になっているので、180度加えることで、 //学校数学でなじんだような配置になります。 double thisDegree = degree * i + Math.PI; //点iのx座標 double x = Math.Sin(thisDegree) * size; //点iのy座標 double y = Math.Cos(thisDegree) * size; //この点を記憶しておく points.Add(new Point((int)x, (int)y)); } //▼全体が見えるように平行移動させる //原点を中心とした座標だと第1象限~第4象限のすべてが使用されますが、 //コンピューターは既定では第1象限しか描画・表示しないのですべての点が第1象限に収まるように //図形を平行移動させます。 //TranslateTransformを使うと一撃で平行移動できます。 //第4象限まで見えるように平行移動させる。(既定では第1象限しか表示されていない。) //g.TranslateTransform(size, size); //←これで移動すると一撃です。 //あえて、すべての頂点の座標を再計算して第1象限に平行移動するには下記のようにします。 int offsetX = Math.Abs(points.Aggregate((min, p) => min.X < p.X ? min : p).X); int offsetY = Math.Abs(points.Aggregate((min, p) => min.Y < p.Y ? min : p).Y); offsetX += 10; //上側に余白として 10ピクセルの隙間を空けます。 offsetY += 10; //左側に余白として 10ピクセルの隙間を空けます。 for (int i = 0; i < points.Count; i++) { points[i] = new Point(points[i].X + offsetX, points[i].Y + offsetY); //System.Diagnostics.Debug.Print(points[i].ToString()); //算出後の座標を出力します。 } //▼描画 //背景色黒 g.Clear(Color.Black); //座標を配列化して間を線で結ぶ。 g.DrawPolygon(Pens.Green, points.ToArray()); } |
実行結果