C言語で多角形を描画する

多角形描画の解説ページのアイキャッチ

このページではC言語で「多角形」を描画する方法について解説します。

線を描画するために必要な「ビットマップデータ」や「点の描画方法」については下のページで解説していますので、まだ読んでない方は事前に下のページを読むことをオススメします。

図形描画の解説ページのアイキャッチC言語で図形を描画する

また多角形は複数の線を結ぶことで描画することができます。その「線の描画」については下のページで解説しています。

線描画の解説ページのアイキャッチC言語で線を描画する

特に2つの点を指定して線を描画する drawLineTwoPixels 関数はこのページでも利用していますので、この関数の説明だけでも読んでおいていただけると本ページも読みやすくなると思います。

三角形を描画する

まずは「三角形」の描画を行います。2つの点を指定して斜め線を描画する方法を応用して三角形を描画します。

三角形を描画する考え方

考え方は単純で、三角形の頂点となる3点の座標を指定し、1点目と2点目、2点目と3点目、3点目と1点目それぞれの間に線を引くことで三角形を描画します。

つまり斜め線を描画する(2点指定)で紹介した drawLineTwoPixels 関数に、1点目と2点目、2点目と3点目、3点目と1点目をそれぞれ指定して実行ことで三角形を描画することができます。

三角形を描画するイメージ

スポンサーリンク

三角形を描画する関数

三角形を描画する関数は下記のようになります。

void drawTriangle(
  unsigned char *data, /* ビットマップデータ */
  unsigned int width, /* ビットマップの横幅 */
  unsigned int height, /* ビットマップの高さ */
  unsigned int x1, /* 1つ目の点のx座標 */
  unsigned int y1, /* 1つ目の点のy座標 */
  unsigned int x2, /* 2つ目の点のx座標 */
  unsigned int y2, /* 2つ目の点のy座標 */
  unsigned int x3, /* 3つ目の点のx座標 */
  unsigned int y3, /* 3つ目の点のy座標 */
  unsigned char r, /* 赤の輝度値 */
  unsigned char g, /* 青の輝度値 */
  unsigned char b /* 緑の輝度値 */
){
  drawLineTwoPixels(
    data,
    width,
    height,
    x1, y1,
    x2, y2,
    r, g, b
  );

  drawLineTwoPixels(
    data,
    width,
    height,
    x2, y2,
    x3, y3,
    r, g, b
  );

  drawLineTwoPixels(
    data,
    width,
    height,
    x3, y3,
    x1, y1,
    r, g, b
  );
}

例えば座標 (100, 200)、(100, 200)、(700, 300) を頂点とした三角形を描画をするためには下記のように drawTriangle を呼び出しすれば良いです。三角形の頂点とする3つの座標を、第4引数と第5引数、第6引数と第7引数、第8引数と第9引数でそれぞれ指定しています。

  drawTriangle(
    bitmap.data,
    bitmap.width,
    bitmap.height,
    100, 100,
    100, 200,
    700, 300,
    0x00, 0x00, 0xFF
  );
main 関数について

上記の drawTriangle 関数のように、このページに載せている関数は、下記ページで紹介した main 関数から呼び出すのがオススメです。

C言語で図形を描画する

また PI の定義と math.h のインクルードも必要になりますので注意してください。

libpng をインストールすれば PNG 出力して画像のプレビューも簡単にできます。

このページで紹介する描画結果も上記の main 関数で出力した outpnt.png をプレビューしたものになります。

三角形の描画結果

上記のように drawTriangle 関数を実行した際に出力される output.png は下のようになります。

三角形の出力結果

四角形を描画する

「四角形」についても三角形同様に2つの点を指定して斜め線を描画する方法を応用すれば描画することが可能です。

スポンサーリンク

四角形を描画する考え方

四角形は頂点となる4点の座標を指定し、1点目と2点目、2点目と3点目、3点目と4点目、4点目と1点目それぞれの間に線を引くことで描画することができます。

つまり斜め線を描画する(2点指定)で紹介した drawLineTwoPixels 関数に1点目と2点目、2点目と3点目、3点目と4点目、4点目と1点目をそれぞれ指定して実行することで三角形を描画することができます。

四角形を描画するイメージ

四角形を描画する関数

四角形を描画する関数は下記のようになります。

void drawQuadrangle(
  unsigned char *data, /* ビットマップデータ */
  unsigned int width, /* ビットマップの横幅 */
  unsigned int height, /* ビットマップの高さ */
  unsigned int x1, /* 1つ目の点のx座標 */
  unsigned int y1, /* 1つ目の点のy座標 */
  unsigned int x2, /* 2つ目の点のx座標 */
  unsigned int y2, /* 2つ目の点のy座標 */
  unsigned int x3, /* 3つ目の点のx座標 */
  unsigned int y3, /* 3つ目の点のy座標 */
  unsigned int x4, /* 4つ目の点のx座標 */
  unsigned int y4, /* 4つ目の点のy座標 */
  unsigned char r, /* 赤の輝度値 */
  unsigned char g, /* 青の輝度値 */
  unsigned char b /* 緑の輝度値 */
){
  drawLineTwoPixels(
    data,
    width,
    height,
    x1, y1,
    x2, y2,
    r, g, b
  );

  drawLineTwoPixels(
    data,
    width,
    height,
    x2, y2,
    x3, y3,
    r, g, b
  );

  drawLineTwoPixels(
    data,
    width,
    height,
    x3, y3,
    x4, y4,
    r, g, b
  );

  drawLineTwoPixels(
    data,
    width,
    height,
    x4, y4,
    x1, y1,
    r, g, b
  );
}

例えば座標 (100, 200)、(100, 200)、(700, 300)、(500, 150) を頂点とした四角形を描画をするためには下記のように drawQuadrangle を呼び出しすれば良いです。四角形の頂点とする4つの座標を、第4引数と第5引数、第6引数と第7引数、第8引数と第9引数、第10引数、第11引数でそれぞれ指定しています。

  drawQuadrangle(
    bitmap.data,
    bitmap.width,
    bitmap.height,
    100, 100,
    100, 200,
    700, 300,
    500, 150,
    0x00, 0x00, 0xFF
  );

四角形の描画結果

上記のように drawQuadrangle 関数を実行した際に出力される output.png は下のようになります。

スポンサーリンク

五角形・六角形… を描画する

ここまでの解説を読んでくださった方にはもう分かってると思います。

五角形の場合は5つの頂点を、六角形の場合は6つの頂点を、といったように描画したい多角形の頂点の数分の座標を指定できる関数を用意し、その関数内で全ての頂点を繋ぎ合わせるように drawLineTwoPixels 関数を実行すれば多角形を描画することが可能です。

長方形を描画する

次は「長方形」の描画です。長方形に限定することで、一般の四角形よりも簡単に描画することができます。

長方形を描画する考え方

四角形を描画するで紹介した方法は、drawLineTwoPixels 関数を使用した四角形の描画方法でした。drawLineTwoPixels 関数の中では三角関数を使う必要があり、数学的要素の比較的多いものでした。

しかし、四角形を長方形に限定することで簡単に描画することが可能です。今回は長方形を指定された色で塗り潰すやり方を紹介しようと思います。

始点 (x1, y1) と長方形の幅 w と高さ h が指定されたとき、下のような長方形を描画することを考えます。

長方形を描画するイメージ

この長方形を細かく見てみると、下のように幅 w の横線が h 本集まったものと考えることができます。

長方形が線から構成されるイメージ

さらに、横線は点が横方向に連続的に描画されたものでしたね!

なので、始点 (x1, y1) として、横方向に座標を移動させながら点の描画を w 回繰り返すことで横線を描画し、さらにこの横線の描画を始点から縦方向に座標を移動させながら h 回繰り返すことで長方形を描画することができます。

スポンサーリンク

長方形を描画する関数

長方形を描画する関数は下のようになります。

void drawRectangle(
  unsigned char *data, /* ビットマップデータ */
  unsigned int width, /* ビットマップの横幅 */
  unsigned int height, /* ビットマップの高さ */
  unsigned int x1, /* 始点のx座標 */
  unsigned int y1, /* 始点のy座標 */
  unsigned int w, /* 長方形の幅 */
  unsigned int h, /* 長方形の高さ */
  unsigned char r, /* 赤の輝度値 */
  unsigned char g, /* 青の輝度値 */
  unsigned char b /* 緑の輝度値 */
){
  unsigned int x, y;
  unsigned char *p;
  
  for(y = y1; y < y1 + h; y++){
    for(x = x1; x < x1 + w; x++){
      p = data + y * width * 3 + x * 3;
      p[0] = r;
      p[1] = g;
      p[2] = b;
    }
  }
}

例えば座標 (100, 50) を始点とした幅 400 、高さ 300 を描画をするためには下記のように drawRectangle を呼び出しすれば良いです。四角形の頂点とする4つの座標を、第4引数と第5引数で始点の座標、第6引数と第7引数で長方形の幅と高さをそれぞれ指定しています。

  drawRectangle(
    bitmap.data,
    bitmap.width,
    bitmap.height,
    100, 50,
    400, 300,
    0x00, 0xFF, 0xFF
  );

長方形の描画結果

上記のように drawRectangle を呼び出した時に出力される output.png は下のようになります。

長方形の描画結果

まとめ

このページでは多角形を描画する方法の解説と線を描画する関数の紹介を行いました。

線の描画を利用して様々な多角形が描画できて、少しはプログラミングの楽しさが伝ったかなぁと思います。点と線の描画がマスターできれば様々な図形を描画することが可能です。是非色々試してみてください!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です