Home> 2011-bアーカイブ
2011-bの最近のブログ記事
b-11 3Dの座標を使う
- 2011年12月12日 14:40
- 2011-b
3Dの回転(x軸, y軸, z軸)
2Dの回転をもとに動きを付けてみる
void setup() {
size(100, 100);
rectMode(CENTER);
}
void draw() {
background(0);
translate(width/2, height/2);
rotate(frameCount*PI/60);
rect(0, 0, width/2, height/2);
}
x軸 rotateX
void setup() {
size(100, 100, P3D);
rectMode(CENTER);
}
void draw() {
background(0);
translate(width/2, height/2);
rotateX(frameCount*PI/60);
rect(0, 0, width/2, height/2);
}
y軸 rotateY
void setup() {
size(100, 100, P3D);
rectMode(CENTER);
}
void draw() {
background(0);
translate(width/2, height/2);
rotateY(frameCount*PI/60);
rect(0, 0, width/2, height/2);
}
矩形の描画位置を変更した場合
void setup() {
size(100, 100, P3D);
rectMode(CENTER);
}
void draw() {
background(0);
translate(width/2, height/2);
rotateY(frameCount*PI/60);
rect(width/2, 0, width/2, height/2);
}
z軸 rotateZ
void setup() {
size(100, 100, P3D);
rectMode(CENTER);
}
void draw() {
background(0);
translate(width/2, height/2);
rotateZ(frameCount*PI/60);
rect(0, 0, width/2, height/2);
}
x軸, y軸の両方
void setup() {
size(100, 100, P3D);
rectMode(CENTER);
}
void draw() {
background(0);
translate(width/2, height/2);
rotateX(frameCount*PI/60);
rotateY(frameCount*PI/60);
rect(0, 0, width/2, height/2);
}
3Dの移動
z軸方向に移動したい場合は、translate関数の引数を1つ追加する。
void setup() {
size(100, 100, P3D);
rectMode(CENTER);
}
void draw() {
background(0);
translate(width*2/5, height/2);
rotateY(PI/6);
for (int i = 0; i < 5; i++) {
pushMatrix();
translate(0, 0, i*10);
rotateZ(frameCount*(i+1)*PI/600);
fill(255, 51);
rect(0, 0, width/2, height/2);
popMatrix();
}
}
3Dのオブジェクトを描画する
直方体 box
void setup() {
size(100, 100, P3D);
}
void draw() {
background(0);
translate(width/2, height/2);
rotateY(frameCount*PI/60);
box(40, 30, 20); // 幅, 高さ, 奥行きの順。引数を1つにすると立方体になる。
}
球 sphere
lights関数を用いると光が当たっている状態をシミュレートできる。
void setup() {
size(100, 100, P3D);
}
void draw() {
background(0);
lights();
translate(width/2, height/2);
rotateY(frameCount*PI/120);
translate(50, 0);
noStroke();
sphere(10); //半径30pxの球
}
- Comments (Close): 0
- TrackBack (Close): 0
b-10 オブジェクト指向プログラミング (OOP)
- 2011年12月 5日 14:40
- 2011-b
オブジェクト指向プログラミングとは? → オブジェクト指向プログラミング - Wikipedia
オブジェクト指向プログラミングでプログラムを書く
円を描くプログラムを、オブジェクト指向プログラミングで書いてみる。
step. 0 これまでの書き方
float x, y, diameter; // x座標, y座標, 直径
void setup() {
x = 25;
y = 50;
diameter = 30;
}
void draw() {
ellipse(x, y, diameter, diameter);
}
step. 1 クラスを定義する
Spot sp; //オブジェクトを宣言
void setup() {
sp = new Spot(); //オブジェクトを生成(構築)
sp.x = 25; //属性(プロパティ)に値を代入。以下同様
sp.y = 50;
sp.diameter = 30;
}
void draw() {
ellipse(sp.x, sp.y, sp.diameter, sp.diameter);
}
//Spotクラスを定義
class Spot {
//属性を定義
float x, y, diameter; // x座標, y座標, 直径
}
※「Spot」は、関数を自分で定義したときのように、適切な名前を考えて付ける。その属性も同様。
step. 2 クラスにメソッド(method)の定義を追加する
Spot sp; //オブジェクトを宣言
void setup() {
sp = new Spot(); //オブジェクトを生成(構築)
sp.x = 25; //属性(プロパティ)に値を代入。以下同様
sp.y = 50;
sp.diameter = 30;
}
void draw() {
sp.display();
}
//Spotクラスを定義
class Spot {
//属性を定義
float x, y, diameter; // x座標, y座標, 直径
//表示するメソッドを定義
void display() {
ellipse(x, y, diameter, diameter);
}
}
step. 3 クラスにコンストラクタ(constructor)の定義を追加する
Spot sp; //オブジェクトを宣言
void setup() {
sp = new Spot(25, 50, 30); //オブジェクトを生成(構築)
}
void draw() {
sp.display();
}
//Spotクラスを定義
class Spot {
//属性を定義
float x, y, diameter; // x座標, y座標, 直径
//コンストラクタを定義
Spot(float _x, float _y, float _diameter) {
x = _x;
y = _y;
diameter = _diameter;
}
//表示するメソッドを定義
void display() {
ellipse(x, y, diameter, diameter);
}
}
step. 4 クラスに移動のメソッドを追加し、アニメーションにする
Spot sp; //オブジェクトを宣言
void setup() {
sp = new Spot(25, 50, 30, 1); //オブジェクトを生成(構築)
}
void draw() {
background(204);
sp.move();
sp.display();
}
//Spotクラスを定義
class Spot {
//属性を定義
float x, y, diameter, speed; // x座標, y座標, 直径, 速さ
//コンストラクタを定義
Spot(float _x, float _y, float _diameter, float _speed) {
x = _x;
y = _y;
diameter = _diameter;
speed = _speed;
}
//移動するメソッドを定義
void move() {
x += speed;
if (x > width + diameter/2) x = -diameter/2;
}
//表示するメソッドを定義
void display() {
ellipse(x, y, diameter, diameter);
}
}
クラス定義を別ファイルで管理する
※以降、Spot.pde ファイルの内容は同じなので省略する
異なる属性を持つ複数のオブジェクトを生成(インスタンス化)する
2個
Spot sp1, sp2; //オブジェクトを宣言
void setup() {
sp1 = new Spot(25, 50, 30, 1); //sp1 を生成
sp2 = new Spot(75, 80, 10, 2); //sp2 を生成
}
void draw() {
background(204);
sp1.move();
sp2.move();
sp1.display();
sp2.display();
}
60個(配列を使って)
Spot[] sp = new Spot[60];
void setup() {
for (int i = 0; i < sp.length; i++) {
sp[i] = new Spot(random(width), random(height), random(5,30), random(0.5,3));
}
}
void draw() {
background(204);
for (int i = 0; i < sp.length; i++) {
sp[i].move();
sp[i].display();
}
}
クラスを継承し、拡張された属性または機能を拡張した子クラスを定義する
Spot クラスを継承し、色を指定できる ColorSpot クラスを定義する
ColorSpot[] sp = new ColorSpot[60];
void setup() {
colorMode(HSB);
for (int i = 0; i < sp.length; i++) {
sp[i] = new ColorSpot(
random(width),
random(height),
random(5,30),
random(0.5,3),
color(random(255), 255, 255)
);
}
}
void draw() {
background(204);
for (int i = 0; i < sp.length; i++) {
sp[i].move();
sp[i].display();
}
}
ColorSpot.pde
//Spotクラスを継承し、ColorSpotクラスを定義
class ColorSpot extends Spot {
//属性を定義
color col; // 色
//コンストラクタを定義
ColorSpot(float _x, float _y, float _diameter, float _speed, color _col) {
super(_x, _y, _diameter, _speed); //親クラス(Spot)のコンストラクタを呼びだす
col = _col;
}
//移動するメソッドを定義
void move() {
super.move(); //親クラス(Spot)のメソッドを呼びだす
}
//表示するメソッドを定義
void display() {
fill(col);
super.display();
}
}
Spot.pde
//Spotクラスを定義
class Spot {
//属性を定義
float x, y, diameter, speed; // x座標, y座標, 直径, 速さ
//コンストラクタを定義
Spot(float _x, float _y, float _diameter, float _speed) {
x = _x;
y = _y;
diameter = _diameter;
speed = _speed;
}
//移動するメソッドを定義
void move() {
x += speed;
if (x > width + diameter/2) x = -diameter/2;
}
//表示するメソッドを定義
void display() {
ellipse(x, y, diameter, diameter);
}
}
移動ではなくサイズを変更すると、異なる表現ができる
シンプルな時計をOOPでつくる
- Comments (Close): 0
- TrackBack (Close): 0
b-09 ライブラリを利用する
- 2011年11月28日 14:40
- 2011-b
Processingは「ライブラリ」という仕組みで、その機能を拡張することができる。以前の授業でライブカメラを使用した際には、videoライブラリというライブラリを利用した。
→ Processing公式サイトで紹介されているライブラリ一覧(英語)
音を扱う
Processing で音を扱う場合、標準で用意されている Minim を利用するのが一般的である。以下の素材を利用して、Processingで音を扱ってみよう。
サンプルファイルを再生する
各種ドラム音のような、サンプルファイルは AudioSample クラスを利用する。
import ddf.minim.*;
Minim minim;
AudioSample kick;
AudioSample snare;
void setup() {
minim = new Minim(this);
kick = minim.loadSample("kick.wav", 2048);
snare = minim.loadSample("snare.wav", 2048);
}
void draw() {
}
void keyPressed() {
if (key == 'k') kick.trigger();
if (key == 's') snare.trigger();
}
void stop() {
kick.close();
snare.close();
minim.stop();
super.stop();
}
サイン波を生成し、マウス位置に応じて音程・パンを調整する
import ddf.minim.*;
import ddf.minim.signals.*;
Minim minim;
AudioOutput out;
SineWave sine;
void setup() {
minim = new Minim(this);
out = minim.getLineOut(Minim.STEREO);
sine = new SineWave(440, 0.5, out.sampleRate());
sine.portamento(200);
out.addSignal(sine);
}
void draw() {
}
void mouseMoved() {
float freq = map(mouseY, 0, height, 1500, 60);
sine.setFreq(freq);
float pan = map(mouseX, 0, width, -1, 1);
sine.setPan(pan);
}
void stop() {
out.close();
minim.stop();
super.stop();
}
一般的な音楽ファイルを再生する
ミュージシャンの楽曲のような、一般的な音楽ファイル(再生時間が長い→ファイル容量が大きい)ものは AudioPlayer クラスを利用する。
利用した音楽ファイル: ccMixter - Wataridori 2 - Cornelius
import ddf.minim.*;
Minim minim;
AudioPlayer player;
void setup() {
minim = new Minim(this);
player = minim.loadFile("http://ccmixter.org/contests/freestylemix/Cornelius%20-%20Wataridori%202.mp3", 2048);
player.play(); //再生
}
void draw() {
}
void stop() {
player.close();
minim.stop();
super.stop();
}
mp3ファイルのメタ情報を表示する
import ddf.minim.*;
Minim minim;
AudioPlayer player;
AudioMetaData meta;
void setup() {
minim = new Minim(this);
player = minim.loadFile("http://ccmixter.org/contests/freestylemix/Cornelius%20-%20Wataridori%202.mp3", 2048);
player.play(); //再生
meta = player.getMetaData();
//コンソールに音声データのメタ情報を表示
println("アルバム名: " + meta.album());
println("曲名: " + meta.title());
println("アーティスト名: " + meta.author());
}
void draw() {
}
void stop() {
player.close();
minim.stop();
super.stop();
}
※そのほかAudioPlayer にできることはリファレンスを参照 → AudioPlayer
物理シミュレーション
「物が落ちる」といった物理現象を簡単にシミュレートするためのライブラリで、最も有名なのがBox2Dであり、このBox2DをProcessingで利用できるようにしたものがBoxWrap2Dである。
インストール
- BoxWrap2Dをダウンロード
- BoxWrap2Dページ内の「Get the library」をクリックしてダウンロード
- 解凍したフォルダ「boxwrap2d」を、次のフォルダ内に配置:書類 > Processing > libraries ※Macの場合
- Processing を起動していた場合は、再起動する
Box2D を使ってみる
- 「画面をクリックすると、マウスポインタの位置から円が落ちる」プログラムを書いてみる
import org.jbox2d.p5.*;
Physics physics;
void setup() {
size(500, 500);
frameRate(60);
physics = new Physics(this, width, height);
physics.setDensity(1.0); //重さ(密度)
}
void draw() {
background(204);
}
void mousePressed() {
physics.createCircle(mouseX, mouseY, 15);
}
反発係数を設定する
import org.jbox2d.p5.*;
Physics physics;
void setup() {
size(480, 320);
frameRate(60);
physics = new Physics(this, width, height);
physics.setDensity(1.0); //重さ(密度)
physics.setRestitution(0.9); //反発係数
}
void draw() {
background(204);
}
void mousePressed() {
physics.createCircle(mouseX, mouseY, 10);
}
摩擦係数を設定する
import org.jbox2d.p5.*;
Physics physics;
void setup() {
size(480, 320);
frameRate(60);
physics = new Physics(this, width, height);
physics.setDensity(1.0); //重さ(密度)
physics.setRestitution(0.2); //反発係数
physics.setFriction(0.0); //摩擦係数
}
void draw() {
background(204);
}
void mousePressed() {
float d = 5;
physics.createRect(mouseX - d * 2, mouseY - d, mouseX + d * 2, mouseY + d);
}
- Comments (Close): 0
- TrackBack (Close): 0
b-07 時間を使う
- 2011年11月14日 14:40
- 2011-b
hour, minute, second 時、分、秒
コンソールに日時を表示する
void setup() {
frameRate(1); //フレームレートを1に設定(毎秒1回draw関数を実行)
}
void draw() {
int h = hour(); //時
int m = minute(); //分
int s = second(); //秒
println(h + ":" + m + ":" + s); //コンソールに日時を表示
}
コンソールに日時を表示する(分と秒は2ケタで表示)
void setup() {
frameRate(1);
}
void draw() {
int h = hour();
int m = minute();
int s = second();
String t = h + ":" + nf(m, 2) + ":" + nf(s, 2);
println(t);
}
ウィンドウに日時を表示する
void setup() {
textSize(18);
textAlign(CENTER);
frameRate(1);
}
void draw() {
background(0);
int h = hour();
int m = minute();
int s = second();
String t = h + ":" + nf(m, 2) + ":" + nf(s, 2);
//println(t);
text (t, 50, 55);
}
時間を視覚化する
長方形の長さで、時計を表現する
19:45:06
void setup() {
size(240, 240);
frameRate(1);
}
void draw() {
background(204);
int h = hour();
int m = minute();
int s = second();
//長方形の長さで時計を表現する
rect(0, 0, h*10, height/3);
rect(0, height/3, m*4, height/3);
rect(0, height*2/3, s*4, height/3);
}
三針時計をつくる
秒針から作ると、やりやすい。
void setup() {
size(240, 240);
frameRate(1);
smooth();
}
void draw() {
background(204);
noStroke();
ellipse (width/2, height/2, 200, 200);
int h = hour();
int m = minute();
int s = second();
stroke(0);
//時針
strokeWeight(4);
pushMatrix();
translate(width/2, height/2);
rotate((h%12+m/60.0)*TWO_PI/12);
line(0, 0, 0, -60);
popMatrix();
//分針
strokeWeight(2);
pushMatrix();
translate(width/2, height/2);
rotate((m+s/60.0)*TWO_PI/60);
line(0, 0, 0, -80);
popMatrix();
//秒針
strokeWeight(1);
pushMatrix();
translate(width/2, height/2);
rotate(s*TWO_PI/60);
line(0, 0, 0, -90);
popMatrix();
}
このプログラムでは、線を rotate() で回転することにより時計の針を描画している。以下のように三角関数を利用して針を描画することも可能。
void setup() {
size(240, 240);
frameRate(1);
smooth();
}
void draw() {
background(204);
noStroke();
ellipse (120, 120, 200, 200);
int s = second();
int m = minute();
int h = hour();
stroke(0);
strokeWeight(4);
line(120, 120 , 60 * cos((h + m/60.0) % 12 * TWO_PI / 12 - HALF_PI) + 120, 60 * sin((h + m/60.0) % 12 * TWO_PI / 12 - HALF_PI) + 120); //時針の描画
strokeWeight(2);
line(120, 120 , 80 * cos((m + s/60.0) * TWO_PI / 60 - HALF_PI) + 120, 80 * sin((m + s/60.0) * TWO_PI / 60 - HALF_PI) + 120); //分針の描画
strokeWeight(1);
line(120, 120 , 90 * cos(s * TWO_PI / 60 - HALF_PI) + 120, 90 * sin(s * TWO_PI / 60 - HALF_PI) + 120); //秒針の描画
}
練習
- 時間に関する関数を利用し、時間(秒)に反応したアニメーションを作成する
参考資料:時計を用いたビジュアル・インタラクティブ表現
- Comments (Close): 0
- TrackBack (Close): 0
b-06 ライブカメラを使う
- 2011年11月 7日 14:40
- 2011-b
Processing でビデオ映像を扱う場合は、ライブラリを利用する。今回は標準で用意されている Video ライブラリを利用する。
ライブカメラの映像を表示する
そのまま表示する
import processing.video.*; // Videoを扱うライブラリをインポート
Capture camera; // ライブカメラの映像をあつかうCapture型の変数
void setup() {
size(480, 320);
camera = new Capture(this, width, height, 12); // Captureオブジェクトを生成
}
void draw() {
image(camera, 0, 0); // 画面に表示
}
//カメラの映像が更新されるたびに、最新の映像を読み込む
void captureEvent(Capture camera) {
camera.read();
}
同じ映像を4分割で表示する
import processing.video.*;
Capture camera;
void setup() {
size(480, 320);
camera = new Capture(this, width/2, height/2, 12); // 1/2サイズでCaptureオブジェクトを生成
}
void draw() {
image(camera, 0, 0); // 画面に表示
image(camera, width/2, 0); // 画面に表示
image(camera, 0, height/2); // 画面に表示
image(camera, width/2, height/2); // 画面に表示
}
void captureEvent(Capture camera) {
camera.read();
}
一般化して n*n 分割で表示する
import processing.video.*;
Capture camera;
int d = 4; //画面を4*4で分割する
void setup() {
size(480, 320);
camera = new Capture(this, width/d, height/d, 12);
}
void draw() {
for (int j = 0; j < d ; j++) {
for (int i = 0; i < d ; i++) {
image(camera, i*width/d, j*height/d);
}
}
}
void captureEvent(Capture camera) {
camera.read();
}
色情報を取得して再描画する
import processing.video.*;
Capture camera;
void setup() {
size(480, 320);
camera = new Capture(this, width, height, 12);
smooth();
noStroke();
}
void draw() {
background(0);
camera.loadPixels(); //カメラ画像のpixel情報を読み込み
int d = 10; //円の直径を定義
// ライブカメラの映像から、円の直径の間隔ごとに、色情報を取得し、その色で円を描く
for(int y = d / 2 ; y < height ; y += d) {
for(int x = d / 2 ; x < width ; x += d) {
fill(camera.pixels[y * width + x]);
ellipse(x, y, d, d);
}
}
}
void captureEvent(Capture camera) {
camera.read();
}
練習
- 円の大きさをランダムにしてみる
- 異なる図形や文字で描画してみる
- 色情報を加工してみる
参考:OpenCV(画像処理ライブラリ)を使う
準備:OpenCVのインストール
- OPENCV \ library
- OpenCVのインストール
- OpenCVの Processing ライブラリを、書類 > Processing > libraries 内に配置
※Mac室では、インストールの権限制限があり、みなさん自身ではインストールができません。利用したい場合は事前に相談ください。
そのまま表示する
import hypermedia.video.*; //OpenCVライブラリをインポート
OpenCV opencv; //OpenCV型の変数
void setup() {
size(480, 320);
opencv = new OpenCV(this);
opencv.capture(width, height); ////映像読み込みの初期化
}
void draw() {
opencv.read(); //映像を読み込む
image(opencv.image(), 0, 0); //映像を表示
}
- videoライブラリを使用するときよりも、コードがシンプルになる
加工して表示する
import hypermedia.video.*;
OpenCV opencv;
void setup() {
size(480, 320);
opencv = new OpenCV(this);
opencv.capture(width/2, height/2);
}
void draw() {
opencv.read();
//左上
opencv.convert(OpenCV.GRAY); //グレースケールに変換
image(opencv.image(), 0, 0); //画面に表示 左上
//右上
opencv.invert(); //色を反転
image(opencv.image(), width/2, 0); // 画面に表示 右上
//左下
opencv.restore(); //オリジナルの映像に戻す
opencv.flip(OpenCV.FLIP_HORIZONTAL); //映像を水平方向に反転する
image(opencv.image(), 0, height/2); // 画面に表示 左下
//右下
image(opencv.image(OpenCV.SOURCE), width/2, height/2); // 画面に表示 オリジナルの映像 右下
}
そのほかOpenCVでできること
- Comments (Close): 0
- TrackBack (Close): 0
b-05 ピクセルを操作する
- 2011年10月31日 14:40
- 2011-b
pixels[] pixels 配列
- 画面全体またはPImageオブジェクトを1次元の配列として表したもの
- color型の配列
- (x, y)の情報は pixels[y*width + x] で得られる ※下で具体的に解説
- loadPixels() pixelsを読み込み
- updatePixels() pixelsの更新
- 幅10ピクセル、高さ4ピクセルの画面には、40個の点がある。
- 左上から図のように、0から39の番号を割り振りふる。これらが pixels 配列のインデックス(番号)と一致する。
- 幅7ピクエル、高さ4ピクセルの画面には、28個の点がある。
- 点(5, 2) の情報は pixels[19] で得ることができる。この19という数は2*7+5(y座標*幅+x座標)で得られる。
- 幅100ピクセル、高さ100ピクセルの画面には、10,000個の点がある。
- 幅480ピクセル、高さ320ピクセルの画面には、153,600個の点がある。
- これらの膨大な数の点の色情報を扱えるようにするのが pixels 配列である。
例1 画像の色を調べて表示する(カラーピッカー)
PImage myPhoto;
void setup() {
size(430, 640);
myPhoto = loadImage("http://dl.dropbox.com/u/446018/processing/mannalisa.jpg"); //画像を読み込み
noCursor(); //カーソルを非表示
}
void draw() {
image(myPhoto, 0, 0); //画像を表示
loadPixels(); //画面全体の色情報を配列pixelsとして読み込む
//x,y座標に現在のマウスの位置を代入
int x = mouseX;
int y = mouseY;
//マウス位置に縦線・横線を表示
stroke(255, 51);
line(x, 0, x, height);
line(0, y, width, y);
//マウス位置の色情報を取得し、塗り色に設定
fill(pixels[y*width + x]);
//画面左上にマウス位置の色を表示
stroke(0);
rect(20, 20, 60, 60);
}
例2 画像の色を調べて、図形や文字で再描画する(モザイク)
マウスを動かして描く
PImage myPhoto;
void setup() {
size(430, 640);
myPhoto = loadImage("http://dl.dropbox.com/u/446018/processing/mannalisa.jpg"); //画像を読み込み
noStroke();
smooth();
background(255);
}
void draw() {
myPhoto.loadPixels(); //myPhotoに読み込まれた画像の色情報を配列pixelsとして読み込む
//x,y座標に現在のマウスの位置を代入(x,yの値が画像サイズを超えないようにconstrain関数を利用)
int x = constrain(mouseX, 0, myPhoto.width-1);
int y = constrain(mouseY, 0, myPhoto.height-1);
//その点の色情報を取得し、塗り色に設定
fill(myPhoto.pixels[y*width + x]);
//その点の位置を中心として直径10から20pxの円を描く
float d = random(10, 20);
ellipse(x, y, d, d);
}
アニメーションでランダムに描く
PImage myPhoto;
int myPhotoWidth, myPhotoHeight;
void setup() {
size(430, 640);
myPhoto = loadImage("http://dl.dropbox.com/u/446018/processing/mannalisa.jpg"); //画像を読み込み
//画像のサイズを取得し変数に代入
myPhotoWidth = myPhoto.width;
myPhotoHeight = myPhoto.height;
noStroke();
smooth();
background(255);
}
void draw() {
myPhoto.loadPixels(); //myPhotoに読み込まれた画像の色情報を配列pixelsとして読み込む
//x,y座標をランダムに指定
int x = int(random(myPhotoWidth));
int y = int(random(myPhotoHeight));
//その点の色情報を取得し、塗り色に設定
fill(myPhoto.pixels[y*width + x]);
//その点の位置を中心として直径10から20pxの円を描く
float d = random(10, 20);
ellipse(x, y, d, d);
}
pixels のカラーデータ
これらを利用すると、さらに詳細な色設定が可能になる。
- red() 赤成分の値
- green() 緑成分の値
- blue() 青成分の値
- hue () 色相の値
- saturation() 彩度の値
- brightness() 輝度の値
- alpha() アルファ値
PImage myPhoto;
int myPhotoWidth, myPhotoHeight;
void setup() {
size(430, 640);
colorMode(HSB);
myPhoto = loadImage("http://dl.dropbox.com/u/446018/processing/mannalisa.jpg"); //画像を読み込み
//画像のサイズを取得し変数に代入
myPhotoWidth = myPhoto.width;
myPhotoHeight = myPhoto.height;
noStroke();
smooth();
background(255);
}
void draw() {
myPhoto.loadPixels(); //myPhotoに読み込まれた画像の色情報を配列pixelsとして読み込む
//x,y座標をランダムに指定
int x = int(random(myPhotoWidth));
int y = int(random(myPhotoHeight));
//その点の色情報を取得
color myPhotoColor = myPhoto.pixels[y*width+x];
//塗り色に設定(色相と明度は変更なし、輝度は0に設定 ...モノクロになる)
fill(hue(myPhotoColor), 0, brightness(myPhotoColor));
//その点の位置を中心として直径10から20pxの円を描く
float d = random(10, 20);
ellipse(x, y, d, d);
}
練習:画像の色を調べて、図形や文字で再描画する(元画像の原形をとどめていなくても良い)
- Comments (Close): 0
- TrackBack (Close): 0
b-04 配列を使う
- 2011年10月24日 14:40
- 2011-b
配列とは
似たような複数の変数をプログラムで制御したい場合は「配列」を利用する。
例えば、
How are you? I am fine thank you!
という会話中の単語を用いて何かブログラムを書こうとするとき、配列を用いない場合は
String s0 = "How";
String s1 = "are";
String s2 = "you?";
String s3 = "I";
String s4 = "am";
String s5 = "fine";
String s6 = "thank";
String s7 = "you!";
と1つずつ変数に代入する必要があるが、配列を用いれば
String[] chat = {"How","are","you?","I","am","fine","thank","you!"};
というように、まとめて代入ができる。
配列には「インデックス」と呼ばれる0から始まる番地があり、順に値が代入される(マンションの0号室, 1号室, 2号室... とイメージするとわかりやすい)。
配列に代入された値は、このインデックスを用いて利用する。例えば、"How"という文字を利用したければ、0番(1番ではなく、0から始まることに注意)を指定すればよい。具体的には、
String[] chat = {"How","are","you?","I","am","fine","thank","you!"};
text(chat[0], 0, 50);
とすれば、画面中央左に「How」と表示される。chat[0] は「配列chatの0番の値」ということである。
そのほかの単語も画面に表示してみよう。
for文を用いてすべての単語をランダムな位置に表示する
インデックスは0から始まる整数の連番なので、for文を用いた処理と相性が良い。例えば、配列のすべての値を表示したい場合は、以下のように書くことができる。
String[] chat = {"How","are","you?","I","am","fine","thank","you!"};
for (int i = 0; i < chat.length; i++) {
text(chat[i], random(width), random(height));
}
ポイントはfor文の繰り返しの範囲を chat.length で表しているところ。こうすると「配列 chat の長さ」(この場合は8)が適用される。
※このプログラムでは、文字が画面からはみ出てしまうことがあるので、textAlignの指定を追加したりrandomの指定を調整すると良い。
単語を順に表示する
String[] chat = {"How","are","you?","I","am","fine","thank","you!"};
int count = 0;
void setup() {
size(100, 100);
frameRate(3);
}
void draw() {
background(204);
fill(0);
textAlign(CENTER);
text(chat[count], width/2, height/2);
count++;
if(count >= chat.length) count = 0;
}
ポイントは2つ。
- setupでフレームレート(1秒間に再生するフレーム数)の設定をしている。frameRate(3) は「1秒間に3フレーム再生する」ということ。
- 1回再生するごとにカウンター(変数countでカウント)を1増やし、countの値が配列の長さ以上になったらカウンターをリセット(countの値を0)している。こうすることで、繰り返し単語が順に表示される。
練習「おみくじ」を作る
- 大吉、中吉、小吉、吉の4つとする
- ウィンドウサイズは自由とする
制作の進め方で気を付けたいこと
- 基本的な機能が動作するシンプルな「プロトタイプ」を作る
- プロトタイプが出来てから、細部を作り込んでいく
作り方のヒント
- どのタイミングでおみじくを表示するか?
- ユーザーがアクションを起こしたとき
- どうやってユーザーにアクションを起こしてもらうか?
- マウスやキーボードからの入力
- おみくじデータの用意方法は?
- 配列を利用する
- おみくじをランダムに選ぶには?
- random関数を利用する
- 大吉が出にくく、吉が出やすくするには?
- 「100本のくじのうち、大吉は10本、中吉は20本、小吉は30本、吉は40本」と考える
- if(...){...}else if(...){...}else if(...){...}else{}
配列を使ったプログラムの例
形の描画を効率化する
void setup() {
size(600, 300);
}
void draw() {
//画面のリセット
fill(204, 10);
noStroke();
rect(0, 0, width, height);
//ランダムな位置・傾き・サイズで☆が描画されるように座標変換する
translate(random(width), random(height));
rotate(random(PI));
scale(random(0.1, 0.5));
//配列の定義
int[] x = {50, 29, 83, 17, 71}; //点A,B,C,D,Eのx座標
int[] y = {18, 82, 43, 43, 82}; //点A,B,C,D,Eのy座標
// 5つの点A,B,C,D,Eを順に直線で結び☆を描く
translate(-50, -50); //☆を原点の位置に座標変換する
fill(255);
stroke(0);
beginShape();
for (int i = 0; i < x.length; i++) {
vertex(x[i] + random(-5, 5), y[i] + random(-5, 5));
}
endShape(CLOSE);
}
カーソルの位置を記憶させる
int num = 50; //円の個数
int[] x = new int[num]; //x座標を記録する配列
int[] y = new int[num]; //y座標を記録する配列
void setup() {
size(600, 300);
}
void draw() {
background(204); //画面をリセット
//配列を参照して円を描画する
for(int i = 0 ; i < num ; i++) {
fill(i * 3);
ellipse(x[i], y[i], i, i);
}
}
//マウスが動いたときの処理:マウスの座標を記録する
void mouseMoved() {
//配列の値をひとつ後ろへ移動する
for(int i = num - 1 ; i > 0 ; i--) {
x[i] = x[i-1];
y[i] = y[i-1];
}
x[0] = mouseX;
y[0] = mouseY;
}
画像を読み込んでアニメーションにする
int numFrames = 60; //アニメーションのフレーム数
PImage[] images = new PImage[numFrames]; //アニメーション画像の配列
void setup() {
size(320, 240);
frameRate(30);
// 画像の読み込み
for (int i = 0; i < images.length; i++) {
images[i] = loadImage("http://dl.dropbox.com/u/446018/sq_iinaiina/animation-" + nf(i, 3) + ".jpg");
}
}
void draw() {
int frame = frameCount % numFrames; //現在のフレームをアニメーションのフレーム数で割った余りを代入
image(images[frame], 0, 0); //画像を表示
}
- Comments (Close): 0
- TrackBack (Close): 0
b-03 文字を使う
- 2011年10月17日 14:40
- 2011-b
text() 文字を描く関数
text("あいうえお愛", 10, 35); // 表示するテキスト, x座標, y座標
text("あいうえお愛", 10, 35, 40, 40); // 表示するテキスト, x座標, y座標, 表示領域の幅, 表示領域の高さ
fill(0); //塗色を設定する
text("あいうえお愛", 10, 35, 40, 40);
textSize() 文字サイズを指定する
fill(0);
textSize(16);
text("あいうえお愛", 10, 35);
textAlign() 文字揃えを指定する
fill(0);
textAlign(CENTER);
text("あいうえお愛", 50, 35);
String 文字列のデータ型
文字列を変数で扱う場合は String 型を用いる。
String s = "あいうえお愛";
text(s, 10, 35);
ランダムに表示する
ランダムな位置に、ランダムな数字を表示する
void setup() {
size(200, 200);
}
void draw() {
fill(random(256));
textSize(random(12, 36));
textAlign(CENTER);
text(int(random(10)), random(width), random(height));
}
キーボードを押すと、その文字をランダムな位置に表示する
void setup() {
size(200, 200);
}
void draw() {
}
void keyPressed() {
fill(random(256), random(102, 256));
textSize(random(36, 64));
textAlign(CENTER);
text(key, random(width), random(height));
}
指定したフォントで文字を描く
準備
以下のようにフォントデータを生成しておく
PFont 変数でフォントデータを扱う場合のデータ型 , textFont 使用するフォントを指定
size(500, 200);
PFont myFont = loadFont("HelveticaNeue-Bold-24.vlw");
textFont(myFont);
text("I Love Processing!", 0, 100);
- Comments (Close): 0
- TrackBack (Close): 0
b-02 反応させる(マウス、キーボードからの入力に)
- 2011年10月10日 14:40
- 2011-b
mouseX, mouseY マウスポインタの位置(座標)
現在のマウスポインタの位置に円が描かれる。
void setup() {
size(400, 400);
}
void draw() {
ellipse(mouseX, mouseY, 60, 60);
}
pmouseX, pmouseY 前フレームのマウスポインタの位置(座標)
前フレームのマウスポインタの位置から現フレームのマウスポインタの位置に線が描かれる。(マウスを動かすと、線が描かれるように見える)
void setup() {
size(400, 400);
}
void draw() {
line(mouseX, mouseY, pmouseX, pmouseY);
}
mousePressed マウスボタンが押されている(== true)、押されていない(== false)
マウスボタンを押している間、線が描かれる。
void setup() {
size(400, 400);
strokeWeight(10);
}
void draw() {
if (mousePressed == true){
line(mouseX, mouseY, pmouseX, pmouseY);
}
}
mousePressed() {...} マウスボタンが押されたときに1回だけ {...} の中を実行する
マウスボタンを押すと、円が描かれる。
void setup() {
size(400, 400);
}
void draw() {
}
void mousePressed() {
ellipse(mouseX, mouseY, 60, 60);
}
mouseReleased() {...} マウスボタンが離されたときに1回だけ {...} の中を実行する
マウスボタンを押している間、線が描かれる。ボタンが離されると線が消える。
void setup() {
size(400, 400);
strokeWeight(10);
}
void draw() {
if (mousePressed == true){
line(mouseX, mouseY, pmouseX, pmouseY);
}
}
void mouseReleased() {
background(204); //マウスボタンが離されると画面がリセットされる
}
練習:次のような動作をするプログラムを書く
マウスポインタの位置に赤い円が描かれる。マウスボタンを押すと、円の塗り色が変わる。
マウスボタンを押すと、前回マウスボタンを押した位置からの折れ線が描ける。
keyPressed キーが押されている(== true)、押されていない(== false)
キーが押されているとき、円が左から右にすすむ
float x = 0.0;
float speed = 1.0;
void setup() {
size(400, 400);
}
void draw() {
background(204);
if (keyPressed == true) {
x += speed;
//println(key);
}
ellipse(x, height/2, 60, 60);
}
key 押されたキーの文字や記号を納める変数
キーのa(小文字のエー)が押されているとき、円が左から右にすすむ
float x = 0.0;
float speed = 1.0;
void setup() {
size(400, 400);
}
void draw() {
background(204);
if ((keyPressed == true) && (key == 'a')) {
x += speed;
}
ellipse(x, height/2, 60, 60);
}
※大文字小文字を問わないようにするためには、次のように「aまたはAが押されているとき」で条件を設定する
float x = 0.0;
float speed = 1.0;
void setup() {
size(400, 400);
}
void draw() {
background(204);
if ((keyPressed == true) && ((key == 'a') || (key == 'A'))) {
x += speed;
}
ellipse(x, height/2, 60, 60);
}
keyPressed() {...} キーが押されたときに1回だけ {...} の中を実行する
※キーを押しっぱなしにして一定時間経つと、キーの連続入力状態になり、そのスピードに合わせ連続して実行される。
キーが押されると、円が1ピクセルだけ左から右にすすむ
float x = 0.0;
float speed = 1.0;
void setup() {
size(400, 400);
}
void draw() {
}
void keyPressed() {
background(204);
x += speed;
ellipse(x, height/2, 60, 60);
//println(key);
}
keyReleased() {...} キーが離されたときに1回だけ {...} の中を実行する
キーが離されると、円が止まる
float x = 0.0;
float speed = 1.0;
void setup() {
size(400, 400);
}
void draw() {
background(204);
x += speed;
ellipse(x, height/2, 60, 60);
}
void keyReleased() {
speed = 0.0;
}
- Comments (Close): 0
- TrackBack (Close): 0
b-01 動かす
- 2011年10月 3日 14:40
- 2011-b
正方形を横に動かす
step.1 静止した正方形を描く
//最初に1回だけ実行する
void setup() {
size(200, 200);
}
//毎フレーム繰り返し実行する
void draw() {
rect(0, height/2, 10, 10); //画面中央左に一辺が10pxの正方形を描く
}
rectのx座標がじょじょに大きくなれば、正方形は数のように左に移動し、動いているように見える。
step.2 正方形のx座標を変数で置き換え、変数の値がじょじょに大きくなるようにする
float x; //小数型の変数xを宣言
void setup() {
size(200, 200);
x = 0; //xの初期値を0とする
}
void draw() {
x += 1; //毎フレームで正方形のx座標を1ずつ増やす
rect(x, height/2, 10, 10);
}
正方形が動くようになったが、黒い帯が残る。これは、正方形が描き重ねられているからである。毎フレームで画面をクリアした後に正方形を描けば、黒い帯は残らないようになる。
step. 3 画面をクリアしてから正方形を描画する
float x;
void setup() {
size(200, 200);
x = 0;
}
void draw() {
background(204); //背景色を設定することで画面をクリアする
x += 1;
rect(x, height/2, 10, 10);
}
正方形が画面右に消える(正方形のx座標が200を超える)と、画面に変化がなくなってしまい退屈である。次に、右に消えたら再び左から現れるようにしよう。
step. 4 ループ移動させる
float x;
void setup() {
size(200, 200);
x = 0;
}
void draw() {
background(204);
x += 1;
if (x > width) x = -10; //正方形が画面からはみ出たら、正方形を画面の左外に戻す
rect(x, height/2, 10, 10);
}
step. 5 正方形の出現位置をランダムに設定する
if文を実行する際、正方形のy座標をランダムに設定するし、さらに変化を付ける。
float x, y; //変数にyを追加
void setup() {
size(200, 200);
x = 0;
y = height/2; //yの初期値を画面の中央にする
}
void draw() {
background(204);
x += 1;
if (x > width) {
x = -10;
y = random(width - 10); //正方形が画面内に収まる範囲で、yの値をランダムに設定
}
rect(x, y, 10, 10);
}
練習 - 上記のプログラムを改変してみる
- 正方形の幅を変数wで表し、任意の大きさの正方形がループ移動するプログラムに書きかえる
- 正方形の移動するスピードを速くする、または遅くする
- 正方形の移動するスピードを変数speedで表し、任意のスピードで正方形が移動するプログラムに書きかえる
- 正方形を右から左に動かす(ヒント:元のプログラムを書きかえる際、if文はコメントアウトしておき、移動の部分を書きかえてから、if文でのループ移動の条件を書きかえる)
- 正方形を上から下に動かす
- 円を動かす
座標を移動する
座標を移動することで、正方形が動いているように見せることができる。このやり方の方が汎用性がある。
float x, y;
float speed;
int w;
void setup() {
size(200, 200);
x = 0.0;
y = height/2.0;
speed = 1.0;
w = 10;
}
void draw() {
background(204);
x += speed;
if (x > width) {
x = -w;
y = random(width - w);
}
translate(x, y); //座標を移動する
rect(0, 0, w, w); //座標を移動するので、正方形は固定の位置に描画する
}
応用例:バスを動かす
float x, y;
float speed;
void setup() {
size(200, 200);
x = 0.0;
y = height/2.0;
speed = 1.0;
}
void draw() {
background(204);
x += speed;
if (x > width+60) {
x = -60;
y = random(30, width-45);
}
translate(x, y);
//draw Bus
rectMode(CENTER);
rect(0,0,120,60);
ellipse(-35,30,30,30);
ellipse(35,30,30,30);
ellipse(-35,30,20,20);
ellipse(35,30,20,20);
rectMode(CORNER);
rect(45,-20,15,20);
rect(-5,-20,30,20);
rect(-50,-20,30,20);
}
- Comments (Close): 0
- TrackBack (Close): 0
Home> 2011-bアーカイブ
- カテゴリ
-
- 1a
- 1b
- 2010-a (13)
- 2010-b (11)
- 2011-a (10)
- 2011-b (10)
- android (1)
- libraries
- processing.js (1)
- tools (2)
- トピックス (1)
- ノート
- アーカイブ
- 購読
- Recommends
-
- Powerd By














































