Matrix3D.appendRotation()

Matrix3D.appendRotation()Matrix3D. appendRotation()と同じ計算の関数を作ってみる。
appendRotation(degrees:Number, axis:Vector3D, pivotPoint:Vector3D = null):void

▼Wonderfl

いろいろ

Matrix3D.appendRotation();
と同じ機能の関数を作ってみる。

各要素をrandomで値を入れて、appendRotationする。

赤い四角がビルトイン関数の計算結果。
青い丸が同機能関数(mtrx3D)の計算結果。

ビルトイン関数のほう、axisが単位ベクトルで無い場合、
どういう計算をしているのかがわからなかった。
クオータニオンとか軸角度の計算の場合は単位ベクトルにするのが
セオリーなんだから、自動的に単位ベクトル化してもいいくらいだと
思うんだけど、そうはなっていない。

あと、10,0,22,87より前のプラグインバグがあったので、
ところどころ1/20している。
↓これの話。
http://wonderfl.net/code/f38acee5dab57b47ee85f2c46a961f48b7d092a7

値を比較すると、小数点4桁以下の誤差が出ることがあるが、
これは恐らく、Marix3Dでは計算速度を高めるために、
値のテーブルを作って、参照させていると予想。
↓こんなふうに
http://wonderfl.net/code/659d1427c67d807afd7a52273ac54e9aba086261

ちなみに、helpにある、
myObject.z = 1;
myObject.transform.matrix3D.appendTranslation(10,10,0);
myObject.transform.matrix3D.appendRotation(1, Vector3D.YAXIS);
myObject.transform.matrix3D.appendTranslation(-10,-10,0);

これは

myObject.z = 1;
myObject.transform.matrix3D.position = new Vector3D();
myObject.transform.matrix3D.appendRotation(1, Vector3D.YAXIS,new Vector3D(-10,-10,0));

ともかける、はず。

計算内容

Matrix3D.appendRotation()メソッドについて
http://help.adobe.com/ja_JP/AS3LCR/Flash_10.0/flash/geom/Matrix3D.html#appendRotation()

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

処理の流れとしては以下。
・0)パラメーター(角度と軸方向=AXIS_ANGLE)

・1)AXIS_ANGLEのQUATERNION化

・2)QUATERNIONの行列化

・3)entity行列と上で求められたパラメーター行列でappendする。

となる。
 
 
・0)パラメーター(角度と軸方向=AXIS_ANGLE)

このパラメーターの角度と軸方向はAXIS_ANGLEという。
軸方向(axis)のxyzと 1 つの角度(degrees)で表すので、
QUATERNIONぽいけど、ちょっと違うみたい。
参考:「実例で学ぶゲーム3D数学」オライリージャパン社、P161

 
 
・1)AXIS_ANGLEのQUATERNION化

AXIS_ANGLEからQUATERNIONを生成するメソッドを作るとしたらこんな感じになる(未検証)。
注:下記AxisAngle.wはラジアンだが、Mtrx.appendRotation()ではdegreesなので若干異なる。
[code lang=”actionscript3″ tab_size=”2″ width=”600″]
function AXIS_ANGLEtoQUATERNION(AxisAngle:Vector3D):Vector3D {
var Quaternion:Vector3D = new Vector3D();
Quaternion.w = Math.cos(AxisAngle.w/2);
Quaternion.x = Math.sin(AxisAngle.w/2) * AxisAngle.x;
Quaternion.y = Math.sin(AxisAngle.w/2) * AxisAngle.y;
Quaternion.z = Math.sin(AxisAngle.w/2) * AxisAngle.z;
return Quaternion;
}
[/code]
 
 
・2)QUATERNIONの行列化

QUATERNIONを行列にするのはちょっとめんどくさい。
まずは↓このblogエントリーを参考にしてクオータニオン(の計算)を理解する。
Zで行こう!:アイテムの回転をクオータニオンで表す
http://blog.livedoor.jp/take_z_ultima/archives/51383303.html

「実際の計算」のところが、x,y,zの座標を求める用に書かれているが、
Matrix3Dの4行4列の行列を作るにはwのぶんも必要なため、計算し直し。
 
i,j,kは虚数で、ii=jj=kk=-1 ij=k jk=i ki=j ji=-k kj=-i ik=-jという関係を持っている。

練習問題

q1 = w1+x1i+y1j+z1k
q2 = w2+x2i+y2,j+z2k

q1、q2を乗算してみる

q1q2
=w1w2+x1w2i+y1w2j+z1w2k
+w1x2i+x1x2ii+y1x2ji+z1x2ki
+w1y2j+x1y2ij+y1y2jj+z1y2kj
+w1z2k+x1z2ik+y1z2jk+z1z2kk
(w,x,y,zの部分は実数なので左右入れ替えてもいいが、ijkは交換法則が成り立ってないので気をつける)

これに上記の虚数の関係をあてはめる。

=w1w2+x1w2i+y1w2j+z1w2k
+w1x2i+x1x2(-1)+y1x2(-k)+z1x2(j)
+w1y2j+x1y2(k)+y1y2(-1)+z1y2(-i)
+w1z2k+x1z2(-j)+y1z2(i)+z1z2(-1)

整理する

=w1w2+x1w2i+y1w2j+z1w2k
+w1x2i-x1x2-y1x2k+z1x2j
+w1y2j+x1y2k-y1y2-z1y2i
+w1z2k-x1z2j+y1z2i-z1z2

並べ替える

=w1w2-x1x2-y1y2-z1z2
+x1w2i+w1x2i-z1y2i+y1z2i
+y1w2j+z1x2j+w1y2j-x1z2j
+z1w2k-y1x2k+x1y2k+w1z2k

まとめる

=w1w2-x1x2-y1y2-z1z2
+(x1w2+w1x2-z1y2+y1z2)i
+(y1w2+z1x2+w1y2-x1z2)j
+(z1w2-y1x2+x1y2+w1z2)k

となる。
 
ここまでは練習問題。
 
 
肝心のクオータニオンの行列化は以下

q1 = w+xi+yj+zk
P = m + ai + bj + ck
q2 = w-xi-y,j-zk

q1Pq2を求めるために、まずは前半のq1Pを求める。

q1P
=w*m-x*a-y*b-z*c
+(w*a+x*m+y*c-z*b)i
+(w*b-x*c+y*m+z*a)j
+(w*c+x*b-y*a+z*m)k

計算が面倒なので各実数部分をまとめ

A = w*m-x*a-y*b-z*c
B = w*a+x*m+y*c-z*b
C = w*b-x*c+y*m+z*a
D = w*c+x*b-y*a+z*m
とすると
q1P = A+Bi+Cj+Dk
となる。

これにq2を乗算すると

q1Pq2
= A*w+B*x+C*y+D*z
+ (-A*x+B*w-C*z+D*y)i
+ (-A*y+B*z+C*w-D*x)j
+ (-A*z-B*y+C*x+D*w)k

各実数部分をまとめる

A*w+B*x+C*y+D*z
= (w*x+z*y-y*z-x*w)*a+(-z*x+w*y+x*z-y*w)*b+(y*x-x*y+w*z-z*w)*c+(x*x+y*y+z*z+w*w)*m
= 0*a+0*b+0*c+(x*x+y*y+z*z+w*w)*d

-A*x+B*w-C*z+D*y
= (x*x-z*z-y*y+w*w)*a+(y*x+x*y-w*z-z*w)*b+(z*x+w*y+x*z+y*w)*c+(-w*x+z*y-y*z+x*w)*m
= (w*w+x*x-y*y-z*z)*a+2*(y*x-w*z)*b+2*(z*x+w*y)*c+0*d

-A*y+B*z+C*w-D*x
= (y*x+x*y+w*z+z*w)*a+(-x*x+y*y-z*z+w*w)*b+(-w*x+z*y+y*z-x*w)*c+(-z*x-w*y+x*z+y*w)*m
= 2*(y*x+w*z)*a+(w*w-x*x+y*y-z*z)*b+2*(z*y-w*x)*c+0*d

-A*z-B*y+C*x+D*w
= (z*x-w*y+x*z-y*w)*a+(w*x+z*y+y*z+x*w)*b+(-x*x-y*y+z*z+w*w)*c+(y*x-x*y-w*z+z*w)*m
= 2*(z*x-w*y)*a+2*(w*x+z*y)*b+(w*w-x*x-y*y+z*z)*c+0*d

これらの式は行列で表すことができる。
注:上の式では(w,x,y,z)の順番になっているが、Matrix3dでは(x,y,z,w)で計算するためちょっと順番を入れ替える。

umhr_appendrotation


これで行列ができた。
[sourcecode language=”as3″]
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);
[/sourcecode]
 

・3)entity行列と上で求められたパラメーター行列でappendする。

あとは基本的にappend()と同じで、pivotPointのぶんだけ加えてあげれば完成。
 
 

参考

AXIS_ANGLE
http://help.adobe.com/ja_JP/AS3LCR/Flash_10.0/flash/geom/Orientation3D.html#AXIS_ANGLE
日本語では「軸回転」。axisは単位ベクトルで表すので、axis.normalize()をする。
Mtrx.appendRotation()では事前に単位ベクトル化しておかないと誤差が大きくなる。

ここも参考になりそう:http://yaneu.com/yaneurao/3dcg/funda01.html
 
 

ActionScript AS3(FP10)

[sourcecode language=”as3″]
/*
Matrix3D.appendRotation();
と同じ機能の関数を作ってみる。

各要素をrandomで値を入れて、appendRotationする。

赤い四角がビルトイン関数の計算結果。
青い丸が同機能関数(mtrx3D)の計算結果。

ビルトイン関数のほう、axisが単位ベクトルで無い場合、
どういう計算をしているのかがわからなかった。
クオータニオンとか軸角度の計算の場合は単位ベクトルにするのが
セオリーなんだから、自動的に単位ベクトル化してもいいくらいだと
思うんだけど、そうはなっていない。

あと、10,0,22,87より前のプラグインバグがあったので、
ところどころ1/20している。
↓これの話。
http://wonderfl.net/code/f38acee5dab57b47ee85f2c46a961f48b7d092a7

値を比較すると、小数点4桁以下の誤差が出ることがあるが、
これは恐らく、Marix3Dでは計算速度を高めるために、
値のテーブルを作って、参照させていると予想。
↓こんなふうに
http://wonderfl.net/code/659d1427c67d807afd7a52273ac54e9aba086261

ちなみに、helpにある、
myObject.z = 1;
myObject.transform.matrix3D.appendTranslation(10,10,0);
myObject.transform.matrix3D.appendRotation(1, Vector3D.YAXIS);
myObject.transform.matrix3D.appendTranslation(-10,-10,0);

これは

myObject.z = 1;
myObject.transform.matrix3D.position = new Vector3D();
myObject.transform.matrix3D.appendRotation(1, Vector3D.YAXIS,new Vector3D(-10,-10,0));

ともかける、はず。

【参考】
http://help.adobe.com/ja_JP/AS3LCR/Flash_10.0/flash/geom/Matrix3D.html#appendRotation()
*/
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.geom.Matrix3D;
import flash.text.TextField;
import flash.geom.Vector3D;
import flash.system.Capabilities;
import flash.utils.Timer;
public class Main extends Sprite {
private var builtinStage:Sprite = Create.newSprite( { x:stage.stageWidth / 2, y:stage.stageWidth/2 } );
private var mtrx3DStage:Sprite = Create.newSprite( { x:stage.stageWidth / 2, y:stage.stageWidth/2 } );
//ビルトイン関数用の赤い四角
private var builtinRect:Sprite = Create.newSprite( { z:0 }, Create.drawRect( { x: -50, y: -50, width:100, height:100, color:0xFF0000 , alpha:0.5 } ));
//同機能関数(mtrx3D)用の青い丸
private var mtrx3DRect:Sprite = Create.newSprite( { z:0 }, Create.drawCircle( { radius:50, color:0x0000FF , alpha:0.5 } ));
private var tf:TextField = Create.newTextField( { width:stage.stageWidth, height:stage.stageHeight, wordWrap:true } );
//確認用の値を用意
private var builtinEntity:Matrix3D=new Matrix3D();
private var mtrx3DEntity:Matrix3D=new Matrix3D();
public function Main() {

addChild(tf);
addChild(builtinStage);
addChild(mtrx3DStage);
builtinStage.addChild(builtinRect);
mtrx3DStage.addChild(mtrx3DRect);

var myTimer:Timer = new Timer(1000);
myTimer.addEventListener(TimerEvent.TIMER, TIMER);
myTimer.start();
addEventListener(Event.ENTER_FRAME, ENTER_FRAME);
}
private function setTex():void {
var txt:String = "◆同機能関数Mtrx3D.appendRotation" + Capabilities.version + "での実行結果\n\n";
var builtinRawData:Vector.<Number>=builtinEntity.rawData;
txt+="↓Matrix3D.appendRotationの結果\n"+builtinRawData+"\n";
var mtrx3DRawData:Vector.<Number>=mtrx3DEntity.rawData;
txt+="\n↓同機能関数Mtrx3D.appendRotationの結果\n"+mtrx3DRawData+"\n\n";
txt+=Util.hikaku(builtinRawData,mtrx3DRawData);
tf.text = txt;
}

private function TIMER(e:TimerEvent):void {
if (Math.random() < 0.2) {
//たまには初期化してやらないと、画面から外れ続けてしまうので。
builtinEntity.identity();
mtrx3DEntity.identity();
}
var degrees:Number = Math.random() * 720 – 360;
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);

//normalizeしないと、同一の計算結果にならない。
//ビルトイン関数の方は、normalizeしない場合
axis.normalize();
//計算
Mtrx3D.appendRotation(mtrx3DEntity, degrees, axis, pivotPoint);
builtinEntity.appendRotation(degrees, axis, pivotPoint);
setTex();
}
private function ENTER_FRAME(e:Event):void {
builtinRect.transform.matrix3D.interpolateTo(builtinEntity, 0.1);
mtrx3DRect.transform.matrix3D.interpolateTo(mtrx3DEntity, 0.1);
}
}
}

class Mtrx3D{
import flash.geom.Matrix3D;
public static function appendRotation(entity:Matrix3D,degrees:Number,axis:Vector3D,pivotPoint:Vector3D=null):void {
if(!pivotPoint){
pivotPoint = new Vector3D(0,0,0);
}
var _axis:Vector3D = axis.clone();
//_axis.normalize();

//AXIS_ANGLE to QUATERNION
var degreesPIper360:Number = degrees/360*Math.PI;
var w:Number = Math.cos(degreesPIper360);
var x:Number = Math.sin(degreesPIper360)*_axis.x;
var y:Number = Math.sin(degreesPIper360)*_axis.y;
var z:Number = Math.sin(degreesPIper360) * _axis.z;

//QUATERNION to Matrix
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] = 1;

//Matrix * entity
var e:Vector.<Number> = entity.rawData;
var pe:Vector.<Number> = new Vector.<Number>(16, true);
//バグ対応。10,0,22,87未満の場合バグを含むように。
var bug:int = 1;
if(Util.version() <1000022087){
bug = 20;
}
pe[0] = p[0]*e[0]+p[4]*e[1]+p[8]*e[2]+p[12]*e[3];
pe[1] = p[1]*e[0]+p[5]*e[1]+p[9]*e[2]+p[13]*e[3];
pe[2] = p[2]*e[0]+p[6]*e[1]+p[10]*e[2]+p[14]*e[3];
pe[3] = p[3]*e[0]+p[7]*e[1]+p[11]*e[2]+p[15]*e[3];
pe[4] = p[0]*e[4]+p[4]*e[5]+p[8]*e[6]+p[12]*e[7];
pe[5] = p[1]*e[4]+p[5]*e[5]+p[9]*e[6]+p[13]*e[7];
pe[6] = p[2]*e[4]+p[6]*e[5]+p[10]*e[6]+p[14]*e[7];
pe[7] = p[3]*e[4]+p[7]*e[5]+p[11]*e[6]+p[15]*e[7];
pe[8] = p[0]*e[8]+p[4]*e[9]+p[8]*e[10]+p[12]*e[11];
pe[9] = p[1]*e[8]+p[5]*e[9]+p[9]*e[10]+p[13]*e[11];
pe[10] = p[2]*e[8]+p[6]*e[9]+p[10]*e[10]+p[14]*e[11];
pe[11] = p[3]*e[8]+p[7]*e[9]+p[11]*e[10]+p[15]*e[11];
pe[12] = p[0]*e[12]+p[4]*e[13]+p[8]*e[14]+p[12]*e[15]+pivotPoint.x/bug;
pe[13] = p[1]*e[12]+p[5]*e[13]+p[9]*e[14]+p[13]*e[15]+pivotPoint.y/bug;
pe[14] = p[2]*e[12]+p[6]*e[13]+p[10]*e[14]+p[14]*e[15]+pivotPoint.z/bug;
pe[15] = p[3]*e[12]+p[7]*e[13]+p[11]*e[14]+p[15]*e[15];
entity.rawData = pe;
}
}

import flash.geom.Matrix3D;
import flash.geom.Vector3D;
class Util {
import flash.system.Capabilities;
public static function version():uint{
var ver_array:Array = Capabilities.version.substr(4).split(",");
return int(ver_array[0])*100000000+int(ver_array[1])*1000000+int(ver_array[2])*1000+int(ver_array[3]);
}

public static function hikaku(v0:Vector.<Number>,v1:Vector.<Number>):String {
var _str:String="↓二つのMatrixの要素毎の差\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;
}
public static function randomMatrix3D():Matrix3D{
var mt:Matrix3D = new Matrix3D();
var v:Vector.<Vector3D>=new Vector.<Vector3D>(3);
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(3 * Math.random(), 3 * Math.random(), 3 * Math.random());//拡大 / 縮小
mt.recompose(v);
return new Matrix3D(mt.rawData);
}
}

import flash.display.DisplayObject;
import flash.display.Graphics;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.TextFormat;
import flash.display.Sprite;
import flash.display.Shape;
import flash.display.SimpleButton;

class Create{
public static var defaultTextFormat:TextFormat = new TextFormat();

public static function newSimpleButton(x_y_w_h_txt:Array = null,property:Array=null,graphics:Array=null):SimpleButton{

var _x:Number = x_y_w_h_txt[0];
var _y:Number = x_y_w_h_txt[1];
var _width:Number = x_y_w_h_txt[2];
var _height:Number = x_y_w_h_txt[3];
var _text:String = x_y_w_h_txt[4];

var upState:Sprite = newSprite({x:_x,y:_y},{graphics:toDrawRect({color:0xCCCCCC,width:_width,height:_height,round:8})});
upState.addChild(newShape({x:2,y:2},{graphics:toDrawRect({color:0xE5E5E5,width:_width-4,height:_height-4,round:6})}));
var overState:Sprite = newSprite({x:_x,y:_y},{graphics:toDrawRect({color:0xBBBBBB,width:_width,height:_height,round:8})});
overState.addChild(newShape({x:2,y:2},{graphics:toDrawRect({color:0xEEEEEE,width:_width-4,height:_height-4,round:6})}));
var downState:Sprite = newSprite({x:_x,y:_y},{graphics:toDrawRect({color:0xAAAAAA,width:_width,height:_height,round:8})});
downState.addChild(newShape({x:2,y:2},{graphics:toDrawRect({color:0xDDDDDD,width:_width-4,height:_height-4,round:6})}));
var hitTestState:Shape = newShape({x:_x,y:_y},{graphics:toDrawRect({width:_width,height:_height,round:8})});

if(x_y_w_h_txt[4]){
upState.addChild(newTextField({x:0,y:2,width:x_y_w_h_txt[2],height:x_y_w_h_txt[3]-2,text:x_y_w_h_txt[4],setTextFormat:[{font:"_sans",align:"center"}]}));
overState.addChild(newTextField({x:0,y:2,width:x_y_w_h_txt[2],height:x_y_w_h_txt[3]-2,text:x_y_w_h_txt[4],setTextFormat:[{font:"_sans",align:"center"}]}));
downState.addChild(newTextField({x:0,y:3,width:x_y_w_h_txt[2],height:x_y_w_h_txt[3]-3,text:x_y_w_h_txt[4],setTextFormat:[{font:"_sans",align:"center"}]}));
}
var sb:SimpleButton = new SimpleButton(upState,overState,downState,hitTestState);

return sb;
}
public static function toDrawRect(… args):Array{
var _x:Number = args[0]["x"]?args[0]["x"]:0;
var _y:Number = args[0]["y"]?args[0]["y"]:0;
var _width:Number = args[0]["width"]?args[0]["width"]:100;
var _height:Number = args[0]["height"]?args[0]["height"]:100;
var _color:Number = args[0]["color"]?args[0]["color"]:0xFF0000;
var _alpha:Number = args[0]["alpha"]?args[0]["alpha"]:1;
var _round:Number = args[0]["round"]?args[0]["round"]:0;
var _lineSize:Number = args[0]["lineSize"]?args[0]["lineSize"]:0;
var _lineColor:Number = args[0]["lineColor"]?args[0]["lineColor"]:0;
var _lineAlpha:Number = args[0]["lineAlpha"]?args[0]["lineAlpha"]:0;
var _ellipseWidth:Number = args[0]["ellipseWidth"]?args[0]["ellipseWidth"]:_round;
var _ellipseHeight:Number = args[0]["ellipseHeight"]?args[0]["ellipseHeight"]:_ellipseWidth;
return [{beginFill:[_color,_alpha]},{drawRoundRect:[_x,_y,_width,_height,_ellipseWidth,_ellipseHeight]}];
}
public static function drawRect(… args):Object{
var _x:Number = args[0]["x"]?args[0]["x"]:0;
var _y:Number = args[0]["y"]?args[0]["y"]:0;
var _width:Number = args[0]["width"]?args[0]["width"]:100;
var _height:Number = args[0]["height"]?args[0]["height"]:100;
var _color:Number = args[0]["color"]?args[0]["color"]:0xFF0000;
var _alpha:Number = args[0]["alpha"]?args[0]["alpha"]:1;
var _round:Number = args[0]["round"]?args[0]["round"]:0;
var _lineSize:Number = args[0]["lineSize"]?args[0]["lineSize"]:0;
var _lineColor:Number = args[0]["lineColor"]?args[0]["lineColor"]:0;
var _lineAlpha:Number = args[0]["lineAlpha"]?args[0]["lineAlpha"]:0;
var _ellipseWidth:Number = args[0]["ellipseWidth"]?args[0]["ellipseWidth"]:_round;
var _ellipseHeight:Number = args[0]["ellipseHeight"]?args[0]["ellipseHeight"]:_ellipseWidth;
var resultObj:Object;
if(_round || _ellipseWidth || _ellipseHeight){
resultObj = { graphics:[ { beginFill:[_color, _alpha] }, { drawRoundRect:[_x, _y, _width, _height, _ellipseWidth, _ellipseHeight] } ] };
}else {
resultObj = { graphics:[ { beginFill:[_color, _alpha] }, { drawRect:[_x, _y, _width, _height] } ] };
}
return resultObj;
}
public static function drawCircle(… args):Object{
var _x:Number = args[0]["x"]?args[0]["x"]:0;
var _y:Number = args[0]["y"]?args[0]["y"]:0;
var _color:Number = args[0]["color"]?args[0]["color"]:0xFF0000;
var _alpha:Number = args[0]["alpha"]?args[0]["alpha"]:1;
var _r:Number = args[0]["r"]?args[0]["r"]:100;
var _radius:Number = args[0]["radius"]?args[0]["radius"]:_r;
var _width:Number = args[0]["width"]?args[0]["width"]:_radius;
var _height:Number = args[0]["height"]?args[0]["height"]:_radius;
var _lineSize:Number = args[0]["lineSize"]?args[0]["lineSize"]:0;
var _lineColor:Number = args[0]["lineColor"]?args[0]["lineColor"]:0;
var _lineAlpha:Number = args[0]["lineAlpha"]?args[0]["lineAlpha"]:0;
var resultObj:Object;
if(_width == _height){
resultObj = { graphics:[ { beginFill:[_color, _alpha] }, { drawCircle:[_x, _y, _radius] } ] };
}else {
resultObj = { graphics:[ { beginFill:[_color, _alpha] }, { drawEllipse:[_x, _y, _width, _height] } ] };
}
return resultObj;
}

public static function newShape(… args):Shape{
var sp:Shape;
var _str:String;
var _length:int = args.length;
for (var i:int = 0; i < _length; i++) {
var _obj:Object = args[i];
if(i == 0){
if(_obj.Shape){
sp = _obj.Shape;
}else{
sp = new Shape();
}
}
if(_obj.graphics){
for (var j:int = 0; j < _obj.graphics.length; j++) {
if(_obj.graphics[j]){
for (_str in _obj.graphics[j]) {
//trace(_str,_obj.graphics[j][_str])
sp.graphics[_str].apply(null, _obj.graphics[j][_str]);
}
}
}
}
for (_str in _obj) {
if(_str != "Shape" && _str != "graphics"){
sp[_str] = _obj[_str];
}
}
}
return sp;
}
public static function newSprite(… args):Sprite{
var sp:Sprite;
var _str:String;
var _length:int = args.length;
for (var i:int = 0; i < _length; i++) {
var _obj:Object = args[i];
if(i == 0){
if(_obj.Sprite){
sp = _obj.Sprite;
}else{
sp = new Sprite();
}
}
if(_obj.graphics){
for (var j:int = 0; j < _obj.graphics.length; j++) {
if(_obj.graphics[j]){
for (_str in _obj.graphics[j]) {
sp.graphics[_str].apply(null, _obj.graphics[j][_str]);
}
}
}
}
for (_str in _obj) {
if(_str != "Sprite" && _str != "graphics" && _str != "addChild"){
sp[_str] = _obj[_str];
}
}
if(_obj.addChild){
sp.addChild(_obj.addChild);
}
}
return sp;
}
public static function newTextField(… args):TextField{
var ta:TextField = new TextField();
ta.defaultTextFormat = defaultTextFormat;
var _length:int = args.length;
for (var i:int = 0; i < _length; i++) {
var _obj:Object = args[i];
for (var _str:String in _obj) {
if(_str != "setTextFormat"){
ta[_str] = _obj[_str];
}
}
if(_obj.setTextFormat){
var format:TextFormat = new TextFormat();
if(_obj.setTextFormat[0] is TextFormat){
format = _obj.setTextFormat[0];
}else{
for (var tf_str:String in _obj.setTextFormat[0]) {
format[tf_str] = _obj.setTextFormat[0][tf_str];
}
}
ta.setTextFormat(format,isNaN(_obj.setTextFormat[1])?-1:_obj.setTextFormat[1],isNaN(_obj.setTextFormat[2])?-1:_obj.setTextFormat[2]);
}
}
return ta;
}
}

[/sourcecode]
 

1 Comment

Comments are closed.