#描き始める前の注意
Processingでは、x軸は右方向に、y軸は下方向に設定されています。y軸方向(縦方向)の動きが普段使う平面とは逆になっていることに注意が必要です。
#図形を描画する関数
Processingでは、図形を描画するための関数が充実していて、数値を指定するだけで簡単に図形を描画できます。そのうちのいくつかを紹介します。
##ウィンドウを開く
ウィンドウの幅と高さを設定するsize()を使います。
(デフォルトの大きさは100×100pixel)
size()関数では2つのパラメータがあり、1つ目で幅、2つ目で高さを指定します。
幅800ピクセル、高さ500ピクセルのウィンドウが欲しいときは下のようにします。
size(800,500);
##点を描く
point()関数で描きたい点の座標を指定します。
(300,150)の場所に点を描きたいときは下のようにします。
size(600,300);
point(300,150);
##図形を描くための関数
processingでは基本的な図形を描く関数のグループがあり、それらを複数組み合わせることでより複雑な図形を描くことができます。
###線分
線分を描くにはline()関数で始点と終点の座標を指定します。
例えば、(50,50)から(450,150)の線分を引きたいときは下のようにします。
size(500,200);
line(50,50,450,150);
###円
円を描くにはellipse()関数で中心点の座標と円の幅、高さを指定します。
例えば、(200,170)を中心とし、幅300ピクセル、高さ300ピクセル(すなわち半径が150ピクセル)の円を描きたいときは下のようにします。
size(600,400);
ellipse(200,170,300,300);
正円を描きたいときは、ellipse()関数で幅と高さをそろえるか、circle()関数を使うこともできます。中心点の座標、直径を指定します。
(400,300)を中心とし、直径200ピクセルの円を描きたいときには下のようにします。
size(600,600);
circle(400,300,200);
###三角形
三角形を描くときはtriangle()関数で三点の座標を指定します。
(400,50)、(30,350)、(450,400)の三点を通る三角形を描きたいときは下のようにします。
size(500,500);
triangle(400,50,30,350,450,400);
###四角形
長方形を描くときはrect()関数で左上の点の座標、幅、高さを指定します。
(200,80)を左上の点とし、幅250ピクセル、高さ150ピクセルの長方形を描くときは下のようにします。
size(500,250);
rect(200,80,250,150);
正方形を描きたいときはrect()関数で幅と高さをそろえるか、square()関数で左上の点の座標と一辺の長さを指定します。
(50,20)を左上の点とし、一辺130ピクセルの正方形を描くときは下のようにします。
size(500,250);
square(50,20,130);
##図形や線の設定を変える
図形や背景の色や線の色・太さ・端点の形を変えて、描写の幅を広げます。
##色
Proseccingの初期設定では、赤、緑、青(RGB)の3つのパラメータの値をそれぞれ0~255の範囲で指定します。
また、HSBを用いて色の指定をすることもできます。色相、鮮やかさ、明るさを指定する方法で、色に統一感を持たせることができます。
デフォルトでは、
colorMode(RGB,256)
となっており、0~255の256段階で色を指定します。
コードに
colorMode(HSB,360,100,100)
を追加すると、HSBにおいて
色相(Hue)を360段階、彩度(Saturation)、明度(Brightness)をそれぞれ100段階で指定できるようになります。
###背景色
background()関数で指定します。
グレースケールではパラメータ1つで指定できます。
0は黒、128は中間的な灰色、255は白です。
###図形の色
fill()関数で指定します。noFill();を追加すると図形を塗りつぶしません。
##線の設定
###色
stroke()関数で指定します。noStroke();を追加すると図形の枠線を表示しなくなります。
###太さ
strokeWeight()関数で線の太さをピクセル数で指定します。デフォルトでは1ピクセルです。
###両端の形
strokeCap()関数で線分の両端の形を指定します。デフォルトは丸い端で、直角、飛び出た端にすることができます。
###角の形状
strokeJoin()関数で角の形状(線のつなぎ方)を指定します。デフォルトは直角で、丸い角、斜めの角に変えることができます。
size(600,500);
background(255); //背景色変更
fill(0,174,189); //図形色変更
ellipse(200,300,300,300);
noStroke(); //枠線なし
fill(0,102,165); //図形色変更
ellipse(300,250,300,300);
noFill(); //塗りつぶしなし
stroke(0,152,149);
strokeWeight(10); //線の太さ変更
ellipse(400,300,300,300);
stroke(0,72,100); //線の色変更
strokeWeight(20); //線の太さ変更
line(60,25,130,95);
strokeCap(SQUARE); //直角の端
line(160,25,230,95);
strokeCap(PROJECT); //突き出た端
line(260,25,330,95);
strokeCap(ROUND); //丸い端
line(360,25,430,95);
##円の一部だけ描く
arc()関数を使って、円の一部を描くことができます。
円の中心点の座標、円の幅、高さ、円弧の始点と終点の値をラジアンで指定します。
(150,100)を中心点とし、幅・高さともに130ピクセル、始点を0.52ラジアン、終点を5.76ラジアンの円の一部ならば、下のようにします。
size(400,400);
arc(150,100,130,130,0.52,5.76);
##実際に描いてみる
これまで出てきたコードを利用して風船の絵を描いてみます。
void setup(){
size(800,800);
background(255);
}
void draw(){
strokeWeight(1);
stroke(0);
noFill();
arc(560,520,320,320,2.51,3.61); //紐
fill(255,159,21);
triangle(400,470,390,495,410,500); //ゴム部分
arc(400,300,200,200,PI,TWO_PI); //上半分
arc(400,300,200,360,0,PI); //下半分
strokeWeight(24);
stroke(255);
noFill();
point(350,250); //光1
arc(500,340,330,330,2.8,3.3); //光2
}
#描いた絵を動かすプログラム
図形の位置に変数を用いることで、パラパラ漫画の要領で何枚も絵を描き、アニメーションを作ることができます。
常に上に移動するプログラムは下のようにします。
float x = 50;
float speed = 1;
void setup(){
size(800,800);
}
void draw(){
background(255);
x+=speed;
baloonUp(x);
}
void baloonUp(float x){
strokeWeight(1);
stroke(0);
noFill();
arc(560,520-x,320,320,2.51,3.61); //紐
fill(255,159,21);
triangle(400,470-x,390,495-x,410,500-x); //ゴム部分
arc(400,300-x,200,200,PI,TWO_PI); //上半分
arc(400,300-x,200,360,0,PI); //下半分
strokeWeight(24);
stroke(255);
noFill();
point(350,250-x); //光①
arc(500,340-x,330,330,2.8,3.3); //光②
}
例えば、20行目の風船の紐の位置では、2つ目の数値(y座標)に変数xを用いています。
arc(560,520,320,320,2.51,3.61); → arc(560, 520-x ,320,320,2.51,3.61);

また、風船を上下にふわふわと動かすには、三角関数sin xの値域が[-1,1]であることと変化の仕方が曲線的であることを用います。
\frac{\sin x}{x} \, , \, \frac{\cos x}{x}
はグラフで表すと下図のようになり、0に収束します。

これを用いて、ふわふわと動き、かつ次第に動きが小さくなるプログラムを書きました。
int radius = 200;
float x = 50;
float speed = 0.1;
void setup(){
size(800,800);
}
void draw(){
background(255);
x+=speed;
baloonUp(x);
}
void baloonUp(float x){
strokeWeight(1);
stroke(0);
noFill();
arc(555+100*cos(x),520-1000*sin(x)/x,320,320,2.51,3.61); //紐
fill(255,159,21);
triangle(400+100*cos(x)/x,470-1000*sin(x)/x,390+100*cos(x)/x,495-1000*sin(x)/x,410+100*cos(x)/x,500-1000*sin(x)/x); //ゴム部分
arc(400+100*cos(x)/x,300-1000*sin(x)/x,radius,radius,PI,TWO_PI); //上半分
arc(400+100*cos(x)/x,300-1000*sin(x)/x,radius,radius+160,0,PI); //下半分
strokeWeight(24);
stroke(255);
noFill();
point(350+100*cos(x)/x,250-1000*sin(x)/x); //光①
arc(500+100*cos(x)/x,340-1000*sin(x)/x,330,330,2.8,3.3); //光②
}
例えば、20 行目の風船の紐の位置で比較すると、
1つ目の数値(x座標)、2つ目の数値(y座標)を変化させています。
arc(560, 520-x ,320,320,2.51,3.61); → arc(555+100*cos(x),520-1000*sin(x)/x,320,320,2.51,3.61);
それぞれ、100倍、1000倍しているのは、位置の変化をわかりやすくするためです。

##参考文献
著者 Casey Reas,Ben Fry 訳 船田巧 『Processingを始めよう』
著者 巴山竜来 『数学から創るジェネラティブアート』
@reona396 『Processingで描ける図形』
https://qiita.com/reona396/items/5fa4babc8243c4ed4914









