見出し画像

ジェネラティブアート作成時の頭のなか #AltEdu2022 2 日目

 2 日目のお題は「30 分コードを書いて下さい」とのこと。普段は時間制限を設けず、気ままにプログラミングしているので、30  分で書けるコードと言われると結構身構えてしまう。

また、すぐに描きたいものが想像できる場合もあるし、そうでない時もある。私の場合、常にアイデアが湧いているわけではない。

 思い浮かんだのは、昨日やめてしまった曼荼羅模様と、#AltEdu2022 が始まる直前、1/31 に作っていた作品の改良版を作ることだった。ちなみに、その作品は、こんな感じである。

この作品は、上空から眺めた都市を題材として描いたものであるが、#つぶやきProcessing で描くことはなかなか難しかった。このような絵を生成するのが(その時は)精一杯であった。

 とはいえ、コードを見てみると、まだ文字数削減できそうだし、何よりここで終わるのもどうかという気もしてきた。というわけで 2 日目は、この作品を 30 分で改良して、もう少し写実的な都市の画像を生成するようにしてみよう。

 現実の都市では、それぞれの建物は様々な方向を向いており、太陽光線により照らされる明るさは様々なものになる(CG 用語でいうところの diffuse 成分は、面の法線と太陽の向きとの余弦により決まる、いわゆるランバート則で決定される)。というわけで、矩形を描く rect 関数の前に fill 関数を実行するようにし、その明るさを乱数で変化させるようにしてみる:

def Z(z):return 120+z*.1/(301-z*.1)
size(500,300)
background(180,220,255)
stroke(180,200,255)
for z in range(3000):
  if z%100==0:filter(BLUR,2)
  for i in range(10+z/20):
    h=random(20)+10
    fill(random(9)*10+180)
    rect(random(500),Z(z)-h,random(20)+10,h)

そうすると、このような絵ができる:

うん。なかなか良い感じである(自画自賛)。

 とはいうものの、何となく絵に力がない。色ももう少し全体にはっきりしたほうが良い。それにコードの方も無駄が多い。最初に定義している関数 Z は 1 回しか使用されていない。つまり、使っている部分に展開してしまえば、文字数の削減もできる。

…というわけで、関数 Z を展開しつつ(いわゆるインライン展開だ)、また背景色を定義している background 関数の引数も調整してみる:

size(500,300)
background(150,200,255)
stroke(180,200,255)
for z in range(3000):
  if z%100==0:filter(BLUR,2)
  for i in range(10+z/20):
    h=random(20)+10
    fill(random(9)*10+180)
    rect(random(500),120+z*.1/(301-z*.1)-h,random(20)+10,h)

何だか今ひとつだ。遠方の方に霞んでいる、霞の色が悪い気がする。この色は stroke で指定している輪郭線の色が大きく影響を与えている。というのは遠方に描かれるものほど、密度が高くなるように調整しているからであり、結果として輪郭線部分が相対的に多くなるようになっているためである(c を定数とすれば、関数的には z/(c-z) で y 座標を決めているし、手前のものほど後に描くため。興味のある人は noFill 指定して、輪郭線だけ書いてみるとその様子がよく分かる)。

 というわけで、stroke の色をもう少し白っぽくして、空の色も嘘っぽいので、最初の色に戻して試してみる:

size(500,300)
background(180,220,255)
stroke(240)
for z in range(3000):
  if z%100==0:filter(BLUR,2)
  for i in range(10+z/20):
    h=random(20)+10
    fill(random(9)*10+180)
    rect(random(500),120+z*.1/(301-z*.1)-h,random(20)+10,h)

 良い感じになってきたが白すぎる。あと、この雰囲気ならば、もう少し縦長の絵にしても良いかもしれない。というわけで(って、「というわけで」が多いな)、stroke の値を少し下げて、z による変動量を 2 倍にし、建物の大きさを決める変数 h についても変動料が大きくなるように調整する。画像サイズも 500x600 に変更する。

size(500,600)
background(180,220,255)
stroke(230)
for z in range(3000):
  if z%100==0:filter(BLUR,2)
  for i in range(10+z/20):
    h=random(30)+20
    fill(random(9)*15+120)
    rect(random(500),130+z*.2/(301-z*.1)-h,random(10)+10,h)

かなり良い感じになってきたけど、霞の量が多い。霞の量は filter の適用回数に比例するので、100 回に 1 回を 400 回に 1 回に変更する。

size(500,600)
background(180,220,255)
stroke(230)
for z in range(3000):
  if z%400==0:filter(BLUR,2)
  for i in range(10+z/20):
    h=random(30)+20
    fill(random(9)*15+120)
    rect(random(500),130+z*.2/(301-z*.1)-h,random(10)+10,h)

なかなか良い感じになったように思う。

 今日の #AltEdu2022 は時間制限があるので、此の辺りでやめておこう。問題は、このコードで #つぶやきProcessing できるか否かであるが、無事 tweet できた(やれやれ)。


この記事が気に入ったらサポートをしてみませんか?