ジェネラティブアート作成時の頭のなか #AltEdu2022 15 日目
#AltEdu2022 も気がつけば後半戦(?)となった。ここまでは何とか遅れずについていけているので、残りもこの調子で頑張ってみたく思う。
さて、本日のお題は「『懐かしさ』を感じるコード」とのこと。これもなかなか厳しい。ちなみに「懐かしい」で Google 画像検索をすると、レトロなおもちゃや家電などが表示されるが、「懐かしさ」(「懐かし『さ』」)で検索すると夕日の風景などが表示されるようになる。「懐かしい」と「懐かしさ」には差異があるということであり、これもなかかなに興味深い。
自分は何に懐かしさを感じるのだろう。そんなことも考えつつ、でも作品にするのであれば、できるだけ多くの人が懐かしさを感じるものが良いのだろう、とも思う。そんなことを考えていると、画像検索で表示されたように、夕日の景色が良いのではないかと考えがまとまった。
青空と雲は私の興味を惹く主題であるが、夕焼け空もまた興味を惹かれる主題の一つでもある。実際、過去にはこんな作品も制作している。
今回は先日作成した空のコード(下記参照)を利用して、夕焼け空を作ってみようと思う。
まず、空と雲の部分だけを取り出し、背景を夕日のように変更する:
size(550,280);noStroke()
background(200,50,60)
K=150
for i in range(K*K):
x=i%K
y=99-i/K
t=noise(x*.01,y*.02)
t=pow(t,8)*8
fill(220,t*200);circle(x*4,y*3,9)
単に赤い空になっただけである。まるでエヴァンゲリオンのセカンドインパクトである。
やはり空はグラデーションでないと夕焼けのようにはならない…気がする。というわけで、色を変えつつ水平線を描画することにより、夕焼け空のグラデーションを表現してみる。指向錯誤しつつ、パラメータを調整しつつ、ついでに雲の色も調整する。
size(550,280);noStroke()
for y in range(280):
stroke(y+10,y*y*.003,50-y*.5)
line(0,y,550,y)
noStroke()
K=150
for i in range(K*K):
x=i%K
y=99-i/K
t=noise(x*.01,y*.02)
t=pow(t,8)*8
fill(250,180,170,t*255+y*.01);circle(x*4,y*3,9)
かなり良い感じになってきた。
絵としてはもう少し横長の方が良い気がするので(空に広がる夕焼けだし)、画像サイズを 600x280 にする(50 ピクセル増やす)。また、沈みゆく太陽もあった方が良いので、描画位置を試行錯誤をしつつ、それも描画する。単に描画しただけだと、単なる円になってしまうので、ブラーフィルタを少々適用しておく:
size(600,280);noStroke()
for y in range(280):
stroke(y+10,y*y*.003,50-y*.5)
line(0,y,600,y)
noStroke()
fill(240,255,99);circle(80,270,90)
filter(BLUR,2)
K=150
for i in range(K*K):
x=i%K
y=99-i/K
t=noise(x*.01,y*.02)
t=pow(t,8)*8
fill(250,180,170,t*255+y*.01);circle(x*4,y*3,9)
なかなか良い感じである。
この絵は冬の夕暮れを想定しており、私の記憶の中にある冬の夕暮れには、建物などのシルエットが存在している。町並みのシルエットを描くのは難しいので、ノイズ関数を使って山のシルエットを描いてみる。シルエットの色は単に黒ではなく、試行錯誤の末、暗い灰色とした。
size(600,280);noStroke()
for y in range(280):
stroke(y+10,y*y*.003,50-y*.5)
line(0,y,600,y)
noStroke()
fill(240,255,99);circle(80,270,90)
filter(BLUR,2)
K=150
for i in range(K*K):
x=i%K
y=99-i/K
t=noise(x*.01,y*.02)
t=pow(t,8)*8
fill(250,180,170,t*255+y*.01);circle(x*4,y*3,9)
stroke(40)
for i in range(600):
line(i,300-noise(i*.0045)*99,i,280)
filter(BLUR,1.2)
なかなか良い感じであるが、冬の雲はもう少し細長く、横長な印象がある(あくまでも私の主観であるが)。上記の画像の雲は、なんだか晩秋の雲を連想させる。というわけで、noise 関数に与える x と y の係数を調整する。より大きく変動すると、変化が激しくなるため雲は薄くなる。なので y の係数は x の係数よりも大きくする。x の係数の方も雲の広がり具合をみつつ、試行錯誤しながら調整する:
size(600,280);noStroke()
for y in range(280):
stroke(y+10,y*y*.003,50-y*.5)
line(0,y,600,y)
noStroke()
fill(240,255,99);circle(80,270,90)
filter(BLUR,2)
K=150
for i in range(K*K):
x=i%K
y=99-i/K
t=noise(x*.015,y*.07)
t=pow(t,8)*8
fill(250,180,170,t*255+y*.01);circle(x*4,y*3,9)
stroke(40)
for i in range(600):
line(i,300-noise(i*.0045)*99,i,280)
filter(BLUR,1.2)
まだまだ改善できそうであるが、なんとか冬の夕暮れになったのではないかと思う。本日はこれを #つぶやきProcessing 化していこうと思う。
複数の場所で使用されている関数を1文字の変数に代入して使うことと、for ループの range を range(K*K) ですべて置き換える。というのも、空のグラデーションも山の稜線も十分に大きな値であれば、それらは画面の外に描画されるだけであり、静止画の場合は特に問題は発生しない(画像生成時間が長くなるが、一瞬待つ程度である)。このように変更したコードであっても、まだ文字数が多い:
C=circle
F=filter
S=stroke
K=150
L=range(K*K)
size(600,280);noStroke()
for y in L:S(y+10,y*y*.003,50-y*.5);line(0,y,600,y)
noStroke()
fill(240,255,99);C(80,270,90);F(BLUR,2)
for i in L:
x=i%K;y=99-i/K
t=noise(x*.015,y*.07)
t=pow(t,8)*8
fill(250,180,170,t*255+y*.01);C(x*4,y*3,9)
S(40)
for i in L:line(i,300-noise(i*.0045)*99,i,280)
F(BLUR,1.2)
よく見ると変数 t は 1 箇所でしか使用されていないので、使用箇所に展開する。
C=circle
F=filter
S=stroke
K=150
L=range(K*K)
size(600,280);noStroke()
for y in L:S(y+10,y*y*.003,50-y*.5);line(0,y,600,y)
noStroke()
fill(240,255,99);C(80,270,90);F(BLUR,2)
for i in L:
x=i%K;y=99-i/K
fill(250,180,170,pow(noise(x*.015,y*.07),8)*2040+y*.01);C(x*4,y*3,9)
S(40)
for i in L:line(i,300-noise(i*.0045)*99,i,280)
F(BLUR,1.2)
まだ 88 文字も多い。
仕方がないので、山の稜線の描画はあきらめよう。また、よく見ると最初の noStroke は不要である(すぐその後で、空のグラデーション表現のため stroke 関数を呼び出しているので)。
C=circle
F=filter
S=stroke
K=150
L=range(K*K)
size(600,280)
for y in L:S(y+10,y*y*.003,50-y*.5);line(0,y,600,y)
noStroke()
fill(240,255,99);C(80,270,90);F(BLUR,2)
for i in L:
x=i%K;y=99-i/K
fill(250,180,170,pow(noise(x*.015,y*.07),8)*2040+y*.01);C(x*4,y*3,9)
まだあと 11 文字減らさないといけない。
さて、どうしたものか。空のグラデーション描画での色指定で用いている式、y+10 は y+9 で近似できることに気がつく。いや、そもそも y (つまり y+0)でも絵にはあまり変化がない。なので、y+10 ではなく、単に y とする。y*.5 も y/2 で良い。y*y*.003 も 0.003≒1/300 なので、y*y/300 に変更する。
雲の描画部分にある noise 関数のところであるが、0.015≒1/66 であるので、x*.015 は x/66.0 で近似(実際のコードは x/66.)。2040 は 2000=2e3 で近似。そして noStroke を stroke(0,0) つまり S(0,0) で代理。
このような努力により、#つぶやきProcessing することができました。
やれやれ。今日は #つぶやきProcessing の技法について、お伝えできたのでは?と思う。参考になれば幸いである。