クォータニオン実装

2008年4月21日

solarsystem1.gif

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

ソースのメイン部分はこんな感じです。

Actionscript:
  1. package threeD
  2. {
  3.     public class Quaternion
  4.     {
  5.         public var w:Number;
  6.         public var x:Number;
  7.         public var y:Number;
  8.         public var z:Number;
  9.  
  10.         public function Quaternion()
  11.         {
  12.             // コンストラクタ
  13.         }
  14.  
  15.         //
  16.         // 角度、ベクトル -> QT
  17.         //
  18.         public static function rotateQT( rad:Number, v:Vector3D ):Quaternion
  19.         {
  20.             var q:Quaternion = new Quaternion();
  21.             var s:Number = Math.sin( rad / 2.0 );
  22.             q.w = Math.cos( rad / 2.0 );
  23.             q.x = v.x * s;
  24.             q.y = v.y * s;
  25.             q.z = v.z * s;
  26.             return q;
  27.         }
  28.        
  29.         //
  30.         // 座標 -> QT
  31.         //
  32.         public static function positionQT( x:Number, y:Number, z:Number ):Quaternion
  33.         {
  34.             var q:Quaternion = new Quaternion();
  35.             q.w = 0;
  36.             q.x = x;
  37.             q.y = y;
  38.             q.z = z;
  39.             return q;
  40.         }
  41.        
  42.         //
  43.         // QT *s -> QT
  44.         //
  45.         public function multiplScalarQT( s:Number ):Quaternion
  46.         {
  47.             var q:Quaternion = new Quaternion();
  48.             q.w = w * s;
  49.             q.x = x * s;
  50.             q.y = y * s;
  51.             q.z = z * s;
  52.             return q;
  53.         }
  54.        
  55.         //
  56.         // QT * QT -> QT
  57.         //
  58.         public function multiplyQT( q2:Quaternion ):Quaternion
  59.         {
  60.             var q:Quaternion = new Quaternion();
  61.             q.w = this.w * q2.w - this.x * q2.x - this.y * q2.y - this.z * q2.z;
  62.             q.x = this.y * q2.z - this.z * q2.y + this.w * q2.x + this.x * q2.w;
  63.             q.y = this.z * q2.x - this.x * q2.z + this.w * q2.y + this.y * q2.w;
  64.             q.z = this.x * q2.y - this.y * q2.x + this.w * q2.z + this.z * q2.w;
  65.             return q;
  66.         }
  67.        
  68.         //
  69.         // QT + QT -> QT
  70.         //
  71.         public function addQT( q2:Quaternion ):Quaternion
  72.         {
  73.             var q:Quaternion = new Quaternion();
  74.             q.w = this.w + q2.w;
  75.             q.x = this.x + q2.x;
  76.             q.y = this.y + q2.y;
  77.             q.z = this.z + q2.z;
  78.             return q;
  79.         }
  80.        
  81.         //
  82.         // QT -> 共役QT
  83.         //
  84.         public function conjugationQT():Quaternion
  85.         {
  86.             var q:Quaternion = new Quaternion();
  87.             q.w = this.w;
  88.             q.x = -this.x;
  89.             q.y = -this.y;
  90.             q.z = -this.z;
  91.             return q;
  92.         }
  93.     }
  94. }

投稿者:
ken

sequence1.gif

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

投稿者:
ken