Processing を使ってプログラミングを楽しみたいみたいと思います。 以下、Processing を使っていく上での記録を記していきます。 同じように Processing を使っていこうとする人に参考になるように。
Processing とは、MITメディアラボに期限を持つオープンソースプロジェクト(つまり、その筋ではとっても有名なところが始めた、
無料でみんなが利用できるソフトウエアの開発事業)であり、そのプログラミング言語であり、また、そのプログラミングを行うため
の開発環境(開発用のソフトウエア)でもあります。プロジェクトだったり、言語だったり、ソフトウエアだったりするので、
何を指しているのか、時々気をつけて下さい。
この中で、言語としての Processing の位置づけは、プログラミングを行おうとする場合には、もっとも関心があると思います。次のような特徴があります。
Processing はArduinoと関係があります。マイコン(マイクロコンピュータ)制御に関連した Processing を基にしたプロジェクトに Wiring があります。
Arduino は、Wiring から派生したプロジェクトです。
//
// Freefall motion due to the Gravity on the Earth, on the Moon, and on the Mars.
//
// Based on the following program
// Augmented Reality Dynamic Example by Amnon Owed (21/12/11)
// Processing 1.5.1 + NyARToolkit 1.1.6 + GSVideo 1.0
import java.io.*; // for the loadPatternFilenames() function
import processing.opengl.*; // for OPENGL rendering
import jp.nyatla.nyar4psg.*; // the NyARToolkit Processing library
import codeanticode.gsvideo.*; // the GSVideo library
String camPara = "D:/My Documents/Processing/libraries/NyAR4psg/data/camera_para.dat"; // カメラのパラメタ?
String patternPath = "D:/デスクトップ/開発工作/Processing/patternMaker/examples/ARToolKit_Patterns"; // AR マーカーを学習させたパターンファイルへのパス。
// Preparation for Camera ------------------------------------------------------------------------------------------------------
int arWidth = 640; // カメラから修得する画像のサイズ。カメラに依存する。大きすぎると遅くなる。
int arHeight =360;
GSCapture cam;
// Preparation for AR ---------------------------------------------------------------------------------------------------------
int numMarkers = 10; // 利用する AR マーカーの数
float markersize = 136;
int[] inittime = new int[numMarkers];
float[] vx = new float[numMarkers]; // 初速x成分 単位 mm/ms
float[] vy = new float[numMarkers]; // 初速y成分 単位 mm/ms
float[] gr = new float[numMarkers]; // 重力加速度 単位 mm/ms^2 MKS の 1/1000
MultiMarker nya;
void setup() {
// Initialization for Camera -------------------------------------------------------------------------------------------------
size(arWidth, arHeight, OPENGL);
cam = new GSCapture(this, arWidth, arHeight);
cam.start(); // start capturing
noStroke(); // turn off stroke for the rest of this sketch :-)
// Initialization for AR -------------------------------------------------------------------------------------------------
// create a new MultiMarker at a specific resolution (arWidth x arHeight), with the default camera calibration and coordinate system
nya = new MultiMarker(this, arWidth, arHeight, camPara, NyAR4PsgConfig.CONFIG_DEFAULT);
// set the delay after which a lost marker is no longer displayed. by default set to something higher, but here manually set to immediate.
nya.setLostDelay(1);
String[] patterns = loadPatternFilenames(patternPath);
// Initialization for Individual Markers -------------------------------------------------------------------------------------
// for the selected number of markers, add the marker for detection
// create an individual scale, noiseScale and maximum mountainHeight for that marker (= mountain)
for (int i=0; i<numMarkers; i++) {
nya.addARMarker(patternPath + "/" + patterns[i], markersize); // リファレンスマニュアルと違う?第二引数は、ミリメートル単位でのマーカーのサイズのようだ。
//
// マーカーごとに、それぞれ別々の運動を表現したい場合には、ここを変更する。
//
inittime[i] = -1;
vx[i] = 1.4142;
vy[i] = 1.4142;
gr[i] = 9.8e-3 * i / (numMarkers - 1);
}
gr[8] = 1.622e-3; // 月
gr[7] = 8.87e-3; // 金星
gr[6] = 3.71e-3; // 火星
gr[5] = 23.12e-3; // 木星
}
void draw() {
// if there is a cam image coming in...
if (cam.available()) {
cam.read(); // read the cam image
background(0); // a background call is needed for correct display of the marker results
image(cam, 0, 0, width, height); // 表示 : display the image at the width and height of the sketch window
// create a copy of the cam image at the resolution of the AR detection (otherwise nya.detect will throw an assertion error!)
PImage cSmall = cam.get();
cSmall.resize(arWidth, arHeight);
nya.detect(cSmall); // detect markers in the image
drawBalls(); // draw dynamically flowing mountains on the detected markers (3D)
}
}
void drawBalls() {
int etime = 0;
float posx, posy;
nya.setARPerspective(); // Projection Matrix をカメラのものにする……そうだ。
lights(); // 適当な陰影をつけてくる。これをコメントアウトすると、のっぺりになる。
for (int i=0; i<numMarkers; i++) { // マーカーの数だけ繰り返し調べる
// if the marker does NOT exist (the ! exlamation mark negates it)...
if ((!nya.isExistMarker(i))) { // マーカーが見つけられなかったら時間をリセット
inittime[i] = -1;
continue;
}
// マーカーが見つかったら以下を実行
setMatrix(nya.getMarkerMatrix(i)); // nya.getMarkerMatrix(i) : 変換行列を取得
translate( -markersize/2, -markersize/2) ; // 座標(-resX/2, -resY/2)を原点に変更する → ARのオブジェクトは全部真中にくる。
// マーカーを塗りつぶす
fill(180);
beginShape();
vertex(0, 0);
vertex(0, markersize);
vertex(markersize, markersize);
vertex(markersize, 0);
endShape(CLOSE);
// ボールを描く
etime = millis() - inittime[i];
if( etime < 1000 ){
etime = 0;
}else{
etime -= 1000;
}
if ( inittime[i] == -1 ){ inittime[i] = millis(); }
posx = vx[i] * etime;
posy = vy[i] * etime - gr[i] / 2 * etime * etime;
// println( etime);
fill(200,200,255);
translate( posx, posy); sphere(10); translate(-posx, -posy);
// 時間が経過したら、また、画面から明らかに外れたら、初期化する
if ( posx > 3e3 || posy > 3e3 || etime > 3000 ){
inittime[i] = millis();
}
}
// reset to the default perspective
perspective();
}
// this function loads .patt filenames into a list of Strings based on a full path to a directory (relies on java.io)
String[] loadPatternFilenames(String path) {
File folder = new File(path);
FilenameFilter pattFilter = new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(".patt");
}
};
return folder.list(pattFilter);
}