クォータニオン実装
2008年4月21日
3D回転をクォータニオンでAS3で実装しました。
http://test3.sonicjam.co.jp/~ken/solarsystem/
ややわかりにくいんですがw
地球の周りを月がまわり、地球と月が太陽のまわりをまわる、というイメージです。
それぞれの回転軸が3次元で別々に設定されています。
まさにこういう軸中心の動きの場合はアフィン変換より数割(?)高速になります。たぶん。
参考:
http://www.microsoft.com/japan/msdn/academic/Articles/DirectX/01/
http://marupeke296.com/DXG_No10_Quaternion.html
http://staff.aist.go.jp/toru-nakata/quaternion.html
http://yamasv.blog92.fc2.com/blog-entry-49.html
http://ja.wikipedia.org/wiki/%E5%9B%9B%E5%85%83%E6%95%B0
http://www.nilab.info/wiki/Quaternion.html
ソースのメイン部分はこんな感じです。
-
package threeD
-
{
-
public class Quaternion
-
{
-
public var w:Number;
-
public var x:Number;
-
public var y:Number;
-
public var z:Number;
-
-
public function Quaternion()
-
{
-
// コンストラクタ
-
}
-
-
//
-
// 角度、ベクトル -> QT
-
//
-
public static function rotateQT( rad:Number, v:Vector3D ):Quaternion
-
{
-
var q:Quaternion = new Quaternion();
-
var s:Number = Math.sin( rad / 2.0 );
-
q.w = Math.cos( rad / 2.0 );
-
q.x = v.x * s;
-
q.y = v.y * s;
-
q.z = v.z * s;
-
return q;
-
}
-
-
//
-
// 座標 -> QT
-
//
-
public static function positionQT( x:Number, y:Number, z:Number ):Quaternion
-
{
-
var q:Quaternion = new Quaternion();
-
q.w = 0;
-
q.x = x;
-
q.y = y;
-
q.z = z;
-
return q;
-
}
-
-
//
-
// QT *s -> QT
-
//
-
public function multiplScalarQT( s:Number ):Quaternion
-
{
-
var q:Quaternion = new Quaternion();
-
q.w = w * s;
-
q.x = x * s;
-
q.y = y * s;
-
q.z = z * s;
-
return q;
-
}
-
-
//
-
// QT * QT -> QT
-
//
-
public function multiplyQT( q2:Quaternion ):Quaternion
-
{
-
var q:Quaternion = new Quaternion();
-
q.w = this.w * q2.w - this.x * q2.x - this.y * q2.y - this.z * q2.z;
-
q.x = this.y * q2.z - this.z * q2.y + this.w * q2.x + this.x * q2.w;
-
q.y = this.z * q2.x - this.x * q2.z + this.w * q2.y + this.y * q2.w;
-
q.z = this.x * q2.y - this.y * q2.x + this.w * q2.z + this.z * q2.w;
-
return q;
-
}
-
-
//
-
// QT + QT -> QT
-
//
-
public function addQT( q2:Quaternion ):Quaternion
-
{
-
var q:Quaternion = new Quaternion();
-
q.w = this.w + q2.w;
-
q.x = this.x + q2.x;
-
q.y = this.y + q2.y;
-
q.z = this.z + q2.z;
-
return q;
-
}
-
-
//
-
// QT -> 共役QT
-
//
-
public function conjugationQT():Quaternion
-
{
-
var q:Quaternion = new Quaternion();
-
q.w = this.w;
-
q.x = -this.x;
-
q.y = -this.y;
-
q.z = -this.z;
-
return q;
-
}
-
}
-
}
Flashで簡易シーケンサーつくりました。
http://test3.sonicjam.co.jp/~ken/sequence1/sequencer.html
使い方:
(1) BPMに適当な数字を入力する(デフォルト120)
(2) STARTボタンをクリックするとスライダーが動いて再生開始
(3) 各ボタンに各種サウンドが割り振られているので鳴らしたいところを選択する
(4) 完成したら、CREATEボタンをクリック。するとサーバ上でサウンドファイルを生成する
(5) download mp3リンクで作成したサウンドをダウンロードできます
備考:
Flash上で再生する際は、Timerイベントで音を鳴らしているだけなので、処理の正確さに欠ける。特にテンポが速いとぐちゃぐちゃだ。まあこのへんはあまり追及していないです。サーバー上でのサウンド合成をしたかっただけで、シーケンサーはそのための入力用につくっただけなので。
最終的に合成したmp3は正確なタイミングで合成されています。
今はmp3を生成していますが、最終的には携帯用の着メロを作成しようかと。まあこれから応用方法は考えます。
サーバー上のサウンド合成はCsoundを使用しています。
参照:
http://ja.wikipedia.org/wiki/Csound
http://www.sonicjam.co.jp/soniclabs/?p=55

