Matrix3D.determinant

determinantMatrix3D.determinantプロパティについて
http://help.adobe.com/ja_JP/AS3LCR/Flash_10.0/flash/geom/Matrix3D.html#determinant

実体行列.determinant

処理としては
余因子(cofactor)を作り、
サルス(Sarrus)の公式(関-サルスの公式)で
行列式(determinant)を求める。

20倍のバグがあるようで、ちゃんとやっても計算が合わない。
とりあえず実用上問題ないように適当に補正している。
普通は、0か0じゃないかの判別だけで使うので、実用上問題ないはず。
 
 
◆関連項目
Matrix3D.invert()
 
 
◆動作確認

▼ActionScript AS3(FP10)
[sourcecode language=”as3″]
/*
Matrix3D.determinant;
と同じ機能の関数を作ってみる。
MAC 10,0,2,54,MAC 10,0,12,36で動作確認。

実体行列.determinant

処理としては
余因子(cofactor)を作り、
サルス(Sarrus)の公式(関-サルスの公式)で
行列式(determinant)を求める。

各要素をrandomで値を入れて、determinantし、
比較して確認とした。

ちゃんとやっても計算が合わない。

とりあえず実用上問題ないように適当に補正している。

Matrix3D.invert()
の際につかう処理と全く同じで、
そっちのほうは問題ないのになー
適当に20倍した方が、値が近くなる。やっぱ、バグなような、、、。
あと、符号も逆にしてる。

普通は、0か0じゃないかの判別だけで使うので、実用上問題ないはず、、、、。

Matrix3D.determinant
http://help.adobe.com/ja_JP/AS3LCR/Flash_10.0/flash/geom/Matrix3D.html#determinant
*/
package {
import flash.display.Sprite;
import flash.geom.Matrix3D;
import flash.geom.Orientation3D;
import flash.text.TextField;
import flash.geom.Vector3D;
import flash.system.Capabilities;
public class FlashTest extends Sprite {
public function FlashTest() {
var txt:String="◆同機能関数Mtrx3D.determinant "+Capabilities.version+"での実行結果\n\n";

//確認用の値を用意
var entity:Matrix3D=new Matrix3D(Util.random9());

//実行
var d1:Number = entity.determinant;
var d2:Number = Mtrx3D.determinant(entity);

//確認
txt+="↓Matrix3D.determinantの結果\n"+d1+"\n";
txt+="\n↓同機能関数Mtrx3D.determinantの結果\n"+d2+"\n\n";
txt+="↓二つの値の差\n";
txt+=d1-d2;

//テキストフィールドを作りtxtを流し込み。
var tf:TextField = new TextField();
tf.width=stage.stageWidth;
tf.height=stage.stageHeight;
tf.wordWrap=true;
stage.addChild(tf);
tf.text=txt;
}
}
}
import flash.display.Sprite;
class Mtrx3D extends Sprite {
import flash.geom.Matrix3D;
import flash.geom.Vector3D;
import flash.system.Capabilities;
public static function determinant(entity:Matrix3D):Number{
//だいたいできた
//行列式の展開公式
var e:Vector.<Number> = Vector.<Number>(entity.rawData);
e[12] *=20;
e[13] *=20;
e[14] *=20;
//余因子(cofactor)を作る
var d:Number = e[0]*sarrus([e[5],e[9],e[13],e[6],e[10],e[14],e[7],e[11],e[15]]);
//dはdeterminantから
d -= e[1]*sarrus([e[4],e[8],e[12],e[6],e[10],e[14],e[7],e[11],e[15]]);
d += e[2]*sarrus([e[4],e[8],e[12],e[5],e[9],e[13],e[7],e[11],e[15]]);
d -= e[3]*sarrus([e[4],e[8],e[12],e[5],e[9],e[13],e[6],e[10],e[14]]);
d -= ((e[4]-e[8])*e[1]+(e[9]-e[5])*e[0])*e[11]*e[14];
return -d;
function sarrus(c:Array):Number{
//cはcofactorから
//サルス(Sarrus)の公式(関-サルスの公式)
return c[0]*c[4]*c[8]+c[3]*c[7]*c[2]+c[6]*c[1]*c[5]
-c[6]*c[4]*c[2]-c[3]*c[1]*c[8]-c[0]*c[7]*c[5];
}
//http://www22.atwiki.jp/linearalgebra/pages/21.html
//http://www.snap-tck.com/room04/c01/matrix/matrix08.html
}
}
class Util {
import flash.geom.Matrix3D;
import flash.geom.Vector3D;
public static function hikaku(v0:Vector.<Number>,v1:Vector.<Number>):String {
var _str:String="↓二つのMatrix3Dの要素毎の差\n";
var _n:int=v0.length;
for (var i:int=0; i<_n; i++) {
_str += "["+i+"]:"+(v0[i]-v1[i])+"\n";
}
return _str;
}
public static function hikaku2(v0:Vector3D,v1:Vector3D):String {
var _str:String="↓二つのVector3Dの要素毎の差\n";
_str += ".x:"+(v0.x-v1.x)+"\n";
_str += ".y:"+(v0.y-v1.y)+"\n";
_str += ".z:"+(v0.z-v1.z)+"\n";
_str += ".w:"+(v0.w-v1.w)+"\n";
return _str;
}

public static function random16():Vector.<Number> {
var _v:Vector.<Number>=new Vector.<Number>(16,true);
for (var i:int=0; i<16; i++) {
_v[i]=Math.random()*200-100;
}
return _v;
}
public static function random9():Vector.<Number> {
var _mt:Matrix3D = new Matrix3D();
var v:Vector.<Vector3D>=new Vector.<Vector3D> ;
v[0]=new Vector3D(200*Math.random()-100,200*Math.random()-100,200*Math.random()-100);//平行移動、
v[1]=new Vector3D(10*Math.random()-5,10*Math.random()-5,10*Math.random()-5);//回転
v[2]=new Vector3D(100*Math.random(),100*Math.random(),100*Math.random());//拡大 / 縮小
_mt.recompose(v);
return _mt.rawData;
}
}
[/sourcecode]