Matrix3D.prependRotation()

by umhr forked from Matrix3D.prepend() (diff: 98)
Matrix3D.prependRotation();
と同じ機能の関数を作ってみる。
MAC 10,0,2,54,MAC 10,0,12,36で動作確認。

実体行列.prependRottion(角度,軸方向,回転の中心)


◆処理内容
appendとは行列乗算時の左右の順番が入れ替わっただけ。

◆確認方法
各要素をrandomで-100〜100の値を入れて、prependする。
小数点6桁目あたりから誤差が出る場合がある。
内部的な値の管理が根本的に違うのかも。

pivotPoint.x,y,zを1/20しているけど、なんでこうなるかはよくわかんない。

prependRotation
http://help.adobe.com/ja_JP/AS3LCR/Flash_10.0/flash/geom/Matrix3D.html#prependRotation()
AXIS_ANGLE
http://help.adobe.com/ja_JP/AS3LCR/Flash_10.0/flash/geom/Orientation3D.html#AXIS_ANGLE

♥0 | Line 101 | Modified 2009-02-14 20:24:37 | 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/ejMC
 */

/*
Matrix3D.prependRotation();
と同じ機能の関数を作ってみる。
MAC 10,0,2,54,MAC 10,0,12,36で動作確認。

実体行列.prependRottion(角度,軸方向,回転の中心)


◆処理内容
appendとは行列乗算時の左右の順番が入れ替わっただけ。

◆確認方法
各要素をrandomで-100〜100の値を入れて、prependする。
小数点6桁目あたりから誤差が出る場合がある。
内部的な値の管理が根本的に違うのかも。

pivotPoint.x,y,zを1/20しているけど、なんでこうなるかはよくわかんない。

prependRotation
http://help.adobe.com/ja_JP/AS3LCR/Flash_10.0/flash/geom/Matrix3D.html#prependRotation()
AXIS_ANGLE
http://help.adobe.com/ja_JP/AS3LCR/Flash_10.0/flash/geom/Orientation3D.html#AXIS_ANGLE

*/
package {
	import flash.display.Sprite;
	import flash.geom.Matrix3D;
	import flash.text.TextField;
	import flash.geom.Vector3D;
	import flash.system.Capabilities;
	public class FlashTest extends Sprite {
		public function FlashTest() {
			var txt:String="◆同機能関数Mtrx3D.prependRotation\n"+Capabilities.version +"での実行結果\n\n";
			
			//確認用の値を用意
			var entity:Matrix3D=new Matrix3D(Util.random16());
			var parameter:Matrix3D=new Matrix3D(Util.random16());
			var entity1:Matrix3D=entity.clone();
			var entity2:Matrix3D=entity.clone();
			var degrees:Number = Math.random()*360-180;
			var axis:Vector3D = new Vector3D(Math.random()-0.5,Math.random()-0.5,Math.random()-0.5);
			var pivotPoint:Vector3D = new Vector3D(Math.random()*200-100,Math.random()*200-100,Math.random()*200-100);
			axis.normalize();
			
			//実行
			entity1.prependRotation(degrees,axis);
			Mtrx3D.prependRotation(entity2,degrees,axis);
			
			//確認
			var entity1RawData:Vector.<Number>=entity1.rawData;
			txt+="↓Matrix3D.prependRotationの結果\n"+entity1RawData+"\n";
			var entity2RawData:Vector.<Number>=entity2.rawData;
			txt+="\n↓同機能関数Mtrx3D.prependRotationの結果\n"+entity2RawData+"\n\n";
			
			txt+=Util.hikaku(entity1RawData,entity2RawData);
			
			
			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;
	public static function prependRotation(entity:Matrix3D,degrees:Number,axis:Vector3D,pivotPoint:Vector3D=null):void {
		if(!pivotPoint){
			pivotPoint = new Vector3D(0,0,0);
		}
		axis.normalize();
		var w:Number = Math.cos(degrees/360*Math.PI);
		var x:Number = Math.sin(degrees/360*Math.PI)*axis.x;
		var y:Number = Math.sin(degrees/360*Math.PI)*axis.y;
		var z:Number = Math.sin(degrees/360*Math.PI)*axis.z;
		var p:Vector.<Number> = new Vector.<Number>(16,true);
		p[0] = (w*w+x*x-y*y-z*z);
		p[1] = 2*(y*x+w*z);
		p[2] = 2*(z*x-w*y);
		p[3] = 0;
		p[4] = 2*(y*x-w*z);
		p[5] = (w*w-x*x+y*y-z*z);
		p[6] = 2*(w*x+z*y);
		p[7] = 0;
		p[8] = 2*(z*x+w*y);
		p[9] = 2*(z*y-w*x);
		p[10] = (w*w-x*x-y*y+z*z);
		p[11] = 0;
		p[12] = 0;
		p[13] = 0;
		p[14] = 0;
		p[15] = (x*x+y*y+z*z+w*w);
		var e:Vector.<Number> = entity.rawData;
		var ep:Vector.<Number> = new Vector.<Number>(16,true);
		ep[0] = e[0]*p[0]+e[4]*p[1]+e[8]*p[2]+e[12]*p[3];
		ep[1] = e[1]*p[0]+e[5]*p[1]+e[9]*p[2]+e[13]*p[3];
		ep[2] = e[2]*p[0]+e[6]*p[1]+e[10]*p[2]+e[14]*p[3];
		ep[3] = e[3]*p[0]+e[7]*p[1]+e[11]*p[2]+e[15]*p[3];
		ep[4] = e[0]*p[4]+e[4]*p[5]+e[8]*p[6]+e[12]*p[7];
		ep[5] = e[1]*p[4]+e[5]*p[5]+e[9]*p[6]+e[13]*p[7];
		ep[6] = e[2]*p[4]+e[6]*p[5]+e[10]*p[6]+e[14]*p[7];
		ep[7] = e[3]*p[4]+e[7]*p[5]+e[11]*p[6]+e[15]*p[7];
		ep[8] = e[0]*p[8]+e[4]*p[9]+e[8]*p[10]+e[12]*p[11];
		ep[9] = e[1]*p[8]+e[5]*p[9]+e[9]*p[10]+e[13]*p[11];
		ep[10] = e[2]*p[8]+e[6]*p[9]+e[10]*p[10]+e[14]*p[11];
		ep[11] = e[3]*p[8]+e[7]*p[9]+e[11]*p[10]+e[15]*p[11];
		ep[12] = e[0]*p[12]+e[4]*p[13]+e[8]*p[14]+e[12]*p[15]+pivotPoint.x/20;
		ep[13] = e[1]*p[12]+e[5]*p[13]+e[9]*p[14]+e[13]*p[15]+pivotPoint.y/20;
		ep[14] = e[2]*p[12]+e[6]*p[13]+e[10]*p[14]+e[14]*p[15]+pivotPoint.z/20;
		ep[15] = e[3]*p[12]+e[7]*p[13]+e[11]*p[14]+e[15]*p[15];
		entity.rawData = ep;
	}
}
class Util {
	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 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;
	}
}

Forked