円を描く アイキャッチ

円を描く

どうもこんにちは。
サステナブルにキッチュなきうちです。

突然ですが。
プログラムで図形を描かせるのが好きです。
特に好きなのはコッホ曲線です。雪の結晶みたいなやつ。

シンプルなコッホ曲線

シンプルなコッホ曲線

しかし、一番最初に覚えたのは、(線を描くとか四角を描くとかを除くと)円の描き方です。
円を描く、というと、基本的には大抵のグラフィック描画可能なプログラミング言語には最初っからあるんですが・・・
(例えばC#ならDrawEllipseとか)
そうではなく、例えば「円形に何かイラストを並べる」とかそういうことに応用可能なやつ。
そう、SinとかCosとかの三角関数を使うやつです。

えー、三角関数ぅ~?

ってなる方も多いかもしれませんが、三角関数なんて次の3つを知ってれば詳しく知らなくても円は描けます。

1.角度をもとにX座標とかY座標を計算してくれる
2.X座標はCos、Y座標はSin
3.座標といっても、単位円(=半径「1」の円)上の座標なので、例えば2倍にすれば半径2の円を描ける

というわけで、唐突ですが、コードを載せます。
言語はC#です。
適当にWindowsフォームプロジェクトを作ったあと、フォームのPaintイベントをダブルクリックで生成させた上で、フォームクラスのコードに貼ってあげてください。

Paintイベントの設定

Paintイベントの設定

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        e.Graphics.Clear(Color.Black);

        for(int i = 0; i < 360; i+= 10)
        {
            double theta = i * Math.PI / 180;
            double x = Math.Cos(theta) * 100 + 150;
            double y = Math.Sin(theta) * 100 + 150;
            e.Graphics.DrawRectangle(Pens.Lime, (int)x, (int)y, 8, 8);
        }
    }
}

ここで、iは0から360まで10おきに増えていく値、角度です。
for文の中で i * π / 180 を計算していますが、これは「度数」から「ラジアン」に変換する式です。
プログラミング言語上のSin、Cosは度数ではなくラジアンを受け付けるので。
あるいは、最初からラジアンでfor文を組んでもいいです。
for (double theta = 0; theta <= Math.PI * 2; theta += 0.628) {
という具合に。
(ラジアン…というのは、角度を0から2π(2πでちょうど一周)で表す方式。)

動かすと・・・ほら。

四角を円形に並べてみた

四角を円形に並べてみた


 
これを応用すると、花火っぽいのができます^^

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        e.Graphics.Clear(Color.Black);

        for (int r = 0; r < 100; r += 20)
        {
            for (int i = 0; i < 360; i += 10)
            {
                double theta = i * Math.PI / 180;
                double x = Math.Cos(theta) * r + 150;
                double y = Math.Sin(theta) * r + 150;
                e.Graphics.DrawRectangle(Pens.Lime, (int)x, (int)y, 8, 8);
            }
        }
    }
}
半径を変えながら並べてみた

半径を変えながら並べてみた

ここで、rは半径であり、0から100まで20おきに増えていきます。
先ほどは100倍にしていましたが、今度はr倍にしています。

こういうのをいろいろ変えながら実行してみると楽しいですよ^^

最後にさっきちょっと触れた「何かイラストを・・・」をやってみます。

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        e.Graphics.Clear(Color.Black);

        Image image = Image.FromFile("image.png");

        for (int i = 0; i < 360; i += 20)
        {
            double theta = i * Math.PI / 180;
            double x = Math.Cos(theta) * 100 + 150;
            double y = Math.Sin(theta) * 100 + 150;
            e.Graphics.DrawImage(image, (float)x, (float)y);
        }
    }
}

image.png という名前でお好きな画像をプロジェクトに追加して、プロパティで「出力ディレクトリにコピー」を「常にコピーする」にしてあげてください。

出力ディレクトリにコピー

出力ディレクトリにコピー

実行するとこんな感じです。うちのロゴを並べてみました。

GEEXロゴを円形に並べる

GEEXロゴを円形に並べる

うーん、タコとか並べてみたいな?
タコ並べてみましょう。
タコイラスト、自作しました。よかったらどうぞ。

タコのイラスト

タコのイラスト


タコを並べてみた

タコを並べてみた

予想以上に楽しい絵面になりました(笑)