ジェネラティブアート作成時の頭のなか #AltEdu2022 1 日目
今日のお題は「画面の中央に円を描くところからコードを書いてください。」とのこと。こんな感じで、毎日テーマが設定されていて、そのテーマでみんなが作品を作るというのが #AltEdu2022 というイベントである。
中央に円…と言われて思い浮かんだのは曼荼羅の画像。再帰的に円の配置を繰り返していけば良いか…とぼんやりと考えつつ Twitter をみていると、はぅくんさん(@Hau_kun)さんの作品が目にとまる。
か、かっこいい。
真ん中に円と言われて、お題そのまま、ある意味やっつけ仕事的に捉えていた自分を恥じつつ、そういえば過去に日蝕という作品を作っていたことを思い出す。
今日の気分としては、黒っぽい作品じゃないよな…と思いつつ、であれば、子供が良く描く青空と太陽のような絵を書いてみようと、ふと思いつく。
size(500,500)
background(150,230,255)
c=[255,99,99]
stroke(*c)
fill(*c)
circle(250,250,100)
strokeWeight(3)
for i in range(16):
t=4*i*.1
r=random(9)*5+60
x1=r*cos(t)+250
y1=r*sin(t)+250
x2=50*cos(t+.2)+250
y2=50*sin(t+.2)+250
x3=50*cos(t-.2)+250
y3=50*sin(t-.2)+250
triangle(x1,y1,x2,y2,x3,y3)
真ん中の円がどこかに行ってしまった。さて、どうしようかと思っていたら、よくよくテーマを見直してみると「画面の中央に円を描くところからコードを書いてください。」なので、これでもテーマに沿っている(ひと安心)。とは言え、これでは絵としてあまり面白くはない。
ちなみに triangle 関数は今回初めて使った…ように思う(多分)。変数 t の式については、360 度はラジアンで 2π、つまり大体 6.28。16×4 で 64 なので、それを 0.1 倍して、0 から 6.4 まで 0.4 ラジアン刻み=23 度刻みで変化させるという計算式になっている。
閑話休題。
生成される絵をもうすこし魅力的にするべく色を変えてみることにする。最終的に #つぶやきProcessing として発表する予定なので、文字数圧縮も少し考慮しつつプログラムを少し修正する。
def C(r,g,b):stroke(r,g,b);fill(r,g,b)
size(500,500)
background(99,220,240)
strokeWeight(3)
C(255,50,50)
circle(250,250,100)
C(255,150,50)
for i in range(16):
t=4*i*.1
r=random(9)*5+60
x1=r*cos(t)+250
y1=r*sin(t)+250
x2=50*cos(t+.2)+250
y2=50*sin(t+.2)+250
x3=50*cos(t-.2)+250
y3=50*sin(t-.2)+250
triangle(x1,y1,x2,y2,x3,y3)
文字数圧縮を考えて 1 行目に色変え用の関数 C を追加した。実行結果は以下の通り:
なんとなく良い感じになってきた。今日はこの作業にあまり時間をかけられる状況でもないので、1 日目の作品はここで終わることとしよう。
#AltEdu2022 としては、ここまでで十分なんだと思う。しかし、私の場合は #つぶやきProcessing として作品発表したいので、ここから文字数削減作業に入る(これを code golfing などと言う)。
sin と cos を頻繁に使っているし、どちらも x,y 座標の計算に使っているので、この部分を関数にまとめる。Python は多値返却ができるので、その機能を使う。
def C(r,g,b):stroke(r,g,b);fill(r,g,b)
def P(t,r):return r*cos(t)+250,r*sin(t)+250
size(500,500)
background(99,220,240)
strokeWeight(3)
C(255,50,50)
circle(250,250,100)
C(255,150,50)
for i in range(16):
t=4*i*.1
r=random(9)*5+60
x1,y1=P(t,r)
x2,y2=P(t+.2,50)
x3,y3=P(t-.2,50)
triangle(x1,y1,x2,y2,x3,y3)
Python の場合はインデントの量は決まっていないので、for ループのブロックのインデントを 1 文字として、文字数削減を試みる。一応、このコードを Twitter の tweet 欄に貼り付けてみると文字数オーバー。まだまだ文字数を減らさないといけない。今回は #つぶやきProcessing タグの他に #AltEdu2022 タグも入れないといけないので、かなり文字数を減らさないといけない。
次は変数の除去を行う。よく見ると変数 t 以外は代入するも使用している場所は 1 箇所のみなである。よって、それらの計算を変数が使用されている場所に直接記述するように変更する…んだけれども、関数 P が多値返却を使っているのでちょっと戦略を変えないといけない。というのも、リスト中のタプルを展開する演算子 * は Python3 から導入されたものらしく、Processing が使用している Python 2.7.1 では使用できないからだ。
というわけで、関数 P で triangle に必要な 6 つの変数をすべて計算するように変更する。250 という数値の使用頻度も高くなるので、定数 K にまとめて、それを利用するように変更。
def C(r,g,b):stroke(r,g,b);fill(r,g,b)
K=250
def P(t,r,s):return r*cos(t)+K,r*sin(t)+K,s*cos(t+.2)+K,s*sin(t+.2)+K,s*cos(t-.2)+K,s*sin(t-.2)+K
size(500,500)
background(99,220,240)
strokeWeight(3)
C(255,50,50)
circle(250,250,100)
C(255,150,50)
for i in range(16):
t=4*i*.1
r=random(9)*5+60
triangle(*P(t,r,50))
この状況で再度 tweet 欄にコードを貼り付けてみる。30 文字以上オーバーしており、これでは tweet できない。よく考えてみれば stroke と fill を同じ値に設定しているので、stroke があまり効果を出していない。ということで noStroke 指定をし、stroke 関係のコードを削除する。あわせて変数 t と変数 r も triangle 関数の引数として埋め込むようにする。この変更を行うと for ループの中身が triangle 関数呼び出しひとつになるので、for のコロンの直後にそのまま繋げるようにする(改行ならびにインデント用の文字が不要になるので、文字数削減できる)。
K=250
def P(t,r,s):return r*cos(t)+K,r*sin(t)+K,s*cos(t+.2)+K,s*sin(t+.2)+K,s*cos(t-.2)+K,s*sin(t-.2)+K
size(500,500)
background(99,220,240)
noStroke()
fill(255,50,50)
circle(250,250,100)
fill(255,150,50)
for i in range(16):triangle(*P(4*i*.1,random(9)*5+60,50))
stroke を除去したコードの実行結果は以下の通りである。印象もほとんど変化していない:
上記のコードは 1 tweet 以内に収まるようになったが、#つぶやきProcessing タグが入らない。この関連タグを入れ込むための余白作りが、個人的には最も #つぶやきProcessing で難航する段階である。
関数 P は多値返却する関数であるので、lambda にすれば return 文が不要となる。まず、これを試してみる:
K=250
P=lambda t,r,s:[r*cos(t)+K,r*sin(t)+K,s*cos(t+.2)+K,s*sin(t+.2)+K,s*cos(t-.2)+K,s*sin(t-.2)+K]
size(500,500)
background(99,220,240)
noStroke()
fill(255,50,50)
circle(250,250,100)
fill(255,150,50)
for i in range(16):triangle(*P(4*i*.1,random(9)*5+60,50))
#つぶやきProcessing タグは無事入るようになった。#つぶやきProcessing としてはこれで完成であるが、今回は #AltEdu2022 も入れないといけない。あと 11 文字は削減しないといけない。
コードをよく見ると 250 という数値や 255 や 220 という数値があることに気づく。少々乱暴ではあるが、これらの数値を全部変数 K で置き換えてしまえばある程度の文字数削減はできそうである。ということで、実際にやってみる:
K=250
P=lambda t,r,s:[r*cos(t)+K,r*sin(t)+K,s*cos(t+.2)+K,s*sin(t+.2)+K,s*cos(t-.2)+K,s*sin(t-.2)+K]
size(500,500)
background(99,K,K)
noStroke()
fill(K,50,50)
circle(K,K,100)
fill(K,150,50)
for i in range(16):triangle(*P(4*i*.1,random(9)*5+60,50))
上記のコードで生成された画像は次のようになる:
少し色味が変わってしまったが、無事 #つぶやきProcessing かつ #AltEdu2022 として tweet できた。
今回初めて紙上ライブコーディングを試してみました。また、初めて note を使ってみました。自分の場合は note にまとめるというのが意外に良いのかも…という感じです。読んで下さってありがとうございました。
この記事と似たようなものに、#つぶやきProcessing で空を作るというのがあります:
こちらは note ではありませんが、もしよかったら見て下さい:
この記事が参加している募集
この記事が気に入ったらサポートをしてみませんか?