AS3で3Dの描画をする その4 | Photoshop CC Tutorials
自作3Dエンジンでポリゴンを描画してみました。

参考文献:Javaアプレット 3Dゲーム開発とレンダリング
$ピック社長のブログ

Main.as
package 
{
import flash.display.Sprite;
import flash.text.TextField;

public class Main extends Sprite
{
private var textField:TextField;

public function Main():void
{
//デバッグエリア
textField = new TextField();
textField.background = true;
textField.border = true;
textField.x = 50;
textField.y = 100;
textField.width = 300;
textField.height = 50;
Debug.textField = textField;
Debug.trace("default");
this.addChild(textField);

var DEF_VERTEX:Array =
[
[ -50, -50, 50],
[ 0, 50, 0],
[ 50, -50, 50]
];

var face:Face = new Face(DEF_VERTEX);
var sp:Sprite = new Sprite();
face.fillPolygon(sp.graphics);
this.addChild(sp);
}

}

}


Face.as
package  
{
import flash.display.Graphics;
/**
* 面クラス
* @author pick
*/
public class Face
{
// PUBLIC MEMBERS
public static const NUM_VERTEX:int = 3;

// PRIVATE MEMBERS
private static const DEF_VERTEX:Array =
[
[ -0.5, -0.5, 0.0],
[ 0.5, -0.5, 0.0],
[ 0.0, 0.5, 0.0]
];

private var diffuse:Array = [1.0, 1.0, 1.0];
private var ambient:Array = [0.125, 0.125, 0.125];

private var lineColor:Array = [0.5, 0.5, 0.5];
private var pointColor:Array = [1.0, 1.0, 1.0];

private var vertex:Array;
private var normal:Vector3d;
private var center:Vector3d;

// CONSTRUCTORS
public function Face(...args)
{
switch(args.length) {
case 0:
var scale:Number = 1.0;
vertex = new Array(NUM_VERTEX);
for (var i:int = 0; i < vertex.length; i++) {
vertex[i] = new Vector3d(DEF_VERTEX[i]);
vertex[i].multiplyEqual(scale);
}

normal = new Vector3d(0.0, 0.0, 1.0);
center = new Vector3d(0.0, 0.0, 0.0);

// デバッグ
/*Debug.trace(vertex[0].get(0) + " " + vertex[0].get(1) + " " + vertex[0].get(2) + "\n" +
vertex[1].get(0) + " " + vertex[1].get(1) + " " + vertex[1].get(2) + "\n" +
vertex[2].get(0) + " " + vertex[2].get(1) + " " + vertex[2].get(2)
);*/
break;
case 1:
if (args[0] is Number) {
scale = args[0];
vertex = new Array(NUM_VERTEX);
for (i = 0; i < vertex.length; i++) {
vertex[i] = new Vector3d(DEF_VERTEX[i]);
vertex[i].multiplyEqual(scale);
}

normal = new Vector3d(0.0, 0.0, 1.0);
center = new Vector3d(0.0, 0.0, 0.0);
}
else if (args[0] is Array) {
var v:Array = args[0];
if (v[0] is Vector3d) {
vertex = new Array(NUM_VERTEX);
for (i = 0; i < vertex.length; i++) {
vertex[i] = v[i].copy();
}

calculateNormal();

center = new Vector3d();
calculateCenter();

// デバッグ
/*Debug.trace(vertex[0].get(0) + " " + vertex[0].get(1) + " " + vertex[0].get(2) + "\n" +
vertex[1].get(0) + " " + vertex[1].get(1) + " " + vertex[1].get(2) + "\n" +
vertex[2].get(0) + " " + vertex[2].get(1) + " " + vertex[2].get(2)
);*/
}
else if (v[0] is Array) {

vertex = new Array(NUM_VERTEX);
for (i = 0; i < vertex.length; i++) {
vertex[i] = new Vector3d(v[i]);
}

calculateNormal();

center = new Vector3d();
calculateCenter();

// デバッグ
/*Debug.trace(vertex[0].get(0) + " " + vertex[0].get(1) + " " + vertex[0].get(2) + "\n" +
vertex[1].get(0) + " " + vertex[1].get(1) + " " + vertex[1].get(2) + "\n" +
vertex[2].get(0) + " " + vertex[2].get(1) + " " + vertex[2].get(2)
);*/
}
}
break;
}
}

private function calculateNormal():void
{
var v0:Vector3d = new Vector3d(vertex[0]);
var v1:Vector3d = new Vector3d(vertex[1]);
var v2:Vector3d = new Vector3d(vertex[2]);
var v21:Vector3d = v2.subtract(v1); // v21 = v2 - v1
var v01:Vector3d = v0.subtract(v1); // v01 = v0 - v1

normal = v21.cross(v01); // n = v21 × v01
normal.normalize();

// デバッグ
//Debug.trace(v0.get(0) + " " + v1.get(1) + " " + v2.get(2));
//Debug.trace(normal.get(0) + " " + normal.get(1) + " " + normal.get(2) + " " );
}

private function calculateCenter():void
{
center.setValue(0.0, 0.0, 0.0);
for (var i:int = 0; i < vertex.length; i++) {
center.addEqual(vertex[i]);
}
center.divideEqual(vertex.length);
}

public function fillPolygon(g:Graphics):void {
var v2d:Array = new Array(vertex.length);
for (var i:int = 0; i < vertex.length; i++) {
v2d[i] = new Vector2d(vertex[i].getX(), vertex[i].getY());
}

var x:Array = new Array(vertex.length);
var y:Array = new Array(vertex.length);

// ポリゴンの描画
g.beginFill(0xffff0000);
x[0] = int(v2d[0].getX());
y[0] = int( -v2d[0].getY());
g.moveTo(x[0] + 200, y[0] + 200);
for (i = 0; i < vertex.length; i++) {
x[i] = int(v2d[i].getX());
y[i] = int(-v2d[i].getY());
g.lineTo(x[i] + 200, y[i] + 200);
}
g.endFill();
}

}

}


vector2d.as
package  
{
/**
* 2次元ベクトルクラス
* @author pick
*/
public class Vector2d
{
// PUBLIC MEMBERS
public static const DIMENSION:int = 2;

// PRIVATE MEMBERS
private var vec:Array;

// CONSTRUCTORS
public function Vector2d(...args)
{
switch(args.length) {
case 0:
vec = new Array(DIMENSION);
vec[0] = 0.0;
vec[1] = 0.0;
break;
case 2:
var x:Number = args[0];
var y:Number = args[1];
vec = new Array(DIMENSION);
vec[0] = x;
vec[1] = y;
break;
}
}

public function add(v:Vector2d):Vector2d
{
var dstV:Vector2d = new Vector2d();
for (var i:int = 0; i < DIMENSION; i++) {
dstV.vec[i] = vec[i] + v.vec[i];
}

return dstV;
}

public function subtract(v:Vector2d):Vector2d
{
var dstV:Vector2d = new Vector2d();
for (var i:int = 0; i < DIMENSION;i++ ) {
dstV.vec[i] = vec[i] - v.vec[i];
}

return dstV;
}

public function dot(v:Vector2d):Number
{
var dot:Number = 0.0;
for (var i:int = 0; i < DIMENSION; i++ ) {
dot += vec[i] * v.vec[i];
}

return dot;
}

public function set(index:int, value:Number):void
{
if (index < 0 || index >= DIMENSION) {
return;
}

vec[index] = value;
}

public function get(index:int):Number
{
if (index < 0 || index >= DIMENSION) {
return 0.0;
}

return vec[index];
}


public function getVec():Array
{
return vec;
}

public function getX():Number
{
return get(0);
}

public function getY():Number
{
return get(1);
}

public function length():Number
{
return Math.sqrt(dot(this));
}

public function normalize():Number
{
var l:Number = length();
if (l == 0.0) {
return 0.0;;
}

for (var i:int = 0; i < DIMENSION;i++ ) {
vec[i] /= l;
}

return l;
}

public function rotate(angle:Number):Vector2d
{
var v:Vector2d = new Vector2d();
var radian:Number = degreeToRadian(angle);
var cos:Number = Math.cos(radian);
var sin:Number = Math.sin(radian);

v.vec[0] = cos * vec[0] + -sin * vec[1];
v.vec[1] = sin * vec[0] + cos * vec[1];

return v;
}

public function degreeToRadian(degree:Number):Number
{
return (degree * Math.PI / 180.0);
}

}

}


vector3d.as
package  
{
/**
* 3次元ベクトルクラス
* @author pick
*/
public class Vector3d
{
// PUBLIC MEMBERS
public static const DIMENSION:int = 3;

// PRIVATE MEMBERS
private var vec:Array;

// CONSTRUCTORS
public function Vector3d(...args)
{
switch(args.length) {
case 0:
vec = new Array(DIMENSION);
vec[0] = 0.0;
vec[1] = 0.0;
vec[2] = 0.0;
break;
case 1:
if(args[0] is Array){
var v:Array = args[0];
vec = new Array(DIMENSION);
vec[0] = v[0];
vec[1] = v[1];
vec[2] = v[2];
}
else if (args[0] is Vector3d) {
var v3d:Vector3d = args[0];
vec = new Array(DIMENSION);
vec[0] = v3d.vec[0];
vec[1] = v3d.vec[1];
vec[2] = v3d.vec[2];
}

break;
case 3:
var x:Number = args[0];
var y:Number = args[1];
var z:Number = args[2];
vec = new Array(DIMENSION);
vec[0] = x;
vec[1] = y;
vec[2] = z;
break;
}
}

public function add(v:Vector3d):Vector3d
{
var dstV:Vector3d = new Vector3d();
for (var i:int = 0; i < DIMENSION; i++ ) {
dstV.vec[i] = vec[i] + v.vec[i];
}

return dstV;

}

public function subtract(v:Vector3d):Vector3d
{
var dstV:Vector3d = new Vector3d();
for (var i:int = 0; i < DIMENSION;i++ ) {
dstV.vec[i] = vec[i] - v.vec[i];
}

return dstV;
}

public function multiply(scalar:Number):Vector3d
{
var v:Vector3d = new Vector3d();
for (var i:int = 0; i < DIMENSION; i++) {
v.vec[i] = vec[i] * scalar;
}

return v;
}

public function addEqual(...args):void {
if (args[0] is Number) {
var scalar:Number = args[0];
for (var i:int = 0; i < DIMENSION; i++) {
vec[i] += scalar;
}
}
else if(args[0] is Vector3d) {
var v:Vector3d = args[0];
for (i = 0; i < DIMENSION; i++) {
vec[i] += v.vec[i];
}
}
}

public function multiplyEqual(scalar:Number):void
{
for (var i:int = 0; i < DIMENSION; i++) {
vec[i] *= scalar;
}
}

public function divideEqual(scalar:Number):void
{
if (scalar == 0.0) {
return;
}

for (var i:int = 0; i < DIMENSION; i++) {
vec[i] /= scalar;
}

}

public function dot(v:Vector3d):Number
{
var dot:Number = 0.0;
for (var i:int = 0; i < DIMENSION;i++ ) {
dot += vec[i] * v.vec[i];
}

return dot;
}

public function cross(v:Vector3d):Vector3d
{
var cross:Vector3d = new Vector3d();
for (var i:int = 0; i < DIMENSION;i++ ) {
cross.vec[i] =
vec[(i + 1) % DIMENSION] * v.vec[(i + 2) % DIMENSION] -
vec[(i + 2) % DIMENSION] * v.vec[(i + 1) % DIMENSION];
}

return cross;
}

public function length():Number
{
return Math.sqrt(dot(this));
}

public function normalize():Number
{
var l:Number = length();
if (l == 0.0) {
return 0.0;;
}

for (var i:int = 0; i < DIMENSION;i++ ) {
vec[i] /= l;
}

return l;
}

public function angle(v:Vector2d):Number
{
var normal1:Vector2d = new Vector2d(vec);
normal1.normalize();
var normal2:Vector2d = new Vector2d(v.getVec);
normal2.normalize();

var cos:Number = normal1.dot(normal2);

return (radianToDegree(Math.acos(cos)));
}

public function radianToDegree(radian:Number):Number
{
return (radian * 180.0 / Math.PI);
}

public function set(index:int, value:Number):void
{
if (index < 0 || index >= DIMENSION) {
return;
}

vec[index] = value;
}

public function get(index:int):Number
{
if (index < 0 || index >= DIMENSION) {
return 0.0;
}

return vec[index];
}

public function getX():Number
{
return get(0);
}

public function getY():Number
{
return get(1);
}

public function getZ():Number
{
return get(2);
}

public function setX(value:Number):void
{
set(0, value);
}

public function setY(value:Number):void
{
set(1, value);
}

public function setZ(value:Number):void
{
set(2, value);
}

public function setValue(...args):void {
switch(args.length) {
case 1:
var v:Array = args[0];
for (var i:int = 0; i < DIMENSION; i++) {
set(i, v[i]);
}
break;
case 3:
var x:Number = args[0];
var y:Number = args[1];
var z:Number = args[2];
setX(x);
setY(y);
setZ(z);
break;
}
}

public function copy():Vector3d
{
return (new Vector3d(vec));
}

}

}


Mtrix4x4d.as
package  
{
/**
* 4×4行列クラス
* @author pick
*/
public class Matrix4x4d
{
// PUBLIC MEMBERS
public static const DIMENSION:int = 4;

// PRIVATE MEMBERS
private var mat:Array;

// CONSTRUCTORS
public function Matrix4x4d(...args)
{
switch(args.length) {
case 0:
mat = new Array(DIMENSION);
for (var i:int = 0; i < DIMENSION; i++ ) {
mat[i] = new Array(DIMENSION);
for (var j:int = 0; j < DIMENSION;j++ ) {
mat[i][j] = 0.0;
}
}

makeIdentity();
break;
case 1:
var m:Array = args[0];
mat = new Array(DIMENSION);
for (i = 0; i < DIMENSION; i++ ) {
mat[i] = new Array(DIMENSION);
for (j = 0; j < DIMENSION;j++ ) {
mat[i][j] = 0.0;
}
}

setValue(m);
break;
}
}

public function makeIdentity():void
{
for (var i:int = 0; i < DIMENSION;i++ ) {
for (var j:int = 0; j < DIMENSION;j++ ) {
mat[i][j] = (i == j ? 1.0 : 0.0);
}
}
}

public function setValue(m:Array):void
{
for (var i:int = 0; i < DIMENSION;i++ ) {
for (var j:int = 0; j < DIMENSION;j++ ) {
set(i, j, m[i][j]);
}
}
}

public function set(i:int, j:int, value:Number):void
{
if ((i < 0 || i >= DIMENSION) && (j < 0 || j >= DIMENSION)) {
return;
}

mat[i][j] = value;
}

public function add(m:Matrix4x4d):Matrix4x4d
{
var dstM:Matrix4x4d = new Matrix4x4d();
for (var i:int = 0; i < DIMENSION;i++ ) {
for (var j:int = 0; j < DIMENSION;j++ ) {
dstM.mat[i][j] = mat[i][j] + m.mat[i][j];
}
}

return dstM;
}

public function subtract(m:Matrix4x4d):Matrix4x4d
{
var dstM:Matrix4x4d = new Matrix4x4d();
for (var i:int = 0; i < DIMENSION;i++ ) {
for (var j:int = 0; j < DIMENSION;j++ ) {
dstM.mat[i][j] = mat[i][j] - m.mat[i][j];
}
}

return dstM;
}

public function multiply(scalar:Number):Matrix4x4d
{
var m:Matrix4x4d = new Matrix4x4d();
for (var i:int = 0; i < DIMENSION; i++) {
for (var j:int = 0; j < DIMENSION; j++) {
m.mat[i][j] = mat[i][j] * scalar;
}
}

return m;
}

public function addEqual(...args):void
{
if (args[0] is Number) {
var scalar:Number = args[0];
for (var i:int = 0; i < DIMENSION; i++) {
for (var j:int = 0; j < DIMENSION; j++) {
mat[i][j] += scalar;
}
}
}
else if (args[0] is Matrix4x4d) {
var m:Matrix4x4d = args[0];
for (i = 0; i < DIMENSION; i++) {
for (j = 0; j < DIMENSION; j++) {
mat[i][j] += m.mat[i][j];
}
}
}

}

public function multiplyEqual(scalar:Number):void
{
for (var i:int = 0; i < DIMENSION; i++) {
for (var j:int = 0; j < DIMENSION; j++) {
mat[i][j] *= scalar;
}
}
}

public function getValue(m:Array):void
{
for (var i:int = 0; i < DIMENSION;i++ ) {
for (var j:int = 0; j < DIMENSION;j++ ) {
m[i][j] = get(i, j);
}
}
}

public function get(i:int, j:int):Number
{
if ((i < 0 || i >= DIMENSION) && (j < 0 || j >= DIMENSION)) {

}

return mat[i][j];
}

public function multiplyRight(m:Matrix4x4d):Matrix4x4d
{
var dstM:Matrix4x4d = new Matrix4x4d();
for (var i:int = 0; i < DIMENSION; i++) {
for (var j:int = 0; j < DIMENSION; j++) {
dstM.mat[i][j] = 0.0;
for (var k:int = 0; k < DIMENSION; k++) {
dstM.mat[i][j] += mat[i][k] * m.mat[k][j];
}
}
}

return dstM;
}

public function multiplyVecRight(v:Vector3d):Vector3d
{
var dstV:Vector3d = new Vector3d();

for (var i:int = 0; i < Vector3d.DIMENSION; i++) {
dstV.set(i, 0.0);
for (var j:int = 0; j < Vector3d.DIMENSION; j++) {
dstV.set(i, dstV.get(i) + mat[i][j] * v.get(j));
}
dstV.set(i, dstV.get(i) + mat[i][DIMENSION - 1]);
}

return dstV;
}

public function multiplyLeft(m:Matrix4x4d):Matrix4x4d
{
var dstM:Matrix4x4d = new Matrix4x4d();
for (var i:int = 0; i < DIMENSION; i++) {
for (var j:int = 0; j < DIMENSION; j++) {
dstM.mat[i][j] = 0.0;
for (var k:int = 0; k < DIMENSION; k++) {
dstM.mat[i][j] += m.mat[i][k] * mat[k][j];
}
}
}

return dstM;
}

public function multiplyVecLeft(v:Vector3d):Vector3d
{
var dstV:Vector3d = new Vector3d();

for (var i:int = 0; i < Vector3d.DIMENSION; i++) {
dstV.set(i, 0.0);
for (var j:int = 0; j < Vector3d.DIMENSION; j++) {
dstV.set(i, dstV.get(i) + mat[j][i] * v.get(j));
}
dstV.set(i, dstV.get(i) + mat[DIMENSION - 1][i]);
}

return dstV;
}

public function makeZero():void
{
for (var i:int = 0; i < DIMENSION; i++) {
for (var j:int = 0; j < DIMENSION; j++) {
mat[i][j] = 0.0;
}
}
}

public function makeScale(...args):void {
if (args[0] is Number) {
var scale:Number = args[0];
makeIdentity();

for (var i:int = 0; i < DIMENSION - 1; i++) {
mat[i][i] = scale;
}
}
else if (args[0] is Vector3d) {
var scaleVec3d:Vector3d = args[0];
makeIdentity();

for (i = 0; i < DIMENSION - 1; i++) {
mat[i][i] = scaleVec3d.get(i);
}
}
}

public function makeTranslation(...args):void
{
switch(args.length) {
case 1:
var trans:Vector3d = args[0];
makeIdentity();

for (var i:int = 0; i < DIMENSION - 1; i++) {
mat[i][DIMENSION - 1] = trans.get(i);
}
break;
case 3:
var x:Number = args[0];
var y:Number = args[1];
var z:Number = args[2];
makeIdentity();

mat[0][DIMENSION - 1] = x;
mat[1][DIMENSION - 1] = y;
mat[2][DIMENSION - 1] = z;
break;
}
}

public function makeRotation(axis:Vector3d, angle:Number):void
{
makeIdentity();

var u:Vector3d = axis.copy();
u.normalize();

var I:Matrix4x4d = new Matrix4x4d();
I.makeIdentity();

var uuT:Matrix4x4d = new Matrix4x4d();
uuT.makeIdentity();
for (var i:int = 0; i < DIMENSION - 1; i++) {
for (var j:int = 0; j < DIMENSION - 1; j++) {
uuT.mat[i][j] = u.get(i) * u.get(j);
}
}

var S:Matrix4x4d = new Matrix4x4d();
S.makeIdentity();
S.mat[0][0] = 0.0;
S.mat[0][1] = -u.get(2);
S.mat[0][2] = u.get(1);
S.mat[1][0] = u.get(2);
S.mat[1][1] = 0.0;
S.mat[1][2] = -u.get(0);
S.mat[2][0] = -u.get(1);
S.mat[2][1] = u.get(0);
S.mat[2][2] = 0.0;

var M2:Matrix4x4d;
M2 = I.subtract(uuT);
M2.multiplyEqual(Math.cos(degreeToRadian(angle)));
M2.mat[3][3] = 1.0;

var M3:Matrix4x4d;
M3 = S.multiply(Math.sin(degreeToRadian(angle)));
M3.mat[3][3] = 1.0;

var M:Matrix4x4d = new Matrix4x4d();
M.makeZero();
M.addEqual(uuT);
M.addEqual(M2);
M.addEqual(M3);
M.mat[3][3] = 1.0;

M.getValue(mat);
}

public function makePerspective(l:Number, r:Number, b:Number, t:Number, n:Number, f:Number):void
{

mat[0][0] = 2.0 * n / (r - l);
mat[0][1] = 0.0;
mat[0][2] = (r + l) / (r - l);
mat[0][3] = 0.0;

mat[1][0] = 0.0;
mat[1][1] = 2.0 * n / (t - b);
mat[1][2] = (t + b) / (t - b);
mat[1][3] = 0.0;

mat[2][0] = 0.0;
mat[2][1] = 0.0;
mat[2][2] = -(f + n) / (f - n);
mat[2][3] = -2.0 * f * n / (f - n);

mat[3][0] = 0.0;
mat[3][1] = 0.0;
mat[3][2] = -1.0;
mat[3][3] = 0.0;
}

public function makeView(to:Vector3d, from:Vector3d, up:Vector3d):void
{
var zeroVec:Vector3d = new Vector3d(0.0, 0.0, 0.0);
var dir:Vector3d;
var y:Vector3d = new Vector3d(0.0, 1.0, 0.0);
var z:Vector3d = new Vector3d(0.0, 0.0, 1.0);
var minusZ:Vector3d = new Vector3d(0.0, 0.0, -1.0);
var axis:Vector3d;
var angle:Number;
var cos:Number;
var sin:Number;

dir = to.subtract(from);
dir.normalize();

var dirZX:Vector3d = dir.copy();
dirZX.setY(0.0);
dirZX.normalize();

var rotDirMat1:Matrix4x4d = new Matrix4x4d();
rotDirMat1.makeIdentity();

axis = minusZ.cross(dirZX);
if (axis.length() > 0.0) {
cos = minusZ.dot(dirZX);
sin = axis.length();
angle = radianToDegree(Math.atan2( sin, cos ));
axis.normalize();
rotDirMat1.makeRotation(axis, angle);
}

var rotDirMat2:Matrix4x4d = new Matrix4x4d();
rotDirMat2.makeIdentity();
axis = dirZX.cross(dir);
if (axis.length() > 0.0) {
cos = dirZX.dot(dir);
sin = axis.length();
angle = radianToDegree(Math.atan2(sin, cos));
axis.normalize();
rotDirMat2.makeRotation(axis, angle);
}
var rotMat1:Matrix4x4d = rotDirMat2.multiplyRight(rotDirMat1);

var proj:Number;
var projVec:Vector3d;
var normalUp:Vector3d;
var verticalUp:Vector3d;
var verticalY:Vector3d;
normalUp = up;
normalUp.normalize();
proj = normalUp.dot(dir);
projVec = dir.multiply(proj);
verticalUp = normalUp.subtract(projVec);
proj = y.dot(dir);
projVec = dir.multiply(proj);
verticalY = y.subtract(projVec);
axis = verticalY.cross(verticalUp);

var rotMat2:Matrix4x4d = new Matrix4x4d();
rotMat2.makeIdentity();
if (axis.length() > 0.0) {
cos = verticalY.dot(verticalUp);
sin = axis.length();
angle = radianToDegree(Math.atan2(sin, cos));
axis.normalize();
rotMat2.makeRotation(axis, angle);
}

var rotMat:Matrix4x4d = rotMat2.multiplyRight(rotMat1);

var trans:Vector3d;
var transMat:Matrix4x4d = new Matrix4x4d();
transMat.makeIdentity();
trans = from;
transMat.makeTranslation(trans);

var viewMat:Matrix4x4d;
viewMat = transMat.multiplyRight(rotMat);
viewMat.invert();

viewMat.getValue(mat);
}

public function invert():Boolean
{
var cofactorMat:Array = new Array(DIMENSION);
for (var i:int = 0; i < DIMENSION;i++ ) {
cofactorMat[i] = new Array(DIMENSION);
for (var j:int = 0; j < DIMENSION;j++ ) {
cofactorMat[i][j] = 0.0;
}
}

var _det:Number;
var status:Boolean;

for (var row:int = 0; row < DIMENSION; row++) {
for (var col:int = 0; col < DIMENSION; col++) {
cofactorMat[row][col] = cofactor(col, row);
}
}

_det = det();

if (_det != 0.0) {
for (row = 0; row < DIMENSION; row++) {
for (col = 0; col < DIMENSION; col++) {
mat[row][col] = cofactorMat[row][col] / _det;
}
}
status = true;
}
else {
status = false;
}

return status;
}

private function det(...args):Number
{
switch(args.length) {
case 0:
var det:Number;

if (DIMENSION == 1) {
det = mat[0][0];
}
else {
det = 0.0;
for (var j:int = 0; j < DIMENSION; j++) {
det += mat[0][j] * cofactor(mat, DIMENSION, 0, j);
}
}

break;
case 2:
var mat:Array = args[0];
var dimension:int = args[1];

det;

if (DIMENSION == 1) {
det = mat[0][0];
}
else {
det = 0.0;
for (j = 0; j < dimension; j++) {
det += mat[0][j] * cofactor(mat, dimension, 0, j);
}
}

break;
}
return det;
}

public function cofactor(...args):Number
{
switch(args.length) {
case 2:
var i:int = args[0];
var j:int = args[1];

var cofactor:Number = 0.0;
var m:Array = new Array(DIMENSION);
for (i = 0; i < DIMENSION;i++ ) {
m[i] = new Array(DIMENSION);
for (j = 0; j < DIMENSION;j++ ) {
m[i][j] = 0.0;
}
}

for (var k:int = 0; k < dimension; k++) {
for (var l:int = 0; l < dimension; l++) {
if (k < i && l < j) {
m[k][l] = mat[k][l];
}
else if (k < i && l > j) {
m[k][l - 1] = mat[k][l];
}
else if (k > i && l < j) {
m[k - 1][l] = mat[k][l];
}
else if (k > i && l > j) {
m[k - 1][l - 1] = mat[k][l];
}
}
}

cofactor = Math.pow(-1.0, i + j) * det(m, dimension - 1);
break;
case 4:
var mat:Array = args[0];
var dimension:int = args[1];
i = args[2];
j = args[3];

cofactor = 0.0;
m = new Array(DIMENSION);
for (i = 0; i < DIMENSION;i++ ) {
m[i] = new Array(DIMENSION);
for (j = 0; j < DIMENSION;j++ ) {
m[i][j] = 0.0;
}
}

for (k = 0; k < dimension; k++) {
for (l = 0; l < dimension; l++) {
if (k < i && l < j) {
m[k][l] = mat[k][l];
}
else if (k < i && l > j) {
m[k][l - 1] = mat[k][l];
}
else if (k > i && l < j) {
m[k - 1][l] = mat[k][l];
}
else if (k > i && l > j) {
m[k - 1][l - 1] = mat[k][l];
}
}
}

cofactor = Math.pow(-1.0, i + j) * det(m, dimension - 1);
break;
}
return cofactor;
}

public function degreeToRadian(degree:Number):Number
{
return (degree * Math.PI / 180.0);
}

public function radianToDegree(radian:Number):Number
{
return (radian * 180.0 / Math.PI);
}
}

}


Debug.as
package  
{
import flash.text.TextField;
/**
* デバッグクラス
* @author pick
*/
public class Debug
{
public static var textField:TextField;

public function Debug()
{

}

public static function trace(...args):void {
textField.text = String(args[0]);
}

}

}


実行結果
$ピック社長のブログ


$ピック社長のブログ