3D表現
バッファに格納したdelta値を3次元空間上に螺旋状に表示
Last updated
バッファに格納したdelta値を3次元空間上に螺旋状に表示
Last updated
実行手順
PeasyCamライブラリをインストール
[スケッチ] > [ライブラリインポート] > [Manage Libraries]
開いたウインドウで 「PeasyCam」を検索してinstall
Vieを装着し、Vie StreamでVieに接続
「計測開始(Activate Sensor)」ボタンを押す
「OSC転送(OSC Streaming)」ボタンを押す
「ポート番号」と「デバイス識別子」を確認。(通常はそれぞれ、65001、1)
コードの実行
キーボードの1~0キーで表現を切り替える
//deltaの値は最小0、最大100なので、これを0〜500にスケーリングする場合
float delta = 50;
float m = map(delta, 0, 100, 0, 500);
println(m); // Prints "250"
import peasy.*;
import oscP5.*;
import netP5.*;
//OSCP5クラスのインスタンス
OscP5 oscP5;
//PeasyCam
PeasyCam cam;
float [] waveLeft = new float[5]; //左用
float [] waveRight = new float[5]; //右用
float [] waveMean = new float[5]; //左と右の平均
//脳波を一定数記録するバッファ
ArrayList<BrainWave> bwBuffer = new ArrayList<BrainWave>();
int bwBufferSize = 300;
int circleVerticiesNum = 6; //円環を何角形で描くか。ここでは6角形
float marginPerCycle = 5; //一つのバッファを描くごとにz方向に何ピクセル移動するか
float distMax = 600.0; //最も強い脳波を何ピクセルで表現するか
float distMin = 5.0; //最も弱い脳波を何ピクセルで表現するか
float posX = 0.0, posY = 0.0, posZ = 0.0;
float posXp = 0.0, posYp = 0.0, posZp = 0.0;
int vizMode = 1;
void setup() {
size(800,600,P3D);
//ポートを65001に設定して新規にOSCP5のインスタンスを生成
oscP5 = new OscP5(this,65001);
//カメラの初期化
cam = new PeasyCam(this, 700);
//バッファを初期化する
for(int i=0; i<bwBufferSize; i++){
bwBuffer.add( new BrainWave() );
}
colorMode(HSB,255,255,255,255);
blendMode(ADD);
}
void draw() {
background(0);
noStroke();
//脳波をバッファに格納
BrainWave bw = new BrainWave();
bw.set(waveMean[0],waveMean[1], waveMean[2], waveMean[3], waveMean[4]);
bwBuffer.add(bw);
//バッファサイズが上限に達したら先頭を削除
if(bwBuffer.size() > bwBufferSize){
bwBuffer.remove(0);
}
//描画
float anglePerBuffer = 2*PI / circleVerticiesNum;
float distFromCenter = 0.0;
pushMatrix();
translate(0,0,-posZ - (0.5 * bwBufferSize * marginPerCycle));
//線として描画
if(vizMode ==0){
beginShape();
for(int i=0; i<bwBuffer.size(); i++){
//バッファされたデルタ波の数値を中心からの距離に変換
distFromCenter = map( bwBuffer.get(i).delta, 0, 100, distMin, distMax);
//頂点の座標を計算
posX = distFromCenter * cos( anglePerBuffer * i );
posY = distFromCenter * sin( anglePerBuffer * i );
posZ += marginPerCycle;
stroke(0,0,255,255);
noFill();
vertex(posX,posY,posZ);
}
endShape();
}
//面として描画
else if(vizMode == 1){
beginShape(TRIANGLES);
for(int i=0; i<bwBuffer.size(); i++){
//バッファされたデルタ波の数値を中心からの距離に変換
distFromCenter = map( bwBuffer.get(i).delta, 0, 100, distMin, distMax);
//バッファされたデルタ波の数値を色相と再度に変換
float hue = map( bwBuffer.get(i).delta, 0, 100, 160, 255);
float sat = map( bwBuffer.get(i).delta, 0, 100, 0, 255);
//一つ前のバッファで計算した頂点座標を保存
posXp = posX;
posYp = posY;
posZp = posZ;
//頂点の座標を計算
posX = distFromCenter * cos( anglePerBuffer * i );
posY = distFromCenter * sin( anglePerBuffer * i );
posZ += marginPerCycle;
//ポリゴンの3頂点を登録
//頂点の色に色相と再度を反映
fill(hue,0,255,10);
stroke(hue,0,255,255);
vertex(0,0,posZp);
fill(hue,sat,255,10);
stroke(hue,sat,255,255);
vertex(posXp,posYp,posZp);
fill(hue,sat,255,10);
stroke(hue,sat,255,255);
vertex(posX,posY,posZ);
}
endShape();
}
popMatrix();
}
//OSCメッセージを受信した際に実行するイベント
void oscEvent(OscMessage msg) {
if(msg.checkAddrPattern("/wave/L/1")==true) {
for(int i=0;i<5;i++){
waveLeft[i] = msg.get(i).floatValue();
//左右の平均を取る
calWaveMean(i);
}
}
if(msg.checkAddrPattern("/wave/R/1")==true) {
for(int i=0;i<5;i++){
waveRight[i] = msg.get(i).floatValue();
//左右の平均を取る
calWaveMean(i);
}
}
}
void calWaveMean(int n){
waveMean[n] = 0.5*(waveLeft[n] + waveRight[n]);
}
class BrainWave{
public float delta;
public float theta;
public float alpha;
public float beta;
public float gamma;
BrainWave(){
this.delta =0.0;
this.theta =0.0;
this.alpha =0.0;
this.beta =0.0;
this.gamma =0.0;
}
void set(float d,float t,float a,float b,float g){
this.delta =d;
this.theta =t;
this.alpha =a;
this.beta =b;
this.gamma =g;
}
}
void keyPressed(){
if(key == '0'){
vizMode = 0;
}
if(key == '1'){
vizMode = 1;
}
}