CHROMA

世の中の "当たり前" を確認する

processing.jsの構造

今後Basic Demosのものを参考にいくつか作って行きたいと思います。

今回はProcessing.jsの構造が書かれてる箇所を読んだのでそこのまとめ。
再帰2、グラフィック作成の項目の解釈はまだできてないし、間違ってる箇所も多々あると思うので調べたり理解で来たところから直してく。
この記事はメモみたいなものです。

構造

コメント

"Statements are the elements that make up programs. The ";" (semi-colon) symbol is used to end statements. It is called the "statement terminator." Comments are used for making notes to help people better understand programs. A comment begins with two forward slashes ("//")."

ステートメントは、プログラムを構成する要素である。 ";"(セミコロン)記号は、文を終了するために使用されます。これは、 "文の終了記号"と呼ばれています。コメントは、人々がより良いプログラムを理解するためにノートを作るために使用されています。コメントは、2つのスラッシュ( "//")で始まります。

※ただのコメントの為、コードの引用無し

座標

"All shapes drawn to the screen have a position that is specified as a coordinate. All coordinates are measured as the distance from the origin in units of pixels. The origin [0, 0] is the coordinate is in the upper left of the window and the coordinate in the lower right is [width-1, height-1]."

画面に描かれたすべての図形は座標として指定された位置を持っています。すべての座標はピクセル単位での原点からの距離として測定されます。 座標原点は、ウィンドウの左上にあり、[0,0]となります。右下の座標は[width-1 、height-1]となります。

// All Examples Written by Casey Reas and Ben Fry
// unless otherwise stated.
// Sets the screen to be 200, 200, so the width of the window is 200 pixels
// and the height of the window is 200 pixels
size(200, 200);
background(0);
noFill();
stroke(255);

// The two parameters of the point() method each specify coordinates.
// This call to point() draws at the position [100, 100]
point(width/2, height/2);

// Draws to the position [100, 50]
point(width/2, height/4); 

// It is also possible to specify a point with any parameter, 
// but only coordinates on the screen are visible
point(60, 30);
point(60, 134);
point(160, 50);
point(280, -800);
point(201, 100);

// Coordinates are used for drawing all shapes, not just points.
// Parameters for different methods are used for different purposes.
// For example, the first two parameters to line() specify the coordinates of the 
// first point and the second two parameters specify the second point
stroke(204);
line(0, 73, width, 73);

// The first two parameters to rect() are coordinates
// and the second two are the width and height
rect(110, 55, 40, 36);

解釈

point(width/2, height/2);

point()でwidth, heightの座標位置を指定します。
width/2とかみたいにpoint()では計算させて数値を指定することもできる。

point(60, 30);
point(60, 134);
point(160, 50);
point(280, -800);
point(201, 100);

こっちはピクセルでの指定方法。
下2つは表示領域を超えているため、画面上に表示されてない。

stroke(204);
line(0, 73, width, 73);

stroke()で線の色の指定。
line()で線の開始点と終点を指定。1番目開始点のx座標、2番目開始点のy座標、3番目終点のx座標、4番目終点のy座標、"width"と指定することでsize()で指定している値(ここでは200)を取ってくる。

point()
一つの画素の大きさで空間の座標を描画します。最初のパラメータはポイントの水平方向の値であり、2番目の値はポイントの垂直方向の値であり、オプションの三番目の値が深さの値です。
http://processingjs.org/reference/point_/

line()
画面に線を(2点間のダイレクト·パス)を描画します。 line()に4つのパラメータを持たせることで2Dの線を描きます。線に色を付けるために、stroke()関数を使用します。
デフォルトでは1ピクセルの幅で描画されますが、これはstrokeWeight()関数を使って変更することができます。
6つのパラメータを記述することでXYZ空間内の配置も可能です。 http://processingjs.org/reference/line_/

rect(110, 55, 40, 36);

四角形の描画をしています。

rect()
画面に四角形を描画します。四角形は、90度の角度で、あらゆる角度と四辺形です。最初の2つのパラメータの位置を設定し、第三には、幅を設定し、4番目は高さを設定します。起源はrectMode()関数を使って変更されます。
http://processingjs.org/reference/rect_/

幅と高さの指定

"The 'width' and 'height' variables contain the width and height of the display window as defined in the size() function."  

'width'と 'height'の変数はsize()で定義されるように、表示ウィンドウの幅と高さを含んでいます。

// All Examples Written by Casey Reas and Ben Fry
// unless otherwise stated.
size(200, 200);
background(127);
noStroke();
for(int i=0; i<height; i+=20) {
  fill(0);
  rect(0, i, width, 10);
  fill(255);
  rect(i, 0, 10, height);
}

解釈

int()で整数型の配列に変換。
rect()でx座標0の位置からy座標のiが200px(sizeのheight)になるまで、20pxの間隔を空けて幅200px(sizeのwidth), 高さ10pxの黒の四角形の描画を繰り返す。
同様に、rect()でy座標0の位置からx座標のiが200px(sizeのwidth)になるまで、20pxの間隔を空けて高さ200px(sizeのheight), 幅10pxの白の四角形の描画を繰り返す。

黒→白の四角形の壁画を交互に繰り返しており、黒が下で白が上、黒が下で・・・と、四角形が交差する形で網目状になっている。

描画設定

"The draw() function creates a structure in which to write programs that change with time."

draw()は、時間と共にその変更プログラムを作成するための構造を作成します。

// All Examples Written by Casey Reas and Ben Fry
// unless otherwise stated.
// The statements in the setup() function 
// execute once when the program begins
void setup() 
{
  size(200, 200);  // Size should be the first statement
  stroke(255);     // Set line drawing color to white
  frameRate(30);
}

float y = 100;

// The statements in draw() are executed until the 
// program is stopped. Each statement is executed in 
// sequence and after the last line is read, the first 
// line is executed again.
void draw() 
{ 
  background(0);   // Set the background to black
  y = y - 1; 
  if (y < 0) { y = height; } 
  line(0, y, width, y);  
}

解釈

void setup() 
{
  size(200, 200);  // Size should be the first statement
  stroke(255);     // Set line drawing color to white
  frameRate(30);
}

描画領域のサイズ設定、線の色設定、frameRate()でfps:フレームス パー セコンドの指定を行なっている。

void

http://processingjs.org/reference/void/

setup()
プログラムが起動されたときに一度だけ呼び出されます。
draw()が実行される前に画面サイズ、背景色、ローディング画像などの定義に使用します。
変数は、setup()の内での宣言をdraw()を含む他の関数内ではアクセスできません。
1つのdraw()に対して1つのsetup()が存在し、最初の実行後に再度呼び出すことができません。
http://processingjs.org/reference/setup_/

frameRate()
秒ごとに表示されるフレーム数を指定します。プロセッサが指定されたレートを維持するのに十分高速ではない場合は達成されません。
たとえば、関数呼び出しのフレームレート(30)は1秒間に30回を更新しようとします。この場合、setup()内のフレームレートを設定することをお勧めします。
デフォルトのレートは毎秒60フレームです。
http://processingjs.org/reference/frameRate_/

float y = 100;

変数yに100を代入。
ここで浮動小数点の指定をする必要はなく、int()でも表示・動作は変らない。

float
浮動小数点数のデータ型。
http://processingjs.org/reference/float/

void draw()
{
  background(0);   // Set the background to black
  y = y - 1;
  if (y < 0) { y = height; }
  line(0, y, width, y);
}

background(0)で背景色黒を指定し、y = y - 1;で変数yにy -1を再代入。
if文で上記で指定した100pxの位置から1pxずつ線を上に上げていき、heightが1番上の0になるとheight200pxの位置より線をまたスタートさせる。

draw()
setup()の直後に呼び出され、プログラムが停止されるか、noLoop()が呼び出されるまで、継続的にブロックの内部に含まれるコードを実行します。
http://processingjs.org/reference/draw_/

ループ無し

"The noLoop() function causes draw() to only execute once. Without calling noLoop(), draw() executed continually."

draw()が一度だけ実行するようにnoLoop()を設定します。 noLoop()を設定しなければ、draw()は継続的に実行されます。

// All Examples Written by Casey Reas and Ben Fry
// unless otherwise stated.
// The statements in the setup() function 
// execute once when the program begins
void setup() 
{
  size(200, 200);  // Size should be the first statement
  stroke(255);     // Set line drawing color to white
  frameRate(30);
  noLoop();
}

float y = 100;

// The statements in draw() are executed until the 
// program is stopped. Each statement is executed in 
// sequence and after the last line is read, the first 
// line is executed again.
void draw() 
{ 
  background(0);   // Set the background to black
  y = y - 1; 
  if (y < 0) { y = height; } 
  line(0, y, width, y);  
}

解釈

先程のコードとほぼ一緒ですが、noLoop()を設定することで線の動作がなくなります。

noLoop()
draw()がデフォルトで継続的に実行するので、処理を停止させます。loop()が呼び出された場合は、draw()内のコードは、連続して再度実行し始める。
setup()でnoLoop()を使用している場合は、ブロック内の最後の行である必要があります。
http://processingjs.org/reference/noLoop_/

ループ

"The loop() function causes draw() to execute continuously. If noLoop is called in setup() the draw() is only executed once. In this example click the mouse to execute loop(), which will cause the draw() the execute continuously."

loop()は、draw()を継続的に実行させます。 noLoop()がsetup()内で呼び出された場合、draw()は一度だけ実行されます。この例では、マウスをクリックするとloop()が実行するようにしています。

// All Examples Written by Casey Reas and Ben Fry
// unless otherwise stated.
// The statements in the setup() function 
// execute once when the program begins
void setup() 
{
  size(200, 200);  // Size should be the first statement
  stroke(255);     // Set stroke color to white
  noLoop();
}

float y = 100;

// The statements in draw() are run until the 
// program is stopped. Each statement is run in 
// sequence and after the last line is read, the first 
// line is run again.
void draw() 
{ 
  background(0);   // Set the background to black
  line(0, y, width, y);  
  
  y = y - 1; 
  if (y < 0) { 
    y = height; 
  } 
} 

void mousePressed() 
{
  loop();
}

解釈

void setup() 
{
  size(200, 200);  // Size should be the first statement
  stroke(255);     // Set stroke color to white
  noLoop();
}

noLoop()でdraw()の動作を止めています。

void draw() 
{ 
  background(0);   // Set the background to black
  line(0, y, width, y);  
  
  y = y - 1; 
  if (y < 0) { 
    y = height; 
  } 
}

yの再代入を行い、yが0になるまで線を上昇させ、0になると一番下の200pxから再び上昇させる。

void mousePressed() 
{
  loop();
}

クリック時にloop()を呼び出し、上記線の移動を始めるようにする。

loop()
連続するdraw()内のコードを実行するための処理が発生します。
noLoop()が呼び出された場合は、draw()内のコードは実行を停止します。
http://processingjs.org/reference/loop_/

mousePressed()
マウスクリック時にプログラミングの動作を実行させる。
http://processingjs.org/reference/mousePressed_/

再描画

"The redraw() function makes draw() execute once. In this example, draw() is executed once every time the mouse is clicked."

関数がdraw()が一度実行させるredraw()を。マウスがクリックされるたびに一度この例では、draw()が実行されます。

// All Examples Written by Casey Reas and Ben Fry
// unless otherwise stated.
// The statements in the setup() function 
// execute once when the program begins
void setup() 
{
  size(200, 200);  // Size should be the first statement
  stroke(255);     // Set line drawing color to white
  noLoop();
}

float y = 100;

// The statements in draw() are executed until the 
// program is stopped. Each statement is executed in 
// sequence and after the last line is read, the first 
// line is executed again.
void draw() 
{ 
  background(0);   // Set the background to black
  y = y - 1; 
  if (y < 0) { y = height; } 
  line(0, y, width, y);  
} 

void mousePressed() 
{
  redraw();
}

解釈

※マウスクリック時の動作の違い以外、内容が同じなのでコードの大半はほっとく。

void mousePressed() 
{
  redraw();
}

redraw()
1回の操作に対して1度draw()内のコードを実行します。 この機能はmousePressed()やkeyPressed()のような関数を使用することで、draw()内の表示を更新することができます。
http://processingjs.org/reference/redraw_/

関数

"The draw_target() function makes it easy to draw many distinct targets. Each call to draw_target() specifies the position, size, and number of rings for each target."

draw_target()は、簡単に多くの異なる図形を描くことができます。draw_target()を設定する時は、その数の分だけ位置、サイズ、回数を指定します。

// All Examples Written by Casey Reas and Ben Fry
// unless otherwise stated.
void setup() 
{
  size(200, 200);
  background(51);
  noStroke();
  smooth();
  noLoop();
}

void draw() 
{
  draw_target(68, 34, 200, 10);
  draw_target(152, 16, 100, 3);
  draw_target(100, 144, 80, 5);
}

void draw_target(int xloc, int yloc, int size, int num) 
{
  float grayvalues = 255/num;
  float steps = size/num;
  for(int i=0; i<num; i++) {
    fill(i*grayvalues);
    ellipse(xloc, yloc, size-i*steps, size-i*steps);
  }
}

解釈

{
  size(200, 200);
  background(51);
  noStroke();
  smooth();
  noLoop();
}

smooth()を追加。

smooth()
なめらかな縁を持つすべての幾何学形を描画します。これは、アプリケーションのフレームレートが遅くなりますが、視覚的洗練さを生み出します。
http://processingjs.org/reference/smooth_/

void draw() 
{
  draw_target(68, 34, 200, 10);
  draw_target(152, 16, 100, 3);
  draw_target(100, 144, 80, 5);
}

1番大きな円draw_target(68, 34, 200, 10);を例にすると、x座標68px, y座標34px, width・heightを200px, 中心に向かってトーンが10回落ちるように(下記コードで指定)設定しています。

draw_target()
draw_target() は、沢山の図形を描画する目的で作られています。
draw_target() は、円の座標・大きさ・(内側の円の)数を指定することができ、一回呼び出すごとに1つの円が作られます。
http://hkpr.info/processing/sample/Basics/Structure/Functions/

void draw_target(int xloc, int yloc, int size, int num) 
{
  float grayvalues = 255/num;
  float steps = size/num;
  for(int i=0; i<num; i++) {
    fill(i*grayvalues);
    ellipse(xloc, yloc, size-i*steps, size-i*steps);
  }
}

x軸 = xloc, y軸 = yloc, 幅と高さ = size, トーンを落とす回数 = num。
float grayvalues = 255/num;で色の指定。255をnum回数で割る。
float steps = size/num;で楕円の中の各線の太さの指定。
for文でiが各draw_targetで設定したnumの数値になるまで、fill()でグレーを薄くするように色を、ellipse()で一回繰り返す毎に小さくなっていく楕円を繰り返す。
x軸、y軸の変更はしてない。

for()
繰り返しのシーケンスを制御します。
各パートは、セミコロンで区切る必要があります。
http://processingjs.org/reference/for_/

再帰

"A demonstration of recursion, which means functions call themselves. Notice how the drawCircle() function calls itself at the end of its block. It continues to do this until the variable "level" is equal to 1."

これは関数が自分自身を呼び出すことを指すデモです。drawCircle()関数がそのブロックの最後で自分自身を呼び出していることに注目してください。変数levelが1に等しくなるまで連続しています。

// All Examples Written by Casey Reas and Ben Fry
// unless otherwise stated.
void setup() 
{
  size(200, 200);
  noStroke();
  smooth();
  noLoop();
}

void draw() 
{
  drawCircle(126, 170, 6);
}

void drawCircle(int x, int radius, int level) 
{                    
  float tt = 126 * level/4.0;
  fill(tt);
  ellipse(x, 100, radius*2, radius*2);      
  if(level > 1) {
    level = level - 1;
    drawCircle(x - radius/2, radius/2, level);
    drawCircle(x + radius/2, radius/2, level);
  }
}

解釈

void draw() 
{
  drawCircle(126, 170, 6);
}

drawCircle(位置、サイズ、楕円の繰り返し回数)

void drawCircle(int x, int radius, int level) 
{                    
  float tt = 126 * level/4.0;
  fill(tt);
  ellipse(x, 100, radius*2, radius*2);      
  if(level > 1) {
    level = level - 1;
    drawCircle(x - radius/2, radius/2, level);
    drawCircle(x + radius/2, radius/2, level);
  }
}

float tt = 126 * level/4.0;fill(tt);で色を指定、ellipse(x, 100, radius*2, radius*2);で座標位置、楕円を指定。
ブロック内、if文でlevel(上記drawCircle()で設定した6)が1になるまで処理を繰り返す設定をし、中でlevelから1を引いて、その数の楕円を描く設定をdrawCircle(x - radius/2, radius/2, level);drawCircle(x + radius/2, radius/2, level); を行う。

再帰2

※上記「再帰」記述内容と同じのため省略

// All Examples Written by Casey Reas and Ben Fry
// unless otherwise stated.
void setup() 
{
  size(200, 200);
  noStroke();
  smooth();
  drawCircle(100, 100, 80, 8);
}

void drawCircle(float x, float y, int radius, int level) 
{                    
  float tt = 126 * level/6.0;
  fill(tt, 153);
  ellipse(x, y, radius*2, radius*2);      
  if(level > 1) {
    level = level - 1;
    int num = int(random(2, 6));
    for(int i=0; i<num; i++) {
      float a = random(0, TWO_PI);
      float nx = x + cos(a) * 6.0 * level;
      float ny = y + sin(a) * 6.0 * level;
      drawCircle(nx, ny, radius/2, level);
    }
  }
}

解釈

fill(tt, 153);

153は透過度。

void drawCircle(float x, float y, int radius, int level) 
{                    
  float tt = 126 * level/6.0;
  fill(tt, 153);
  ellipse(x, y, radius*2, radius*2);      
  if(level > 1) {
    level = level - 1;
    int num = int(random(2, 6));
    for(int i=0; i<num; i++) {
      float a = random(0, TWO_PI);
      float nx = x + cos(a) * 6.0 * level;
      float ny = y + sin(a) * 6.0 * level;
      drawCircle(nx, ny, radius/2, level);
    }
  }
}

"TWO_PIは6.28318530717958647693の値をもつ数学的な定数である。直径における円の円周率である。三角関数sin() とcos()と組み合わせると便利である。"

random
乱数の生成を行います。random()が呼び出される度に指定された範囲内でランダムな値を返します。
randomu(5)は0〜5の値を返します。 random(low, high)で最低値と最高値を決めることができます。 http://processingjs.org/reference/random_/

グラフィック作成

"The createGraphics() function creates an object from the PGraphics class (PGraphics is the main graphics and rendering context for Processing). The beginDraw() method is necessary to prepare for drawing and endDraw() is necessary to finish. Use this class if you need to draw into an off-screen graphics buffer or to maintain two contexts with different properties."

createGraphics()関数は、PGraphics class(CreateGraphics()の処理に必要なグラフィックスとレンダリングコンテキスト)からオブジェクトを作成します。 beginDraw()メソッドは、描画の開始と終了のための準備として必要です。あなたはオフスクリーングラフィックスバッファに描画したり、異なる特性を持つ2つのコンテキストを維持する必要がある場合はこのクラスを使用します。

// All Examples Written by Casey Reas and Ben Fry
// unless otherwise stated.
PGraphics pg;

void setup() {
  size(200, 200);
  pg = createGraphics(80, 80, P3D);
}

void draw() {
  fill(0, 12);
  rect(0, 0, width, height);
  fill(255);
  noStroke();
  ellipse(mouseX, mouseY, 60, 60);
  
  pg.beginDraw();
  pg.background(102);
  pg.noFill();
  pg.stroke(255);
  pg.ellipse(mouseX-60, mouseY-60, 60, 60);
  pg.endDraw();
  
  image(pg, 60, 60); 
}

解釈

PGraphics
メイングラフィックスとレンダリングコンテキストと同様に、 processing.jsの中核を処理するための基本APIの実装をします。
オフスクリーングラフィックスバッファに描画する必要がある場合は、このクラスを使用します。
PGraphicsオブジェクトはCreateGraphics()を使って構築することができます。
http://processingjs.org/reference/PGraphics/

createGraphics()
P2D、P3D、JAVA2Dの新しいPGraphicsオブジェクトを返し、作成します。 P2Dはまだ実装されていませんが、将来のリリースで利用が可能になります。
オフスクリーングラフィックスバッファに描画する必要がある場合はこのクラスを使用します。
画面外使用が許可されていないので、OpenGLでCreateGraphics()を使用することはできません。
DXFとPDFのレンダラーは、filenameパラメータを必要とします。 http://processingjs.org/reference/createGraphics_/