04-03 配列を使った図形描画

練習問題4-3-1

実際に、太陽系の惑星の距離データを使って、軌道を描いてみましょう。

ヒント: さっきのコードで、円の大きさを決めていたのは i * 60 の部分でした。ここを「配列の 𝑖 番目のデータ」に変えてみましょう。

function setup() {
  createCanvas(500, 500);
  noFill();

  // 太陽から各惑星までの距離をスケールダウンしたもの
  let radii = [5, 10, 15, 23, 78, 143, 288, 450];

  for(let i=8; i > 0; i--){
    circle(width/2, height/2, radii[i])
  }
}
変なところで凡ミスしましたが、それ以外は特に問題は置きませんでした。

練習問題4-3-2

  for(let i=0; i>sizes.length; i++)

確かに汎用性を高めるならこの方がいいですね

練習問題4-3-3

次は、惑星の「大きさ」を可視化してみましょう。
以下の配列 sizes には、水星から海王星までの大きさが格納されています(見やすくするために調整されています)。
for文を使って、これらの惑星を横一列に、等間隔で(100pxごとに)並べて描画してください。

function setup() {
  createCanvas(800, 300);
  noFill();

  // 惑星のサイズ(直径)
  let sizes =[7, 17, 18, 10, 200, 167, 73, 70];

  for(let i=0; i<sizes.length; i++){
    circle(50+i*100, height/2, sizes[i]);
  }
}
英語の綴りをミスりつつも、結構すぐに作れました。
問題に100ずつ配置すると書いてあったので最初の円の位置を100にしていたらまで入らなかったので初期値を50にしました。これはなかなか高度な引っ掛け問題でした。

練習問題4-3-4

前問では等間隔に並べましたが、今度は惑星同士が接するように(隙間なく)並べてみましょう。

塗りつぶしの色は、線の色と同じ色ですが、透明度を 50 として描画してください。

ヒント:円の中心座標を管理する変数(xなど)を用意し、for文の中で「半径分だけ進めて円を描く -> さらに半径分だけ進める(次の円のために)」という処理を行うと、きれいに並びます。

function setup() {
  createCanvas(800, 300);

  // 惑星のサイズ(直径)
  let sizes =[7, 17, 18, 10, 200, 167, 73, 70];
  let interval=10
  let r=160
  
  for(let i=0; i<sizes.length;i++){
    interval=interval+sizes[i]/2
    fill(r, 210, 240, 50)
    stroke(r, 210, 240)
    circle(interval, height/2, sizes[i])
    interval=interval+sizes[i]/2
    r+=10
  }
}
この課題はミスにミスを重ねてほぼ消去法みたいな解き方をしました。決して考えていないわけではありません。
色々しても重なったり、間ができたりしてしまったため、一回のループで2回も変数を変えてしまいました。普通なのかもしれませんが、この思考にたどり着くのに意外と時間がかかりました。
それと今回は色も変えました!
そして現れた透明度、裏技みたいな場所にありました。

練習問題4-3-5

次は、パレットにある色の数だけ、円を横に並べて描いてみましょう。
palette.length を使って、配列の要素の数だけ繰り返します。
また、キャンバスの横幅に合わせて円の大きさが自動で調整され、端から端までぴったり敷き詰められるように作成してください。

function setup() {
  createCanvas(300, 300);
  
  noStroke()
  // 色の配列
  let palette = ["#E76F51", "#F4A261", "#E9C46A", "#2A9D8F", "#264653", "#5c374c", "#98527]7", "#ce6a85"];

  for(let i=0; i<palette.length; i++){
    fill(palette[i])
    circle((width/palette.length)/2+i*(width/palette.length), height/2, width/palette.length)
  }
}
この課題では色々やったことがなかったことをやったので、ミスりまくると思っていましたが、意外とサクサク解けて楽しかったです。
一番めんどくさかったのが、18.75をどうやって数字を使わずに出すかでした。
一番苦戦したのが、noStrokeがなぜか動かず、大変でした。動かなかった理由はSが大文字だったことに気づかなかったためです。

練習問題4-3-6

配列に好きな色を入れて、単純な丸を使ったパターンアートを作ってみましょう。

色の参考:COOLORS

  let palette = ["#F5DD90", "#D2FF96", "#E9C46A", "#EDFF7A", "#C3423F", "#5BC0EB", "#B7F0AD ","#F68E5F"];
こういうことなのでしょうか?
それともやはり、下の文言とつながっていたのでしょうか?
私には別の事を言っているように感じたのでどちらもやろうと思いいたりました。

4-3-6.5?

for文を使ってたくさんの円を描き、パレットの色を順番に使ってカラフルな模様にしてください。

ヒント:i % palette.length(剰余演算)を使うと、配列の要素数を超えても、0, 1, 2…と最初に戻って色を繰り返し取得できます。

function setup() {
  createCanvas(600, 400);
  background(245); // 背景色
  noStroke();      // 枠線なし

  // カラーパレット
  let palette = ["#264653", "#2A9D8F", "#E9C46A", "#F4A261", "#E76F51"];

  // 100個の円を描く
  for (let i = 0; i < 100; i++) {
    // ここにコードを書いてください
    fill(palette[i % palette.length])
    circle(random(width), random(height), random(10,80))
  }
}
正直i % palette.lengthというのはどういう仕組みで動いているのかよく分かってはいません、なので今度聞こうと思います。

練習問題4-3-7

配列に実際のデータを入れて、グラフとして表示してみましょう。今回は、気象庁の気象データを使って、月別の気温や降水量を可視化します。

次のサイトから2025年の諏訪市の降水量のデータを取得して、下記の雛形の配列 rainfall にだ代入しなさい。

let rainfall = [12.5, 5, 35, 11, 33.5, 215.5, 163, 78, 119.5, 130.5, 25, 35];

練習問題4-3-8

練習問題4-3-7で作成したスクリプトの続きに、罫線を描くスクリプトを追加しなさい。

座標は数値で指定せず、出来る限り変数 grid を使用して作ること。

function setup() {
  createCanvas(300, 250);
  background(255);

  let rainfall = [12.5, 5, 35, 11, 33.5, 215.5, 163, 78, 119.5, 130.5, 25, 35];
    let grid = 20;

  // グリッド線の描画
  stroke(200);
  strokeWeight(1);
  while(grid < width){
    line(0, grid, width, grid);
    line(grid, 0, grid, height);
    grid+=20
  }
  grid=20

  // 座標軸の描画
  stroke(0);
  strokeWeight(1);
  line(grid, height - grid, width, height - grid)
  line(grid, 0, grid, height-grid)
  
}
なかなかいい出来だと思いますが、x軸が少しずれているのが気にならなくもありません。
ですが、gridを使って作るとこのようにするのだと、私の限界でした。

練習問題4-3-9

練習問題4-3-8で作成したスクリプトの続きに、棒グラフを描くスクリプトを追加しなさい。

rainfall 配列の各要素を、for文を使って棒グラフとして描画してください。各棒は、X軸上に等間隔で配置し、降水量に応じた高さにします。

座標は数値で指定せず、出来る限り変数 grid を使用して作ること。

function setup() {
  createCanvas(300, 250);
  background(255);

  let rainfall = [12.5, 5, 35, 11, 33.5, 215.5, 163, 78, 119.5, 130.5, 25, 35];
    let grid = 20;

  // グリッド線の描画
  stroke(200);
  strokeWeight(1);
  while(grid < width){
    line(0, grid, width, grid);
    line(grid, 0, grid, height);
    grid+=20
  }
  grid=20

  // 座標軸の描画
  stroke(0);
  strokeWeight(1);
  line(grid, height - grid, width, height - grid)
  line(grid, 0, grid, height-grid)
  
    // グラフの描画
  let x=height-grid
  stroke(0, 150, 200);
  strokeWeight(10);
  for(let i=0;i<rainfall.length;i++){
    line(40+i*grid, x, 40+i*grid, x-rainfall[i]);
    print(rainfall[i])
    
  }
  
}
できるだけ指示通りに作ったつもりです。
gridだけだと厳しかったので、いろいろ工夫はしました。
それとグラフの始まりがなんか不自然です。
直そうと思えば何とかならなくもなさそうですが、結構根本的に直さなきゃ厳しそうなので、今回はやめておきます。

コメントする