【ステージ#5】 三角関数の活用に関するプログラミング問題

《難易度★★★》三角関数を使って「円形に並べる」プログラミング問題です。関数を少しずつ変更することで、楕円や螺旋などの形も作れるようになります。

問題

12個のボールを円形に並べて表示するコード(HTML,CSS,javascript)がすでに用意されています。これをベースとして、以下の問題の指示にしたがってコードを追加しなさい。

  • 問題5-1: この内側にもう1周、ボールを6個並べなさい。
  • 問題5-2: 12個のボールを「楕円形」に並べなさい。(最初の円形を縦に少しつぶして横長の楕円状になっている状態に)
  • 問題5-3: ボールを「螺旋状」に並べなさい。

See the Pen ステージ#5問題 by programmingbird (@programmingbird) on CodePen.

問題コード(JavaScript)の確認

//「トリガー」の設定であとで書くアクションの関数を実行している。引数としてnとrを渡している。//「アクション」の設定ユーザー定義関数としてroundを作っている。中身はMath.PI(円周率)やMath.sin(三角関数のサイン)とかMath.cos(同じくコサイン)を使ってボールを円形に並べるもの。引数のnとrは何か?nはボールの数で、rは並べる円の半径(単位はpx)

問題5-1の解説と解答例

解説(発想のしかた)

【トリガーの設定】 内側にもう1周6個ならべろと。内側ってことは半径rを半分ぐらいにすればよいかな。6個なのでnは6にする。引数nを6に、rを100にして関数呼出部分を1行追加しよう。round(6, 100);

解答例

See the Pen ステージ#5問題5-1 by programmingbird (@programmingbird) on CodePen.

問題5-2の解説と解答例

解説(発想のしかた)

① 【アクションの設定】「円形を縦に少しつぶして横長の楕円状」ということなので、関数roundの中身を少し変更する必要がありそうだ。「縦に少しつぶす」ということはy座標を小さくするイメージだな。y座標を決めているのは、たぶん225 + r * Math.sin(i * a)の部分だな。これを少し小さく、60%ぐらいにしてみようか。

//「アクション」の設定
function round(n, r) {
  var a = 360 / n * Math.PI / 180;
  for (var i = 0; i < n; i++) {
    ctx.drawImage(
      bird,
      225 + r * Math.cos(i * a),
      225 + r * Math.sin(i * a) * 0.6,
      50,
      50
    );
  }
}

② 【トリガーの設定】関数の呼び出し部分は、問題5-1と同様にボールが12個なのでnを12、半径のrはもとのままで200にしておこう。round(12, 200);

解答例

See the Pen ステージ#5問題5-2 by programmingbird (@programmingbird) on CodePen.

問題5-3の解説と解答例

解説(発想のしかた)

【アクションの設定】「螺旋状」はどうやって作ればいい?円を描きながら少しずつ少しずつ半径を大きくしていけばいいんじゃないか?まずは、ボールを1個表示するごとにr += 8; をする。スタート時の半径は小さめにしておいたほうがよさそうなので【トリガーの設定】の部分をround(12, 20);にしてみると…いい感じで螺旋状になるが、ちょっと短すぎる感じがするので、ループの回数を3倍ぐらいさせてみよう。 for (var i = 0; i < n * 3; i++)

//「アクション」の設定
function round(n, r) {
  var a = 360 / n * Math.PI / 180;
  for (var i = 0; i < n * 3; i++) {
    ctx.drawImage(
      bird,
      225 + r * Math.cos(i * a),
      225 + r * Math.sin(i * a),
      50,
      50
    );
    r += 8;
  }
}

解答例

See the Pen ステージ#5問題5-3 by programmingbird (@programmingbird) on CodePen.