本記事は Processing Advent Calendar2019 2日目の記事です。
#つぶやきProcessing を布教していこうと思います。
つぶやきProcessingとテンプレート
今年の5月ごろから本日に至るまで、Twitterで #つぶやきProcessing というハッシュタグを使って、Processingの作品を投稿するという遊びを続けております。
詳細は下記記事からどうぞ
大体1~2日に1作品ぐらいのペースでTwitterにアップしております。ネタは毎回その時に考えていて、うまく思った通りに動いたときは気持ちよいのですが、当然うまくいかずにネタに困る時もあります。そんな時は一旦「格子状に図形を並べる」か「円状に図形を並べる」という土台をとっかかりにして、アイディアを膨らませていることが多いです。
今回はこの二つの土台をテンプレートとして紹介していきます。テンプレートを使えばそれっぽい作品がすぐに作れるので、ネタ出しに使えればなと思っております。(そして #つぶやきProcessing の人口が増えればもっといいなと思っております。)
本記事の対象者としては、プログラミングの基本(変数とか関数とか)とProcessingの基本的な命令(size()とかrect()とか)が分かる方以上を対象としています。
今回掲載するプログラムは(当然)自由に使用していただいて構いません。また、すべて「#つぶやきProcessing」のハッシュタグを含めて1ツイートに収まる長さにしているので、パラメーターや命令をちょっと変えればオリジナルの作品として投稿が可能です。
テンプレートの紹介
格子状に図形を並べる
オセロや将棋盤の盤面のように、図形を縦横に格子状に並べるテンプレートです。
size(500,500);
rectMode(CENTER);
for(int i=0;i<100;i++){
float x=i%10*50+25;
float y=i/10*50+25;
// xとyを使って何か描く
}
これで縦横10マスの、合計100マスの格子ができあがります。各マスの大きさは縦横それぞれ50ピクセルです。
「xとyを使って何か描く」の部分に命令を入れていくことで、作品が出来上がります。ちなみにxとyはそれぞれのマスの中心の座標になります。
例えば、四角形を描くsquare()を使ってみると次のようになります。
size(500,500);
rectMode(CENTER);
for(int i=0;i<100;i++){
float x=i%10*50+25;
float y=i/10*50+25;
square(x,y,50);
}

そのままsquare()を増やしてみると、次のような模様が出来上がります。
size(500,500);
rectMode(CENTER);
for(int i=0;i<100;i++){
float x=i%10*50+25;
float y=i/10*50+25;
square(x,y,50);
square(x,y,40);
square(x,y,30);
square(x,y,20);
square(x,y,10);
}

square()の替わりに、circle()で円を描いてみると、次のような模様になります。
size(500,500);
rectMode(CENTER);
for(int i=0;i<100;i++){
float x=i%10*50+25;
float y=i/10*50+25;
circle(x,y,50);
circle(x,y,40);
circle(x,y,30);
circle(x,y,20);
circle(x,y,10);
}

そんな感じで、いろいろ命令を入れて遊んでみます。例えば、square()とcircle()を組み合わせたら、面白い形になってきました。
size(500,500);
rectMode(CENTER);
for(int i=0;i<100;i++){
float x=i%10*50+25;
float y=i/10*50+25;
square(x,y,50);
circle(x,y,40);
square(x,y,30);
circle(x,y,20);
square(x,y,10);
}

今度は色を付けてみます。xとyはそれぞれ「/2」して半分にすれば、そのままグラデーションとして使うことができます。
size(500,500);
rectMode(CENTER);
for(int i=0;i<100;i++){
float x=i%10*50+25;
float y=i/10*50+25;
fill(x/2);
square(x,y,50);
fill(y/2);
circle(x,y,40);
}

xとyをそのまま使わず、ずらして使ってみることもできます。
size(500,500);
rectMode(CENTER);
for(int i=0;i<100;i++){
float x=i%10*50+25;
float y=i/10*50+25;
fill(x/2);
square(x-10,y-10,20);
fill(y/2);
circle(x+10,y+10,20);
}

square()とline()を組み合わせてみました。
size(500,500);
rectMode(CENTER);
for(int i=0;i<100;i++){
float x=i%10*50+25;
float y=i/10*50+25;
fill(x/2,y/2,255);
line(x-20,y-20,x+20,y+20);
line(x-20,y+20,x+20,y-20);
square(x,y,20);
}

このような形で、テンプレート内でxとyを使って図形や色を適当に描いていくだけで、「格子状に並んだ何か」を作っていくことができます。面白そうな形ができたら、そこからアイディアを膨らませていくことで、作品に仕上げていくことができます。
円状に図形を並べる
続いて、円状に図形を並べるテンプレートです。
size(500,500);
rectMode(CENTER);
for(float r=0;r<TAU;r+=TAU/16){
resetMatrix();
translate(250,250);
rotate(r);
// 何か描く
}
「何か描く」のところに命令を加えることで、円状に回転した図形を並べていくことができます。
格子状に並べる場合と異なりxやyがなく、描いた図形がそのまま回転しながら16個描かれることになります。
まず、square()を使ってみます。
size(500,500);
rectMode(CENTER);
for(float r=0;r<TAU;r+=TAU/16){
resetMatrix();
translate(250,250);
rotate(r);
square(0,0,50);
}

square()を描く座標をずらすと、全方向へ回転しながらずれた図形が描かれます。
size(500,500);
rectMode(CENTER);
for(float r=0;r<TAU;r+=TAU/16){
resetMatrix();
translate(250,250);
rotate(r);
square(150,0,50);
}

複数組み合わせれば紋章のような図形が描かれていきます。
size(500,500);
rectMode(CENTER);
for(float r=0;r<TAU;r+=TAU/16){
resetMatrix();
translate(250,250);
rotate(r);
square(150,0,50);
square(100,0,30);
square(50,0,10);
}

ellipse()の楕円を使えば、お花のような模様を描くことができます。
size(500,500);
rectMode(CENTER);
for(float r=0;r<TAU;r+=TAU/16){
resetMatrix();
translate(250,250);
rotate(r);
ellipse(150,0,200,30);
circle(40,0,15);
}

色を付けると見た目がぐっと良くなります。
size(500,500);
rectMode(CENTER);
for(float r=0;r<TAU;r+=TAU/16){
resetMatrix();
translate(250,250);
rotate(r);
fill(0,255,0);
ellipse(150,0,250,100);
fill(255,255,0);
ellipse(150,0,250,30);
}

rに40をかけると、グラデーションとして使うことができます。
size(500,500);
rectMode(CENTER);
for(float r=0;r<TAU;r+=TAU/16){
resetMatrix();
translate(250,250);
rotate(r);
fill(r*40);
arc(150,0,150,100,-PI/4,PI/4);
arc(100,0,100,50,-PI/4,PI/4);
}

for文のところにある「TAU/16」の「16」が円状に配置する図形の個数となります。数字を増減すれば図形の数も増減していきます。
size(500,500);
rectMode(CENTER);
for(float r=0;r<TAU;r+=TAU/32){
resetMatrix();
translate(250,250);
rotate(r);
fill(r*40,r*20,255);
rect(150,150,250,10);
}

まとめ
座標や命令を適当に設定して、いい感じにならないかなーなんていう神頼みをすることもできます。規則的に図形が並ぶので、適当に設定してもそれっぽい作品が出来上がったりして楽しいものです。
#つぶやきProcessing をターゲットとした場合、今回のテンプレートを使用しても、文字数には結構な余力があるためいろいろなものを生み出せると考えております。(動かし始めるととたんに文字数が枯渇するので、いろいろなHackが必要になるのですが。。)
ちょっとしたテンプレートや技があると、それを土台にコーディングを進めていくことができて便利なので、今後もいろいろな作品を作りながら、スキルアップをしていこうと思います。
おまけ
せっかくなので2つのテンプレートを使っていくつか作品を作ってみました。
size(500,500);
rectMode(CENTER);
for(int i=0;i<100;i++){
float x=i%10*50+25;
float y=i/10*50+25;
stroke(204);
fill(x/2,y/2,0);
bezier(x-25,y-25,x+25,y-25,x-25,y+25,x+25,y+25);
fill(0,y/2,x/2);
bezier(x-25,y+25,x+25,y+25,x-25,y-25,x+25,y-25);
}

size(500,500);
rectMode(CENTER);
for(int i=0;i<100;i++){
float x=i%10*50+25;
float y=i/10*50+25;
fill(0);
square(x,y,50);
fill(x/2,x/2,y/2);
circle(x,y,50);
fill(0);
circle(x+random(20)-10,y+random(20)-10,32);
}

size(500,500);
rectMode(CENTER);
for(float r=0;r<TAU;r+=TAU/16){
resetMatrix();
translate(250,250);
rotate(r);
fill(r*20);
triangle(10,50,200,0,200,50);
fill(r*40);
triangle(10,-100,400,0,400,-100);
}

size(500,500);
rectMode(CENTER);
for(float r=0;r<TAU;r+=TAU/32){
resetMatrix();
translate(250,250);
rotate(r);
noStroke();
fill(64,64,128);
bezier(0,0,40,20,80,-40,120,0);
fill(64,128,64);
bezier(120,0,160,60,200,-80,240,0);
}

コメント