2019プログラミング講座7:移動、回転、伸縮

Processingで描画することができるオブジェクトにはそれぞれ座標が存在します。Processingの実行ウィンドウの座標(グローバル座標)は常に左上が座標の原点になりますが、個々のオブジェクトの座標(ローカル座標)は移動、回転、伸縮することができます。

座標の移動
それでは、まず座標の移動について解説します。はじめに座標の移動を実行せずに図形を描画します。

void setup(){
  size(400,400);
}

void draw(){
  rect(0,0,50,50);
}

このプログラムでは図形(正方形)の原点(図形の左上)をX座標=0,Y座標=0(以下(0,0)と記述)としているため、実行ウィンドウの左上から描画されています。

次に図形(正方形)のローカル座標をtranslate()関数を使って移動させてみましょう。

void setup(){
  size(400,400);
}

void draw(){
  translate(200,200);
  rect(0,0,50,50);
}

上のコードでは図形(正方形)の座標は(0,0)であるにも関わらず、実際に図形が描画される位置はtranslate()関数によって実行ウィンドウ上の(200,200)の位置に移動しています。

更に、複数のtranslate()関数を使った例を見てみましょう。

void setup(){
  size(400,400);
}

void draw(){
  background(0);
  translate(mouseX,mouseY);
  rect(0,0,50,50);
  translate(50,50);
  rect(0,0,25,25);
}

上のコードでは、複数のtranslate()関数の効果が合成されることが確かめられます。

座標の回転
図形のローカル座標を回転させるためにはrotate()関数を使用します。rotate()関数のパラメータは1つだけで、回転角(ラジアン)を指定します。
それでは、図形の座標を回転させてみましょう。

void setup(){
  size(160,160);
}

void draw(){
  background(0);
  rotate(mouseX/100.0);
  rect(0,0,160,20);
}

上のコードではrotate()関数を使って図形を回転しています。回転角(ラジアン)は0〜360度までを0〜約6.28の数値で表します。このコードではX座標を100.0で割ることで回転角(ラジアン)に変換しています。

座標の伸縮
座標を伸縮させるには、scale()関数を使用します。scale(2)とすると画面内の図形はすべて2倍の大きさになります。scale(0.5)とすると、図形はすべて半分の大きさになります。
それでは、以下のコードで確認してみましょう。

void setup(){
  size(400,400);
}

void draw(){
  rect(0,0,100,100);
  scale(0.5);
  rect(0,200,100,100);
  scale(4);
  rect(0,100,100,100);
}

座標の復元
座標系の変換(移動、回転、伸縮)は、変換後のすべてのコードに影響を及ぼしますが、その影響の範囲を限定し、変換以前の状態に復元することができます。pushMatrix()関数とpopMatrix()関数を使うことで変換した座標の復元ができます。pushMatrix()関数を実行すると、それ以降に記述した座標系変換の情報が記録され、popMatrix()が使われると変換前の座標系に戻ります。pushMatrix()関数とpopMatrix()関数は常にペアで使う必要があります。
それでは、以下のコードを使って確認してみましょう。

void setup(){
  size(400,400);
}

void draw(){
  background(0);
  pushMatrix();
  translate(mouseX,mouseY);
  ellipse(0,0,50,50);
  popMatrix();
  ellipse(200,200,200,200);
}

上のコードでは1つめの図形(円)の座標系の移動をマウスの座標に合わせていますが、pushMatrix()関数とpopMatrix()関数を使って、座標系の移動が復元されるため、2つめの円は座標系の移動の影響を受けません。

練習課題07:
以下の条件を全て満たす作品を作成してください。
・固定された座標を持つ図形が表示されていること。
・マウスの動きによって変化する図形が表示されること。
・マウスの動きによって色(背景色や図形の色)が変化すること。

2019プログラミング講座6:色

カラーモードについて
Processingで色を表現するためにはカラーモデルを使って色を指定する必要があります。Processingで用いられるカラーモデルにはRGBモデルとHSBモデルがあります。

RGBモデルは、Red (赤)、Green (緑)、Blue (青) の三つの原色を混ぜて色を再現する加法混合の一種です。

HSBモデルはHue(色相)、Saturation(彩度)、Brightness(明度)の三つの成分から色を再現する方法です。

Processingでは、カラーモードを指定することで、RGBモデルとHSBモデルのいずれのカラーモデルを選ぶことができます。カラーモードは、以下のように設定します。

colorMode(mode, range1, range2, range3, range4);

mode  RGBまたはHSB
range  色を指定する値の範囲(intまたはfloat):省略可
range1 赤または色相の範囲(intまたはfloat):省略可
range2 緑または彩度の範囲(intまたはfloat):省略可
range3 青または明度の範囲(intまたはfloat):省略可
range4 透明度の範囲(intまたはfloat) :省略可

ProcessingのデフォルトのカラーモデルはRGBモデルになるため、RGBモデルで各色256段階の範囲で指定する場合は特にcolorMode()関数を使用する必要はありません。

色の設定について
Processingでは、背景の色、図形の線の色、図形の面の色をそれぞれ設定することができます。色を設定するための関数を以下に記載します。

背景の色
background(R,G,B);

線の色
stroke(R,G,B);

面の色
fill(R,G,B);

上記の関数のR,G,Bは色を表すパラメータで、R(Red:赤)、G(Green:緑)、B(Blue:青) の三つの原色を表しており、それぞれ0〜255までの数値で色を指定します。
0は色の最小値でそれぞれの色の成分が表示されません。255は色の最大値となります。

例:R, G, Bが0, 0, 0なら黒、255,0,0なら赤、255,255,255なら白

Processingでは色の選択に使えるツールが備わっています。メニューからTools>Color Selectorを選んで下記のウィンドウを表示し、カラーパレットから色を選択すると、RGB, HSBそれぞれの色の数値やカラーコードが表示されるので、この数値を参考にコード上の数値を記述します。

背景の色を設定する
背景の色を設定してみましょう。背景の色を設定するには、background()関数を使用します。

background(255,0,0);

*background()関数をsetup()関数内で使用するか、draw()関数内で使用するかによって完成するアプリケーションの動作に違いが生じるので注意が必要です。

線の色を設定する
基本図形の線の色を設定してみましょう。線の色を設定するにはstroke()関数を使用します。
また、線を描画しない場合にはnoStroke()関数を使用します。

size(400,400);
background(0);
stroke(255,0,0);
ellipse(100,200,100,100);
noStroke();
ellipse(300,200,100,100);

面の色を設定する
基本図形の面の色を設定してみましょう。面の色を設定するにはfill()関数を使用します。
また、面を描画しない場合にはnoFill()関数を使用します。

size(400,400);
background(255);
fill(255,0,0);
ellipse(150,200,300,300);
noFill();
ellipse(250,200,300,300);

透明度を設定する
図形の面の色や線の色を指定するstroke()関数やfill()関数に、透明度を設定する四つ目のパラメータを加えることで図形の透明度を設定できます。このパラメータをアルファ値と呼びます。

線の透明度設定:
stroke(R,G,B,alpha);

面の透明度設定:
fill(R,G,B,alpha);

アルファ値の値の範囲は0から255で、0にすると完全に透明になり(表示されない)、255にすると完全に不透明になります(アルファ値を指定しない場合と同じ)。
1から254までの値の範囲では半透明になり、下の色と混ざり合った透けた色が表現できます。

size(400,400);
background(255);
stroke(255,0,0,125);
fill(7,165,247,200);
ellipse(150,200,300,300);
stroke(0,255,0,100);
fill(247,7,216,200);
ellipse(250,200,300,300);
練習課題06:基本図形と色の設定を使用してグラフィック作品を作成してください。画面サイズは幅800ピクセル、高さ800ピクセルとします。

2019プログラミング講座5:基本的な図形の描画

Processingには、あらかじめ基本的な図形を描く関数が用意されています。以下に基本的な図形の描画方法を記載します。


point(x座標, y座標);


2つの座標(x座標1, y座標1)と(x座標2, y座標2)を結ぶ1本の直線を描きます。
line(x座標1, y座標1, x座標2, y座標2);

方形
方形(正方形や長方形)は、4つのパラメータで設定します。方形の左上の角を基準点にx座標, y座標で指定し、幅と高さを指定します。
rect(x座標, y座標, 幅, 高さ);

円形
円形(正円や楕円)は、4つのパラメータで設定します。円形の中心を基準点にx座標, y座標で指定し、幅と高さを指定します。
ellipse(x座標, y座標, 幅, 高さ);

三角形
三角形は6つのパラメータを指定して描きます。
triangle(x座標1, y座標1, x座標2, y座標2, x座標3, y座標3);

四辺形
四辺形は8つのパラメータを指定して描きます。
quad(x座標1, y座標1, x座標2, y座標2, x座標3, y座標3, x座標4, y座標4);

描線の太さ
図形の描線の太さを変更できます。描線のデフォルトは1ピクセルですが、strokeWeight()関数を使って変更できます。strokeWeight()関数のパラメータは1つで、太さをピクセル数で指定します。
以下のように記述します。

size(400,400);
strokeWeight(8);
ellipse(200,200,200,200);

描画の順序
プログラムはコードの先頭1行目から順に読み込まれていくため、コードを書く順番は図形の重なり順などに大きく影響します。
重なり合う複数の図形がある場合は、最後に描かれた図形が一番上に重なって表示されます。

描画モード
図形を描画する際に、描画の基準点を設定することができます。
方形の記述ではrectMode()関数を使用して以下のように基準点を設定できます。

rectMode(CORNER) rect(左上頂点のx座標, 左上頂点のy座標, 幅, 高さ); //デフォルトではこの基準点を使う
rectMode(CORNERS) rect(左上頂点のx座標, 左上頂点のy座標, 右下頂点のx座標, 右下頂点のy座標);
rectMode(CENTER) rect(中心のx座標, 中心のy座標, 幅, 高さ);
rectMode(RADIUS) rect(中心のx座標, 中心のy座標, 幅の半分, 高さの半分);

円形の記述ではellipseMode()関数を使用して以下のように基準点を設定できます。

ellipseMode(CENTER) ellipse(中心のx座標, 中心のy座標, 幅(直径), 高さ(直径)); //デフォルトではこの基準点を使う
ellipseMode(RADIUS) ellipse(中心のx座標, 中心のy座標, 幅(半径), 高さ(半径));
ellipseMode(CORNER) ellipse(円が収まる四角い領域の左上角のx座標, 円が収まる四角い領域の左上角のy座標, 幅(直径), 高さ(直径));
ellipseMode(CORNERS) ellipse(円が収まる四角い領域の左上角のx座標, 円が収まる四角い領域の左上角のy座標, 円が収まる四角い領域の右下角のx座標, 円が収まる四角い領域の右下角のy座標);

コードは以下のように記述します。

size(400,400);
rect(100,50,80,80);
ellipse(100,50,80,80);
ellipseMode(CORNER);
rect(200,50,80,80);
ellipse(200, 50, 80, 80);
練習課題05: 幅400ピクセル、高さ400ピクセルの画面に基礎図形を描画してみよう。

2019プログラミング講座4:画面サイズと座標

画面サイズの設定
Processingでは、画面(実行ウィンドウ)のサイズを以下の関数*を使用して設定することができます。

size(画面の幅, 画面の高さ);

*関数とはプログラミングの構成単位であり、パラメータと呼ばれる数値などで定義することができます。

それでは、幅800ピクセル*、高さ600ピクセル*のウィンドウを以下のようにテキストエディタに記述して作成してみましょう。

size(800,600);

*パラメータで扱う単位はコンピュータの画面上で画像を扱う際の最小単位であるピクセル(Pixcel)です。
座標について
座標とは空間上の1点を指定するための方法です。画面に図形を描くためには、図形の位置を決める必要があり、座標を利用します。Processingの画面(実行ウィンドウ)では以下のようにして画面上の1点を指定します。

画面の左上を基準点とし右に移動した距離xと下に移動した距離yで1点を指定する。

それでは、サイズが幅400ピクセル、高さ400ピクセルの画面(実行ウィンドウ)を作成し、x座標が200ピクセル、y座標が200ピクセルの位置に点を描画してみましょう。

点の描画にはpoint()関数を用います。
point(x座標,y座標);

size(400,400);
point(200,200);

練習課題04: ・数値を変えて様々なサイズの画面(実行ウィンドウ)を作成してみよう。
       ・幅400ピクセル、高さ400ピクセルの画面(実行ウィンドウ)の四隅に点を描画してみよう。

2019プログラミング講座3:Processingのストラクチャー(構造)

Processingにおいて時間の経過とともに変化するグラフィックスを作成する場合には、Processingのストラクチャーを学び、効果的に利用することが必要になります。

それでは、まず以下のコードを記述してみましょう。

int x = 10;
int y = 10;
int w = 20;
int h = 20;

void setup(){
  size(400,400);
}

void draw(){
  ellipse(x+frameCount, y+frameCount, 20, 20);
}

記述したコードを実行してみましょう。
以下のように円が対角線上を移動するグラフィックスが表示されます。

このコードをもとにprocessingのストラクチャーについて学んでいきましょう。

このプログラムは以下の3つの部位で成り立っています。

1)グローバル変数の宣言と初期化
グローバル変数とは以下に説明する関数(setup関数とdraw関数)などから参照することができる変数の一種です。

int x = 10;
int y = 10;
int w = 20;
int h = 20;

2)setup関数
各種初期化で行う処理部分。アプリケーションが実行され、ウィンドウが開いたとき、最初に1度だけ実行されます。
setup関数では、画面(ウィンドウ)のサイズを決定するsize関数などの記述を行います。

void setup() {

// 一度だけ実行される処理

}

3)draw関数
アプリケーションが実行中に繰り返し実行し続ける処理部分。draw関数内に記述されたコードが終了するたびに新しいフレームがディスプレイ・ウィンドウに描画されコードが実行され続ける。
デフォルトの描画速度は1秒あたり60フレーム( 1秒あたりのフレーム数はframeRate関数を使って変更することができる)。

void draw() {

// 繰り返し実行される処理

}

練習課題03:
上のコードの記述を変更して、様々なプログラムを作ってみましょう。
例)
・円が水平または垂直に移動するプログラム。
・円の大きさが変化するプログラム。

2019プログラミング講座2:Processingのコードを書いてみよう

プログラミング最初の一歩

プログラミングの動作を記述する一連の文字のことをコード(ソースコード)と呼びます。Processingでは開発環境のウィンドウ[図1]を開いて、その中でコードを記述していきます。

図1 Processingの開発環境ウィンドウ

コードはProcessingの開発環境ウィンドウのテキストエディタの中に書き込んでいきます。それでは、最初のプログラムを作成してみましょう。以下のコードを記述してください。

ellipse(50, 50, 80, 80);

コードが書けたら開発環境ウィンドウの実行ボタンを押してプログラムを実行してみましょう。以下のように円が描画できていれば最初のプログラムの完成です。

円あるいは楕円を描画するためには以下のようにコードを記述します。

ellipse(中心のX座標, 中心のY座標, 楕円の幅, 楕円の高さ);

先ほど描画した楕円(円)は、中心のX座標、Y座標がそれぞれ50ピクセル、幅と高さが80ピクセルの楕円(円)でした。
実行中のプログラムは開発環境ウィンドウの停止ボタンを押して停止させます。

プログラミングの保存
Processingでは作成するプログラミングのことをスケッチと呼びます。それでは、スケッチを保存してみましょう。「ファイル」メニューの「保存」コマンドを選択すると、Processingの開発環境のソフトウェアと同じ場所にあるsketchbookというフォルダに作成されたスケッチが保存されます。
この授業(愛知淑徳大学創造表現学部の実習授業)では「ファイル」メニューから「名前をつけて保存…」コマンドを選択し、「名前:」と書かれた欄に任意の名称を入力し、「場所:」と書かれたプルダウンメニュー内の選択肢から「デスクトップ」を選んで保存するようにしてください。

新しいスケッチの作成を始める
新しいスケッチを作成するときは「ファイル」メニューから「新規」コマンドを選択します。そうすると空のウィンドウが表示されます。

練習課題02: 数値を変えて描画の位置、幅、高さが異なる様々な楕円を描画してみよう。

2019プログラミング講座1: Processingについて

本講座ではプログラミングを学習するための環境としてProcessing[図1]を使用します。

図1 Processingのウェブサイト

Processingはグラフィックスをプログラムで生成するうえで困難な各種設定などを必要とせず、コーディングに専念できるという特長があります。
また、Processingはグラフィックスだけでなく、音声や動画なども扱うことができ、それらを組み合わせてインタラクティブ(双方向性のある)な表現を可能にしてくれます。

それでは最初にProcessingがどういう経緯で制作されたプログラミング環境なのかを解説します。

Processingは当時マサチューセッツ工科大学メディアラボに在籍していたCasey ReasとBen Fryによって2001年に誕生しました。
その後2002年から2008年まで開発が続き、2008年秋からバージョン1.0がリリースされ、2013年にはバージョン2.0が、つづく2015にはバージョン3.0がリリースされ現在に至っています。
ProcessingはJava(Java日本語サイト)というプログラミング言語の環境を活用してグラフィック機能などに特化したものだと言えます。

Processingの作者であるCasey ReasとBen Fryは著書「Processingをはじめよう」の中で影響を受けた先行するプログラミング環境をあげています。
ひとつはLOGO(LOGOファウンデーション)で、教育のために開発されたプログラミング環境でした。この言語は児童の発達心理学の成果などが活かされており子どもが思考するための道具としての工夫がなされていました。
ふたつめはDesign By Numbers(公式サイト)で、この言語はマサチューセッツ工科大学メディアラボのJohn Maedaによって開発されました。Design By Numbersはデザイナーやアーティストといったプログラミングを専門としていない人でもプログラミングが可能となる環境を目指して作られており、数値によるグラフィックデザインの研究や教育に使われました。

上のような先行するプログラミング環境の思想や特徴の影響を色濃く受けたProcessingは、初心者にもわかりやすく、特にアーティストやデザイナーなどが創造や表現のためにプログラミングを使うことを学ぶ最初の一歩を踏み出すのに最適な言語です。

練習課題01: Processingのサイトを閲覧してみよう。

2019プログラミング講座スケジュール

本講座のスケジュールを記載します。

まず、各回に記載している練習課題の制作をすすめてください。第7回では練習課題の講評を実施します。

第7回以降は総合課題として、より複雑な制作に挑んでもらいます。練習課題で取り上げた技術がベースになりますので、第7回までの内容について理解を深めておくようにしてください。第15回では総合課題の講評を実施します。

01: processingの基本
02: 描画(基本図形、色、座標)
03: 変数
04: 条件分岐
05: 繰り返し
06: 外部データの使用(画像、サウンド、動画)
07: 練習課題講評
08: 総合課題1 お絵かきソフトのインターフェイスデザイン
09: 総合課題2 サウンドのビジュアライズ
10: 総合課題3 ビデオコントロールのインターフェイスデザイン
11: 総合課題4 ARを活用した作品制作
12: 制作
13: 制作
14: 制作
15: 総合課題講評

課題提出:2020年1月29日(水)まで

提出方法:共有フォルダに提出(詳細は授業内で告知します)

評価:
1 技術修得回での小課題の制作(25%)練習課題
2 課題を制作する(40%)総合課題
3 講評を受ける(20%)練習課題講評+総合課題講評
4 授業内での積極的制作活動:特に企画報告や進捗状況報告を評価します。(15%)
*注意:課題提出だけを実施し講評会に出席しない場合は講評点(20点)が減点になります。

2018プログラミング講座16:乱数と生成的なグラフィック表現

生成される予測できない数列の要素を乱数と呼びます。Processingではrandom()関数を使って乱数を擬似的に生成することができます。

ランダムな線の描画
random()関数は呼び出すたびに異なる数値を返します。パラメータで値の上限あるいは値の範囲を指定することができます。たとえばrandom(10)とすると、0以上、10未満の乱数が生成されます。生成される数値は浮動小数点になるため、変数は float型を使います。
それでは、乱数を使って線を描画してみましょう。線の配色も乱数で生成しています。

void setup(){
   size(400, 400);
   background(255);
}

void draw(){
  for(int i = 0; i < 100; i++){
    stroke(random(255), random(255), random(255));
    line(random(width), random(height), random(width), random(height));
  }
}

ランダムな円の描画
次に円を乱数を使って描画してみましょう。

float speed = 5;
float x = 200;
float y = 200;

void setup(){
   size(400, 400);
   background(255);
}

void draw(){
    x += random(-speed, speed);
    y += random(-speed, speed);
    noStroke();
    fill(random(255), random(255), random(255));
    ellipse(x, y, 100, 100);
}

これらのグラフィックは、コードが実行されるたびに、その実行結果が異なることに気がついたでしょうか。
コードに規則を与えることで、予測は可能だが確定的ではないグラフィックスなどを生成することができます。

ジェネラティブなグラフィック表現
ここからは、参考書籍「ジェネラティブ・アート Processingによる実践ガイド マット・ピアソン著」を参考にコードを記述していきましょう。

円の描画
まずは、これまでどうりの方法で円を描いてみましょう。

float radius = 200;
int centerx = 400;
int centery = 400;

void setup(){
  size(800,800);
  background(255);
  strokeWeight(2);
  smooth();
}

void draw(){
  stroke(200, 200, 200);
  noFill();
  ellipse(centerx, centery, radius*2, radius*2);
}

円を描画する別の方法
次に三角関数を用いて点で円を描いてみましょう。

float radius = 200;
int centerx = 400;
int centery = 400;
float x, y;
float lastx = -999;
float lasty = -999;
float ang;
float rad; 

void setup(){
  size(800,800);
  background(255);
  strokeWeight(2);
  smooth();
}

void draw(){
  stroke(0, 0, 0);
  for(ang = 0; ang <= 360; ang += 2){
    rad = radians(ang);
    x = centerx + (radius * cos(rad));
    y = centery + (radius * sin(rad));
    point(x,y);
  }
}

円かららせんを描画する
円のコードをもとにして、らせんを描いてみましょう。

float radius = 10;
int centerx = 400;
int centery = 400;
float x, y;
float lastx = -999;
float lasty = -999;
float ang;
float rad; 

void setup(){
  size(800,800);
  background(255);
  strokeWeight(2);
  smooth();
}

void draw(){
  stroke(0, 0, 0);
  for(ang = 0; ang <= 1440; ang += 2){
    radius += 0.5;
    rad = radians(ang);
    x = centerx + (radius * cos(rad));
    y = centery + (radius * sin(rad));
    point(x,y);
  }
}

らせんを線で描画する
らせんを点ではなく線で描きましょう。

float radius = 10;
int centerx = 400;
int centery = 400;
float x, y;
float lastx = -999;
float lasty = -999;
float ang;
float rad; 

void setup(){
  size(800,800);
  background(255);
  strokeWeight(0.5);
  smooth();
}

void draw(){
  stroke(0, 0, 0);
  for(ang = 0; ang <= 1440; ang += 2){ radius += 0.5; rad = radians(ang); x = centerx + (radius * cos(rad)); y = centery + (radius * sin(rad)); if(lastx > -999){
      line(x, y, lastx, lasty);
    }
    lastx = x;
    lasty = y;
    lasty = y;
  }
}

らせんの線にノイズを加える
線にノイズを加えることで手書きの描線のようなゆらぎが現れます。

float radius = 10;
int centerx = 400;
int centery = 400;
float x, y;
float lastx = -999;
float lasty = -999;
float ang;
float rad; 
float radiusNoise;
float thisRadius;

void setup(){
  size(800,800);
  background(255);
  strokeWeight(0.5);
  smooth();
}

void draw(){
  stroke(0, 0, 0);
  radiusNoise = random(10);
  for(ang = 0; ang <= 1440; ang += 5){ radiusNoise += 0.05; radius += 0.5; thisRadius = radius + (noise(radiusNoise) * 200)-100; rad = radians(ang); x = centerx + (thisRadius * cos(rad)); y = centery + (thisRadius * sin(rad)); if(lastx > -999){
      line(x, y, lastx, lasty);
    }
    lastx = x;
    lasty = y;
  }
}

らせんに乱数を加え複数重ねて描画する
らせんの描線に乱数を加えながら複数のらせんを重ねて描いてみましょう。

float radius;
int centerx = 400;
int centery = 400;
float x, y;
float lastx;
float lasty;
float ang;
float rad; 
float radiusNoise;
float thisRadius;
int startangle;
int endangle;
int anglestep;

void setup(){
  size(800,800);
  background(255);
  strokeWeight(0.5);
  smooth();
}

void draw(){
  for(int i = 0; i < 100; i++){
    lastx=-999;
    lasty=-999;
    radius = 10;
    stroke(random(255), random(255), random(255),50);
    startangle = int(random(360));
    endangle = 1440 + int(random(1440));
    anglestep = 5 + int(random(3));
    radiusNoise = random(10);
    for(ang = startangle; ang <= endangle; ang += anglestep){ radiusNoise += 0.05; radius += 0.5; thisRadius = radius + (noise(radiusNoise) * 200)-100; rad = radians(ang); x = centerx + (thisRadius * cos(rad)); y = centery + (thisRadius * sin(rad)); if(lastx > -999){
        line(x, y, lastx, lasty);
      }
      lastx = x;
      lasty = y;
    }
  }
}
総合課題4:
乱数を用いたグラフィック作品を5点、作成する。

2018プログラミング講座15:パーティクル

パーティクル(particle)とは運動する粒子で表現される事象のことで、コンピューターグラフィックスでは、光、炎、水などの現象を表現するのに用いられています。今回はprocessingを用いたパーティクルの表現を学びます。またオブジェクト指向プログラミングのための、クラス構文(以下、クラス)についても学んでいきましょう。

クラスの定義
クラスとは型のようなもので、そこで定義された内容をもとに複数の実体=インスタンスを作成することができます。クラスは以下のように記述します。クラス名は慣例的に大文字で始めます。

class Mediaproduce {
  //初期化用メソッド(コンストラクタ) 
  Mediaproduce ( ) {
    
  }

  //更新用メソッド
 void update() {

 }

  //表示用メソッド
  void display() {

 }
 
}

パーティクルを表示するコード
ひとつの型から複数の実体を生成するというクラスの特徴を活用して、パーティクルを生成するオブジェクト指向プログラムを作成してみましょう。

ArrayList<ParticleSystem> systems;

void setup() {
  size(800, 800);
  systems = new ArrayList<ParticleSystem>();
}

void draw() {
  background(0);
  for (ParticleSystem ps: systems) {
    ps.run();
    ps.addParticle();
  }
}

void mousePressed() {
  systems.add(new ParticleSystem(1, new PVector(mouseX, mouseY)));
}

class CrazyParticle extends Particle {
  float theta;
  CrazyParticle(PVector l) {
    super(l);
    theta = 0.0;
  }

  void update() {
    super.update();
    float theta_vel = (velocity.x * velocity.mag()) / 10.0f;
    theta += theta_vel;
  }

}

class Particle {
  PVector location;
  PVector velocity;
  PVector acceleration;
  float lifespan;

  Particle(PVector l) {
    acceleration = new PVector(0.00,-0.05); //パーティクル生成の方向
    velocity = new PVector(random(-1,1),random(-2,0));
    location = l.get();
    lifespan = 300.0; //パーティクル生成の上限
  }

  void run() {
    update();
    display();
  }

  void update() {
    velocity.add(acceleration);
    location.add(velocity);
    lifespan -= 2.0;
  }

  void display() {
    stroke(255,0,0,lifespan); //パーティクルの線の色
    fill(255,0,0,lifespan); //パーティクルの塗り色
    ellipse(location.x,location.y,2,2); //パーティクルで生成される図形
  }

  boolean isDead() {
    return (lifespan < 0.0);
  }

}

class ParticleSystem {

  ArrayList<Particle> particles;
  PVector origin;
  
  ParticleSystem(int num, PVector v) {
    particles = new ArrayList<Particle>();
    origin = v.get();
    for (int i = 0; i < num; i++) {
      particles.add(new Particle(origin));
    }
  }


  void run() {
    for (int i = particles.size()-1; i >= 0; i--) {
      Particle p = particles.get(i);
      p.run();
      if (p.isDead()) {
        particles.remove(i);
      }
    }
  }

  void addParticle() {
    Particle p;
    if (int(random(0, 2)) == 0) {
      p = new Particle(origin);
    } 
    else {
      p = new CrazyParticle(origin);
    }
    particles.add(p);
  }

  void addParticle(Particle p) {
    particles.add(p);
  }

  boolean dead() {
    return particles.isEmpty();
  }
}
総合課題3:
パーティクルを用いたグラフィックスを作成する。
画面のサイズは自由とする。
以下の項目を用いて独自の作品を制作する。
・背景に画像を使用する(写真やイラストなど)。
・パーティクルの粒子のサイズを変更する。
・パーティクルの生成方向を変更する。
・パーティクルの配色を変更する。