日々のこと

まいにちの暮らしをつれづれ書きます

Ruby でクリエイティブ・コーディングをやってみた

これは 🎅GMOペパボエンジニア Advent Calendar 2023 - Adventar の15日目の記事です。
昨日は、CRE チームで一緒に働いている nissyi さんの 2023年 プライベートで書いた・作ったプログラム でした。nissyi さんは仕事でも便利なツールをつくってくれていつも助けてもらっています。1年にやったことをふりかえるのにちょうどいい季節ですね。

さて、この記事は Ruby でクリエイティブ・コーディング(お絵描き)をやってみた記録です。

クリエイティブ・コーディングとは

クリエイティブ・コーディングとは、プログラミングで視覚的・聴覚的な表現をすることです。

Processing というプログラミング言語・開発環境が有名です。
Processing をJavaScript で動かせるようにした、p5.js というライブラリもあります。

アニメーションなど視覚的におもしろい表現を、プログラミングで書いたらすぐ動かせるのが魅力だと思います。

Ruby でやろうと思ったきっかけ

きっかけは、こちらのスライドでした。
Ruby でクリエイティブ・コーディングができるよ!という内容で、やり方が丁寧にガイドされていてわくわくするスライドでした。
(やってみたいと思った方がいたら、このスライドがわかりやすいガイドになっているのでおすすめです!)

speakerdeck.com

Kaigi on Rails の懇親会でこのスライド作者の @chobishiba さんとお話して、Ruby でお絵描きするのはたのしそうと思ったのでした。
以前から自分も p5.js を使ってお絵描きしてみたことはあったのですが、それを Ruby という手に馴染んだ道具で書けるなら、もっと手軽にたのしめそう!と思ったのがやろうと思ったきっかけです。

クリエイティブ・コーディングというと大仰ですが、気軽にプログラミングでお絵描きをしたり図形を組み立てるという感覚で、やってみました。

以前の p5.js でのお絵描き ↓ hibinokoto.hatenadiary.jp

描いたもの

もうすぐクリスマスなので、クリスマスツリーを描いてみることにしました。
これが現在の最終形です。

rbCanvas/p5p5.rb というブラウザベースのエディタを使いました。

途中経過

作っていったプロセスです。

最初は、9 × 9 の碁盤のキャンバスをつくり、1マスごとに正三角形を並べていきました。 色は黒です。
正三角形にするために、Math::sqrt などのメソッドを使って正三角形の高さを算出しました。

def setup
  $xSlide = 80
  $ySlide = Math::sqrt(($xSlide)**2 - ($xSlide / 2)**2)
  $split = 9
  
  createCanvas($xSlide * $split, $ySlide * $split)
end

def draw
  noLoop
  noStroke
  fill("black")
  
  x = 0
  while x < width
    y = 0
    index = 0
    while y < height
      if index.even?
        triangle(x, y + $ySlide, x + $xSlide / 2, y, x + $xSlide, y + $ySlide)
      else
        triangle(x, y, x + $xSlide, y, x + $xSlide / 2, y + $ySlide)
      end
      y += $ySlide
      index += 1
    end
    x += $xSlide
  end
end

色を、黒から緑に変えてみました。

次に、縦の真ん中の三角だけ色をつけて、他の部分は白にしてみました

試しに、クリスマスカラーで緑と赤で交互に塗ってみることにしました。even? を使ってます。

ここで、このままだとツリーの形にできないと気づいたので、座標をどう計算するかかのメモを紙に書いて考えを整理しました。(ものすごく雑な図ですが)

この図の通りに三角を並べていくことにしました。
まず、頂点の1つ目の三角形を置きました

次に、三角形を2段重ねてみました

一番左の列だけ三角形を全部の段に置いてみました。

for文を入れ子にして横にも三角形を並べました

正三角形より高さがあったほうが木の形に見えると思ったので、正三角形をやめて1マスの縦横を同じ長さに揃えました
このあたりで、やっと作りたかったツリーっぽくなってきました 🌲

さらに 1マスのサイズを細かくしてみました

逆向きにも色を塗りたかったので、逆向きにも三角形を並べることにしました。
逆向きの三角形は、色を違う種類の緑に変えてみました。

色の配列を用意して、それぞれの三角形の色をランダムに色付けしてみます。

背景色を黒にしました。

さらに背景色を変えて、テキストを入れて、いったんここで完成にしました。
メリークリスマス! 🎅

コード

最終的なコードはこのようになりました。

def setup
  $xSlide = 10
  $ySlide = 10
  $split = 60
  $colors = ["green", "mediumaquamarine", "lightgreen", "turquoise", "limegreen"]
  
  createCanvas($xSlide * $split, $ySlide * $split)
  background(color(34, 58, 112))
end

def draw
  noLoop
  noStroke
  
  # スタートの座標位置
  xIndex = $split / 2
  yIndex = 0

  for yIndex in 0..$split
    # 一列でx座標を横にずらしていく
    xAdjust = 0

    for xCount in 0..yIndex
      fill($colors[rand(0..$colors.length-1)])
      triangle($xSlide * (xIndex + xAdjust), $ySlide * yIndex, $xSlide * (xIndex + xAdjust - 0.5), $ySlide * (yIndex + 1), $xSlide * (xIndex + xAdjust + 0.5), $ySlide * (yIndex + 1))
      xAdjust += 1
    end

    xIndex -= 0.5
    yIndex += 1
  end

  # 逆三角形を描いていく
  xIndex = $split / 2 - 0.5
  yIndex = 1

  for yIndex in 1..$split
    xAdjust = 0

    for xCount in 0...yIndex
      fill($colors[rand(0..$colors.length-1)])
      triangle($xSlide * (xIndex + xAdjust), $ySlide * yIndex, $xSlide * (xIndex + xAdjust ++ 0.5), $ySlide * (yIndex + 1), $xSlide *(xIndex + xAdjust + 1), $ySlide * yIndex)
      xAdjust += 1
    end

    xIndex -= 0.5
    yIndex += 1
  end

  fill("white")
  textFont('Courier New')
  textSize($xSlide * 3)
  text("Merry", $xSlide * 3, $ySlide * 5)
  text("Christmas", $xSlide * 3, $ySlide * 10)
  textSize($xSlide * 2.5)
  text("2023.12.15", width / 1.6, height - 50)
end

やってみて思ったこと

1. 書いてみてどう表示されるかがたのしい

普段の業務などでのコーディングとはまた違った作業でした。
書いてみてどう表示されるか見て、じゃあこうしてみようと横道に逸れたりと、偶発性をたのしむような時間でたのしかったです。まさにお絵描きでした。

2. 漸進的に作っていく

少しずつつくっては見てつくっては見て、と漸進的につくっていくプロセスになりました。

3. 座標をどう置くかのメモがあると描きやすい

途中までは組み立てはあまり考えずに試しつつ書いていたのですが、形にしたいものを作るには座標をどう計算するかをメモしたものを用意したところ、描きやすくなりました。

4. Ruby のメソッドですっと書けるのが良い

描き初めは、Ruby のメソッドで書けるのに、p5.js のメソッドがないか探していていました。
途中で、Ruby のメソッドですっと書けることに気づいてやりやすくなりました。
例えば、ある数を2乗する方法は、p5.js だとsq(a) と書くのですが動か図、a**2Ruby の記法で書けばよかったということに気づくのに少し時間をかけてしまいました。

https://p5js.org/reference/#/p5/sq

今回のお絵描きは、Kaigi on Rails の懇親会でお話しなかったらやってみようと思わなかったと思うので、私にとっての Kaigi Effect でした。
たのしかったので、また Ruby でちょこちょこしたお絵描きをやっていきたいです。

明日は

明日は同じサービスで Android エンジニアをされている北原さんです!