Matrix3D.determinant

by umhr forked from Matrix3D.transpose() (diff: 69)
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
♥0 | Line 84 | Modified 2009-02-16 21:26:24 | MIT License
play

ActionScript3 source code

/**
 * Copyright umhr ( http://wonderfl.net/user/umhr )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/z9rQ
 */

/*
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;
	}
}

Forked