2011
06/22
draw3DLine : 3D drawing on 2D canvas (Processing.js)
最近、3Dになったユニバ社のロゴ。
3Dの描画機能だけを切り出してみたので、皆さん使ってね。
ユニバの新ロゴはcanvas+Processing.jsで作られていますが、Processingの3D系の命令は使っていません(WebGLに対応しているブラウザがまだ少ないので…)。3Dのオブジェクトをスクリーン(canvas)に投影する計算を行って、2D系の命令だけで描画しています。
その描画系を切り出したのが以下の関数です。
使い方
draw3DLine(x1, y1, z1, x2, y2, z2, xRotate, yRotate, zRotate)
6つの引数(XYZ座標を2つと、XYZ軸の回転角度)を渡すと、canvasに2座標を結ぶ線を描画します。原点は画面の中央です。
カメラはZ軸上に固定です。カメラの視野角(radS)、カメラの位置(camZ)、スクリーン位置(scZ)だけ、変更することができます。線の太さ、色はweight、strokeH、strokeS、strokeBで持っていますが、2Dで線を描画するパラメータなので、太い線ではパース感の矛盾がよりはっきり見えてきます。細い線でも厳密に言えば奥行き感ゼロ。そこは見せ方でがんばってね。
サンプルでは、線を12本引き、XYZ軸それぞれを1度ずつ回転させて、直方体が回転するアニメーションを作っています。
http://hascanvas.com/draw3DLine
//透視変換用の変数
//視野角θ
float radS = TWO_PI/360*35;
//カメラの原点からの距離
float camZ = -4500;
//スクリーンの原点からの距離
float scZ = -1000;
//回転
float xRotate = 0;
float yRotate = 0;
float zRotate = 0;
//描画用の変数
//線の太さ
float weight = 0.5;
//線の色
int strokeH = 0;
int strokeS = 0;
int strokeB = 0;
//頂点座標を格納する配列 : x1, y1, z1, x2, y2, z2
int[][] va = {
{-200,-200,-20, 200,-200,-20},
{ 200,-200,-20, 200, 200,-20},
{ 200, 200,-20,-200, 200,-20},
{-200, 200,-20,-200,-200,-20},
{-200,-200, 20, 200,-200, 20},
{ 200,-200, 20, 200, 200, 20},
{ 200, 200, 20,-200, 200, 20},
{-200, 200, 20,-200,-200, 20},
{-200,-200,-20,-200,-200, 20},
{ 200,-200,-20, 200,-200, 20},
{ 200, 200,-20, 200, 200, 20},
{-200, 200,-20,-200, 200, 20}
};
//初期化
void setup()
{
size(300, 300);
frameRate(30);
colorMode(HSB);
noSmooth();
noFill();
background(255);
}
//メインループ
void draw()
{
background(255);
//描画ループ
for(int i=0; i<va.length; i++) {
//描画
//x1, y1, z1, x2, y2, z2, rotateX, rotateY, rotateZ
draw3DLine(va[i][0],va[i][1],va[i][2],va[i][3],va[i][4],va[i][5], xRotate, yRotate, zRotate);
}
//回転
xRotate += TWO_PI/360;
yRotate += TWO_PI/360;
zRotate += TWO_PI/360;
}
//透視変換 x1, y1, z1, x2, y2, z2, rotateX, rotateY, rotateZ
void draw3DLine(float x1,float y1, float z1, float x2, float y2, float z2, float rx, float ry, float rz)
{
//Y軸の回転量を反映
float z1cash = z1;
float z2cash = z2;
z1 = x1 * sin(ry) - z1cash * cos(ry);
z2 = x2 * sin(ry) - z2cash * cos(ry);
x1 = x1 * cos(ry) + z1cash * sin(ry);
x2 = x2 * cos(ry) + z2cash * sin(ry);
//X軸の回転量を反映
z1cash = z1;
z2cash = z2;
z1 = y1 * sin(rx) - z1cash * cos(rx);
z2 = y2 * sin(rx) - z2cash * cos(rx);
y1 = y1 * cos(rx) + z1cash * sin(rx);
y2 = y2 * cos(rx) + z2cash * sin(rx);
//Z軸の回転量を反映
float x1cash = x1;
float x2cash = x2;
float y1cash = y1;
float y2cash = y2;
x1 = x1 * sin(rz) + y1cash * cos(rz);
x2 = x2 * sin(rz) + y2cash * cos(rz);
y1 = y1 * sin(rz) - x1cash * cos(rz);
y2 = y2 * sin(rz) - x2cash * cos(rz);
//透視変換
float x1b = width/2 + x1 * (camZ + z1) * tan(radS/2) / (scZ + z1) * tan(radS/2);
float y1b = height/2 + y1 * (camZ + z1) * tan(radS/2) / (scZ + z1) * tan(radS/2);
float x2b = width/2 + x2 * (camZ + z2) * tan(radS/2) / (scZ + z2) * tan(radS/2);
float y2b = height/2 + y2 * (camZ + z2) * tan(radS/2) / (scZ + z2) * tan(radS/2);
//描画開始位置を初期化
translate(0,0);
//線の色・太さ
stroke(strokeH, strokeS, strokeB);
strokeWeight(weight);
//描画
line(x1b,y1b,x2b,y2b);
}
2011
02/08
Music Boxel : Naked-eye 3D Display and Web Socket based multi user interaction
aircord社との協同プロジェクト Music Boxel のデモムービー(1分34秒)です。
Music Boxel from aircord on Vimeo.
関連記事
2011年1月17日 Music Boxel (裸眼3Dディスプレイ x WebSocketインターフェイス)
2011年2月7日 Music Boxel Prototype (Processing+PeasyCam)
2011年2月8日 Music Boxel@CreativeApplications.Net
Naked-eye 3D Display and Web Socket based multi user interaction.
Adding a voxel to make a trigger on roop timeline of virtual music box.
Display/Audio-Visual Program by aircord inc. made with : openFrameworks, SuperCollider
Server/Mobile Interface by Uniba Inc. made with : node.js, CSS3/HTML5
2011
02/08
Music Boxel@CreativeApplications.Net
CreativeApplications.Net 14879 February 7, 2011
Music Boxel [iPhone, iPad, openFrameworks]
http://www.creativeapplications.net/iphone/music-boxel-iphone-ipad/
取り上げていただきました!
ありがとございます!
2011
02/07
Music Boxel Prototype (Processing+PeasyCam)
こんばんは〜
Processingでスケッチするのは、楽しいですね!的な話として今日は、Music Boxelのプロトタイプのご紹介です。
本物のMusic Boxelのリアルタイム・ヴィジュアルオーディオはaircordの森氏によるopenFrameworks+SuperColliderのプログラムですが、ヴィジュアルの試作品はProcessingで書かれました。
開発中のMusic Boxelのヴィジュアル×オーディオを制作チーム内でイメージするために、「キューブ」が同心円状に4列になってぐるぐると周り、円周上の一定の角度(0度〜10度)にさしかかったときに「発光(発音)」しつつ「摩耗」する、というアイディアをProcessingでスケッチしました。
JavaApplet版はここに置いてあります。
Music Boxel Prototype (JavaApplet build with Processing)
Javaプラグインをブラウザに入れていない皆さまはこちらをどうぞ。 ↓ こんな感じです。
(動作中のJavaAppletをiPhoneでビデオ撮影したもの)
Processingのコードはこんな感じ。PeasyCamさえ入っていれば、手元のProcessingで動くと思います。
(PeasyCam、ありがとう!わたしのようなものぐさでも3Dでスケッチする気が起こります)
// 3Dカメラのコントロール用にpeasyを読み込んでいます。描画はOpenGL
import peasy.*;
import processing.opengl.*;
PeasyCam cam;
// キューブのサイズ初期値
float boxSize = 5;
// 4つの円周上に配置するキューブの数の初期値
int num = 4;
int num2 = 8;
int num3 = 4;
int num4 = 8;
// 4つの円の半径
float R = 5;
float R2 = 10;
float R3 = 15;
float R4 = 20;
// 4つの円の初期角度、回転スピード
float Rdiff = 0;
float Rspeed = 1;
float Rdiff2 = 0;
float Rspeed2 = 2;
float Rdiff3 = 0;
float Rspeed3 = 3;
float Rdiff4 = 0;
float Rspeed4 = 4;
void setup() {
size(500,500,OPENGL);
// 3Dカメラを作っています
cam = new PeasyCam(this, 100);
cam.setMinimumDistance(50);
cam.setMaximumDistance(500);
}
void draw() {
background(0);
// 角度を加算。4つの円を回転させています
Rdiff = Rdiff + Rspeed;
Rdiff2 = Rdiff2 + Rspeed2;
Rdiff3 = Rdiff3 + Rspeed3;
Rdiff4 = Rdiff4 + Rspeed4;
// 一番内側の円周上のキューブを描画
for(int i=0; i<num; i=i+1) {
// 現在の角度からキューブを配置する位置を決定しています
pushMatrix();
rotateZ(radians(360/num*i+Rdiff));
translate(R,0,0);
// "摩耗エリア(0〜10度)" にあるときに、キューブを "摩耗" させています。
// また白い輪郭を表示しています
if ((360/num*i+Rdiff)%360 < 10) {
stroke(255);
fill(255);
boxSize = boxSize*0.9;
box(boxSize*2);
noFill();
box(boxSize*3);
} else {
// "摩耗エリア" でないときは、通常の色で描画します
stroke(255,0,0);
fill(255,0,0);
}
// キューブを描画
box(boxSize);
popMatrix();
}
// 内側から二番目の円周上のキューブを描画
for(int i=0; i<num2; i=i+1) {
pushMatrix();
rotateZ(radians(360/num2*i+Rdiff2));
translate(R2,0,boxSize);
if ((360/num2*i+Rdiff2)%360 < 10) {
stroke(255);
fill(255);
boxSize = boxSize*0.9;
box(boxSize*2);
noFill();
box(boxSize*3);
} else {
stroke(0,255,0);
fill(0,255,0);
}
stroke(0,255,0);
box(boxSize);
popMatrix();
}
// 内側から三番目の円周上のキューブを描画
for(int i=0; i<num3; i=i+1) {
pushMatrix();
rotateZ(radians(360/num3*i+Rdiff3));
translate(R3,0,boxSize*2);
if ((360/num3*i+Rdiff3)%360 < 10) {
stroke(255);
fill(255);
boxSize = boxSize*0.9;
box(boxSize*2);
noFill();
box(boxSize*3);
} else {
stroke(0,0,255);
fill(0,0,255);
}
box(boxSize);
popMatrix();
}
// 一番外側の円周上のキューブを描画
for(int i=0; i<num4; i=i+1) {
pushMatrix();
rotateZ(radians(360/num4*i+Rdiff4));
translate(R4,0,boxSize*3);
if ((360/num4*i+Rdiff4)%360 < 10) {
stroke(255);
fill(255);
boxSize = boxSize*0.9;
box(boxSize*2);
noFill();
box(boxSize*3);
} else {
stroke(0,255,255);
fill(0,255,255);
}
box(boxSize);
popMatrix();
}
// キューブがある程度以上 "摩耗" したら、キューブの数、サイズをリセット
if (boxSize < 0.1) {
boxSize = 5;
num = round(random(8));
num2 = round(random(8));
num3 = round(random(8));
num4 = round(random(8));
}
}
MusicBoxelのデモ・ムービーは、近日、もうそろそろ公開予定…
2011
01/17
Music Boxel (裸眼3Dディスプレイ x WebSocketインターフェイス)
aircord社とユニバの協同プロジェクト「Music Boxel」のご紹介です。
MusicBoxelは、aircord社が開発したN-3Dという裸眼立体視ディスプレイと、スマートフォン・携帯電話用のリアルタイム通信を組み合わせた、実験プロジェクトです。手元のモバイル端末から、ウェブページ経由でディスプレイの中を回転する「オルゴール(Music Box)」の音を増やしたり、減らしたりするリアルタイム操作を実現しています。
紹介ムービーを準備しているのですが、そちらは近日公開予定。
また、各パートを担当したスタッフから技術紹介の記事をアップしていきます。
Music Boxel
Naked-eye 3D Display and Web Socket based multi user interaction.
Adding a voxel to make a trigger on roop timeline of virtual music box.
Display/Audio-Visual Program by aircord inc. made with : openFrameworks, SuperCollider
Server/Mobile Interface by Uniba Inc. made with : node.js, CSS3/HTML5







