アルゴリズムのヒントを生成AIに教えてもらおう〜「うずまき」を描くプログラム〜

Monaca Educationで、プロジェクトを新規作成する際、テンプレート「Processing(p5.js)」を選ぶと、図形を描くプログラムを書くことができます。
1秒間に数十回、図形を描きなおす処理を呼び出す方法で、コンピュータによるアニメーションを作成することもできます。

p5.jsの基本について

p5.js(https://p5js.org/)は、無料で使える、オープンソースのJavaScriptライブラリです。
p5.jsの基本は、以下2つのブログ記事で紹介しています。p5.jsの基本的な仕組みについて知りたい方は、先にご覧ください。

p5.jsで図形を描き、色を付ける

p5.jsを使って、図形を描いたり、ボタンを表示してみよう

また、p5.jsの公式サイトのドキュメントは、とても充実しています。簡単に始める方法( https://p5js.org/get-started/ )はもちろん、Webブラウザでアクセスして機能を試すページ( https://editor.p5js.org/ )も用意されています。

複雑な図形を描くためのアルゴリズム

p5.jsには、直線や円など、基本的な図形を描くための関数があらかじめ用意されています。それらの関数に適切な引数を与えて呼び出すだけで、図形を描くことができます。
ただし、複雑な図形を描こうと思うと、プログラムのアルゴリズムを考えなければいけません。
例えば、「うずまき」型を描こうと思ったら、自分でアルゴリズムを考えなければなりません。アルゴリズムを考える前に、そもそも「うずまき」とはどんな形なのか、解析する必要があるかもしれません。

ChatGPTに「うずまき」を描くためのアルゴリズムを考えさせる

今回は、その部分(うずまきがどんな形か解析し、描画するためのアルゴリズムを考える部分)を、ChatGPTにやらせてみました。

(入力したプロンプト)

p5.jsを用いて、うずまきの画像を生成するプログラムを書き出してください。キャンバスのサイズは300×300です。

(ChatGPTが生成したテキスト)


P5.jsを使用してうずまきの画像を生成するために、円形のパスを追いながら進行方向に直角の線を描くことでうずまきを作成することができます。次のようなコードを試してみてください。


let angle = 0;
let angleVel = 0.2;
let radius = 0;

function setup() {
  createCanvas(300, 300);
  background(0);
  angleMode(DEGREES);
}

function draw() {
  translate(width / 2, height / 2);
  let x = radius * cos(angle);
  let y = radius * sin(angle);
  
  stroke(255);
  strokeWeight(2);
  line(0, 0, x, y);

  radius += 0.1;
  angle += angleVel;
}

このプログラムは、始点をキャンバスの中心に置き、そこから角度と半径を使用してうずまきの次の点を決定します。その点から直線を描き、その後で角度と半径を少し増加させます。これを繰り返すことでうずまきが生成されます。

ただし、うずまきの形状や色、背景色などを変更したい場合は、上記のコードを適宜調整してください。

生成されたプログラムをMonaca Educationで実行してみる

ChatGPTが生成したプログラムを、Monaca Educationのp5.jsプロジェクトのsketch.jsにコピーして、実行させてみました(※下の動画は動作の一部です)。

「黒の画面の中心から、白い領域がうず状に広がっていく」というプログラムになっていました。
もう少し、「うず」が分かりやすいプログラムに書き換えてみます。そのためには、ChatGPTが示したプログラムのアルゴリズムを理解しなければなりません。

アルゴリズムを理解する

ファイルsketch.jsのプログラムを読み、どんなアルゴリズムでうずまきを生成したのか、確認してみます。

改めて、先ほど生成させたテキストの中の、プログラムの後に付けられた文章を読んでみましょう。

このプログラムは、始点をキャンバスの中心に置き、そこから角度と半径を使用してうずまきの次の点を決定します。その点から直線を描き、その後で角度と半径を少し増加させます。これを繰り返すことでうずまきが生成されます。

少し分かりにくいので、プログラムのコードとの対応を見ながら考えることにします。ChatGPTに、生成したプログラムに対してコメントを付けるよう、依頼してみました。

(入力したプロンプト)

1行ずつ、コメントをつけてください。

(ChatGPTが生成したテキスト)


もちろんです、以下に1行ずつコメントをつけたコードを記載します:


// 角度の初期化
let angle = 0;

// 角度の変化量の設定
let angleVel = 0.2;

// 半径の初期化
let radius = 0;

// p5.jsのセットアップ関数(初期設定)
function setup() {
  // キャンバスの作成、サイズは300x300ピクセル
  createCanvas(300, 300);

  // 背景色の設定、0は黒色を意味する
  background(0);

  // 角度のモードを度数法に設定(デフォルトはラジアン)
  angleMode(DEGREES);
}

// p5.jsの描画関数(画面の更新ごとに自動的に呼び出される)
function draw() {
  // 描画の中心をキャンバスの中心に設定
  translate(width / 2, height / 2);

  // 極座標を直交座標に変換
  let x = radius * cos(angle);
  let y = radius * sin(angle);
  
  // 線の色を設定、255は白色を意味する
  stroke(255);

  // 線の太さを設定
  strokeWeight(2);

  // 中心から計算された位置(x, y)に向かって線を描画
  line(0, 0, x, y);

  // 次の描画のために半径を少し増加させる
  radius += 0.1;

  // 次の描画のために角度を少し増加させる
  angle += angleVel;
}


このコードはp5.jsを用いたもので、キャンバスの中心から始めて、角度と半径を用いてうずまきの画像を生成しています。

繰り返し実行される処理(関数draw())の終わりあたりを見ると、どうやら、角度を増やすのにあわせて、徐々に半径を増やしていくことで、うずまきを描ける、ということのようです。

概念図を描いてみました。

また、「極座標」という言葉が見えますが、これはある点の座標を示すのに、原点(0,0)からの距離と、角度の値を使って示す方法ですね。それに対して、X軸とY軸が直角に交わっている座標の仕組みが、直交座標です。

角度と、三角関数を使うことで、極座標から直交座標に変換できます。

改めて、プログラム生成時に示された説明を確認してみましょう。

このプログラムは、始点をキャンバスの中心に置き、そこから角度と半径を使用してうずまきの次の点を決定します。その点から直線を描き、その後で角度と半径を少し増加させます。これを繰り返すことでうずまきが生成されます。

該当のプログラムの部分を見てみます。変数radiusが距離で、変数angleが角度です。

なお、最初のtranslate(width / 2,height / 2)は、p5.jsが絵を描くキャンバスの中心(=キャンバスの幅、高さの半分の値)に、座標の原点(0,0)を移動させる処理です。


  translate(width / 2, height / 2);
  let x = radius * cos(angle);
  let y = radius * sin(angle);
  
  stroke(255);
  strokeWeight(2);
  line(0, 0, x, y);

radius×cos(angle)を計算すると、その点の直交座標におけるXの値が分かります。同様に、radiusxsin(angle)を計算すると、その点の直交座標におけるYの値が分かります。

つまり、「原点(0,0)から、計算して分かった座標(x,y)まで、直線を引いている」ということが分かりました。この処理を、radiusの値、angleの値をそれぞれ変化させながら、1秒間に何度も実行することで、うずまき状の線を引いているということです。

「うず」が分かりやすいプログラムに修正する

アルゴリズムが分かったので、修正してみます。
ChatGPTが生成したプログラムでは、原点(0,0)から、座標(x,y)まで直線を引いていたために、「うずまき」らしさが分かりにくくなっていました。
これを、座標(x,y)に、直径10の円を描くようにしてみます。コードのline(0, 0, x, y)の箇所を、次のように変更します。


// line(0, 0, x, y);
circle(x,y,10);

動作の確認

プログラムを変更して、保存すると、プレビューに図形が描かれる様子が表示されます。下の動画は動作の一部です。

うずの形が分かりやすくなりました。

まとめ

今回は、アルゴリズムをChatGPTに考えさせました。それにより、短い時間で、多くのヒントを得ることができました。ヒントを応用して、外側から内側、中心へ向かって、「うずまき」を描くプログラムも、少し考えれば実現出来るでしょう。

そして、AIはとても便利ですが、まだ、ChatGPTが全てを解決してくれるわけではないことが分かりました。生成されたプログラムの内容を理解し、意図した振る舞いに変えるのは、人間の役割といえそうです。