```  o[ 9] = n[ 2];
o[10] = n[ 0];
o[11] = n[ 3];
return o;
}

//o = nNewExchangeZXY (n)
function nNewExchangeZXY (n) {
return [n[ 5], n[ 6], n[ 4], n[ 7],
n[ 9], n[10], n[ 8], n[11],
n[ 1], n[ 2], n[ 0], n[ 3]];
}

//------------------------------------------------------------------------
//identity 恒等変換
//
//    [1 0 0 0]   [x]   [x]
//    [0 1 0 0] * [y] = [y]
//    [0 0 1 0]   [z]   [z]
//    [0 0 0 1]   [1]   [1]
//
//    [1 0 0 0]   [n11 n12 n13 n14]   [n11 n12 n13 n14]
//    [0 1 0 0] * [n21 n22 n23 n24] = [n21 n22 n23 n24]
//    [0 0 1 0]   [n31 n32 n33 n34]   [n31 n32 n33 n34]
//    [0 0 0 1]   [ 0   0   0   1 ]   [ 0   0   0   1 ]
//

//o = nLetIdentity (o)
//  Array o
function nLetIdentity (o) {
o[ 0] = 1;
o[ 1] = 0;
o[ 2] = 0;
o[ 3] = 0;
o[ 4] = 0;
o[ 5] = 1;
o[ 6] = 0;
o[ 7] = 0;
o[ 8] = 0;
o[ 9] = 0;
o[10] = 1;
o[11] = 0;
return o;
}

//o = nNewIdentity ()
//  Array o
function nNewIdentity () {
return [1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0];
}

//------------------------------------------------------------------------
//inverse 逆変換
//
//    d = n11*(n22*n33-n23*n32)+n12*(n23*n31-n21*n33)+n13*(n21*n32-n22*n31)
//
//    [n11 n12 n13 n14]^-1   [(n22*n33-n23*n32)/d (n13*n32-n12*n33)/d (n12*n23-n13*n22)/d (n14*(n23*n32-n22*n33)+n24*(n12*n33-n13*n32)+n34*(n13*n22-n12*n23))/d]
//    [n21 n22 n23 n24]    = [(n23*n31-n21*n33)/d (n11*n33-n13*n31)/d (n13*n21-n11*n23)/d (n14*(n21*n33-n23*n31)+n24*(n13*n31-n11*n33)+n34*(n11*n23-n13*n21))/d]
//    [n31 n32 n33 n34]      [(n21*n32-n22*n31)/d (n12*n31-n11*n32)/d (n11*n22-n12*n21)/d (n14*(n22*n31-n21*n32)+n24*(n11*n32-n12*n31)+n34*(n12*n21-n11*n22))/d]
//    [ 0   0   0   1 ]      [         0                   0                   0                                            1                                  ]
//

//n = nInverse (n)
//  Array n
function nInverse (n) {
let n11 = n[0], n12 = n[1], n13 = n[ 2], n14 = n[ 3];  //double
let n21 = n[4], n22 = n[5], n23 = n[ 6], n24 = n[ 7];  //double
let n31 = n[8], n32 = n[9], n33 = n[10], n34 = n[11];  //double
let d = n11 * (n22 * n33 - n23 * n32) + n12 * (n23 * n31 - n21 * n33) + n13 * (n21 * n32 - n22 * n31);  //double
n[ 0] = (n22 * n33 - n23 * n32) / d;
n[ 1] = (n13 * n32 - n12 * n33) / d;
n[ 2] = (n12 * n23 - n13 * n22) / d;
n[ 3] = (n14 * (n23 * n32 - n22 * n33) + n24 * (n12 * n33 - n13 * n32) + n34 * (n13 * n22 - n12 * n23)) / d;
n[ 4] = (n23 * n31 - n21 * n33) / d;
n[ 5] = (n11 * n33 - n13 * n31) / d;
n[ 6] = (n13 * n21 - n11 * n23) / d;
n[ 7] = (n14 * (n21 * n33 - n23 * n31) + n24 * (n13 * n31 - n11 * n33) + n34 * (n11 * n23 - n13 * n21)) / d;
n[ 8] = (n21 * n32 - n22 * n31) / d;
n[ 9] = (n12 * n31 - n11 * n32) / d;
n[10] = (n11 * n22 - n12 * n21) / d;
n[11] = (n14 * (n22 * n31 - n21 * n32) + n24 * (n11 * n32 - n12 * n31) + n34 * (n12 * n21 - n11 * n22)) / d;
return n;
}

//o = nLetInverse (o, n)
//  Array o
//  Array n
function nLetInverse (o, n) {
let n11 = n[0], n12 = n[1], n13 = n[ 2], n14 = n[ 3];  //double
let n21 = n[4], n22 = n[5], n23 = n[ 6], n24 = n[ 7];  //double
let n31 = n[8], n32 = n[9], n33 = n[10], n34 = n[11];  //double
let d = n11 * (n22 * n33 - n23 * n32) + n12 * (n23 * n31 - n21 * n33) + n13 * (n21 * n32 - n22 * n31);  //double
o[ 0] = (n22 * n33 - n23 * n32) / d;
o[ 1] = (n13 * n32 - n12 * n33) / d;
o[ 2] = (n12 * n23 - n13 * n22) / d;
o[ 3] = (n14 * (n23 * n32 - n22 * n33) + n24 * (n12 * n33 - n13 * n32) + n34 * (n13 * n22 - n12 * n23)) / d;
o[ 4] = (n23 * n31 - n21 * n33) / d;
o[ 5] = (n11 * n33 - n13 * n31) / d;
o[ 6] = (n13 * n21 - n11 * n23) / d;
o[ 7] = (n14 * (n21 * n33 - n23 * n31) + n24 * (n13 * n31 - n11 * n33) + n34 * (n11 * n23 - n13 * n21)) / d;
o[ 8] = (n21 * n32 - n22 * n31) / d;
o[ 9] = (n12 * n31 - n11 * n32) / d;
o[10] = (n11 * n22 - n12 * n21) / d;
o[11] = (n14 * (n22 * n31 - n21 * n32) + n24 * (n11 * n32 - n12 * n31) + n34 * (n12 * n21 - n11 * n22)) / d;
return o;
}

//o = nNewInverse (n)
//  Array o
//  Array n
function nNewInverse (n) {
let n11 = n[0], n12 = n[1], n13 = n[ 2], n14 = n[ 3];  //double
let n21 = n[4], n22 = n[5], n23 = n[ 6], n24 = n[ 7];  //double
let n31 = n[8], n32 = n[9], n33 = n[10], n34 = n[11];  //double
let d = n11 * (n22 * n33 - n23 * n32) + n12 * (n23 * n31 - n21 * n33) + n13 * (n21 * n32 - n22 * n31);  //double
return [(n22 * n33 - n23 * n32) / d,
(n13 * n32 - n12 * n33) / d,
(n12 * n23 - n13 * n22) / d,
(n14 * (n23 * n32 - n22 * n33) + n24 * (n12 * n33 - n13 * n32) + n34 * (n13 * n22 - n12 * n23)) / d,
(n23 * n31 - n21 * n33) / d,
(n11 * n33 - n13 * n31) / d,
(n13 * n21 - n11 * n23) / d,
(n14 * (n21 * n33 - n23 * n31) + n24 * (n13 * n31 - n11 * n33) + n34 * (n11 * n23 - n13 * n21)) / d,
(n21 * n32 - n22 * n31) / d,
(n12 * n31 - n11 * n32) / d,
(n11 * n22 - n12 * n21) / d,
(n14 * (n22 * n31 - n21 * n32) + n24 * (n11 * n32 - n12 * n31) + n34 * (n12 * n21 - n11 * n22)) / d];
}

//------------------------------------------------------------------------
//rotateXY 回転(+x→+y)
//
//    [cos(t) -sin(t) 0 0]   [x]   [cos(t)*x-sin(t)*y]
//    [sin(t)  cos(t) 0 0] * [y] = [sin(t)*x+cos(t)*y]
//    [  0       0    1 0]   [z]   [        z        ]
//    [  0       0    0 1]   [1]   [        1        ]
//
//    [cos(t) -sin(t) 0 0]   [n11 n12 n13 n14]   [cos(t)*n11-sin(t)*n21 cos(t)*n12-sin(t)*n22 cos(t)*n13-sin(t)*n23 cos(t)*n14-sin(t)*n24]
//    [sin(t)  cos(t) 0 0] * [n21 n22 n23 n24] = [sin(t)*n11+cos(t)*n21 sin(t)*n12+cos(t)*n22 sin(t)*n13+cos(t)*n23 sin(t)*n14+cos(t)*n24]
//    [  0       0    1 0]   [n31 n32 n33 n34]   [         n31                   n32                   n33                   n34         ]
//    [  0       0    0 1]   [ 0   0   0   1 ]   [          0                     0                     0                     1          ]
//

//o = nLetIRotateXY (o, t)
//  Array o
//  double t
function nLetIRotateXY (o, t) {
let c = cos (t), s = sin (t);  //double
o[ 0] = c;
o[ 1] = -s;
o[ 2] = 0;
o[ 3] = 0;
o[ 4] = s;
o[ 5] = c;
o[ 6] = 0;
o[ 7] = 0;
o[ 8] = 0;
o[ 9] = 0;
o[10] = 1;
o[11] = 0;
return o;
}

//o = nNewIRotateXY (t)
//  Array o
//  double t
function nNewIRotateXY (t) {
let c = cos (t), s = sin (t);  //double
return [c, -s, 0, 0,
s,  c, 0, 0,
0,  0, 1, 0];
}

//n = nRotateXY (n, t)
//  Array n
//  double t
function nRotateXY (n, t) {
let c = cos (t), s = sin (t);  //double
let n11 = n[0], n12 = n[1], n13 = n[2], n14 = n[3];  //double
let n21 = n[4], n22 = n[5], n23 = n[6], n24 = n[7];  //double
n[ 0] = c * n11 - s * n21;
n[ 1] = c * n12 - s * n22;
n[ 2] = c * n13 - s * n23;
n[ 3] = c * n14 - s * n24;
n[ 4] = s * n11 + c * n21;
n[ 5] = s * n12 + c * n22;
n[ 6] = s * n13 + c * n23;
n[ 7] = s * n14 + c * n24;
return n;
}

//o = nLetRotateXY (o, n, t)
//  Array o
//  Array n
//  double t
function nLetRotateXY (o, n, t) {
let c = cos (t), s = sin (t);  //double
let n11 = n[0], n12 = n[1], n13 = n[2], n14 = n[3];  //double
let n21 = n[4], n22 = n[5], n23 = n[6], n24 = n[7];  //double
o[ 0] = c * n11 - s * n21;
o[ 1] = c * n12 - s * n22;
o[ 2] = c * n13 - s * n23;
o[ 3] = c * n14 - s * n24;
o[ 4] = s * n11 + c * n21;
o[ 5] = s * n12 + c * n22;
o[ 6] = s * n13 + c * n23;
o[ 7] = s * n14 + c * n24;
o[ 8] = n[ 8];
o[ 9] = n[ 9];
o[10] = n[10];
o[11] = n[11];
return o;
}

//o = nNewRotateXY (n, t)
//  Array o
//  Array n
//  double t
function nNewRotateXY (n, t) {
let c = cos (t), s = sin (t);  //double
let n11 = n[0], n12 = n[1], n13 = n[2], n14 = n[3];  //double
let n21 = n[4], n22 = n[5], n23 = n[6], n24 = n[7];  //double
return [c * n11 - s * n21, c * n12 - s * n22, c * n13 - s * n23, c * n14 - s * n24,
s * n11 + c * n21, s * n12 + c * n22, s * n13 + c * n23, s * n14 + c * n24,
n[ 8],             n[ 9],             n[10],             n[11]];
}

//------------------------------------------------------------------------
//rotateYZ 回転(+y→+z)
//
//    [1    0      0    0]   [x]   [        x        ]
//    [0 cos(t) -sin(t) 0] * [y] = [cos(t)*y-sin(t)*z]
//    [0 sin(t)  cos(t) 0]   [z]   [sin(t)*y+cos(t)*z]
//    [0    0      0    1]   [1]   [        1        ]
//
//    [1    0      0    0]   [n11 n12 n13 n14]   [         n11                   n12                   n13                   n14         ]
//    [0 cos(t) -sin(t) 0] * [n21 n22 n23 n24] = [cos(t)*n21-sin(t)*n31 cos(t)*n22-sin(t)*n32 cos(t)*n23-sin(t)*n33 cos(t)*n24-sin(t)*n34]
//    [0 sin(t)  cos(t) 0]   [n31 n32 n33 n34]   [sin(t)*n21+cos(t)*n31 sin(t)*n22+cos(t)*n32 sin(t)*n23+cos(t)*n33 sin(t)*n24+cos(t)*n34]
//    [0    0      0    1]   [ 0   0   0   1 ]   [          0                     0                     0                     1          ]
//

//o = nLetIRotateYZ (o, t)
//  Array o
//  double t
function nLetIRotateYZ (o, t) {
let c = cos (t), s = sin (t);  //double
o[ 0] = 1;
o[ 1] = 0;
o[ 2] = 0;
o[ 3] = 0;
o[ 4] = 0;
o[ 5] = c;
o[ 6] = -s;
o[ 7] = 0;
o[ 8] = 0;
o[ 9] = s;
o[10] = c;
o[11] = 0;
return o;
}

//o = nNewIRotateYZ (t)
//  Array o
//  double t
function nNewIRotateYZ (t) {
let c = cos (t), s = sin (t);  //double
return [1, 0,  0, 0,
0, c, -s, 0,
0, s,  c, 0];
}

//n = nRotateYZ (n, t)
//  Array n
//  double t
function nRotateYZ (n, t) {
let c = cos (t), s = sin (t);  //double
let n21 = n[4], n22 = n[5], n23 = n[ 6], n24 = n[ 7];  //double
let n31 = n[8], n32 = n[9], n33 = n[10], n34 = n[11];  //double
n[ 4] = c * n21 - s * n31;
n[ 5] = c * n22 - s * n32;
n[ 6] = c * n23 - s * n33;
n[ 7] = c * n24 - s * n34;
n[ 8] = s * n21 + c * n31;
n[ 9] = s * n22 + c * n32;
n[10] = s * n23 + c * n33;
n[11] = s * n24 + c * n34;
return n;
}

//o = nLetRotateYZ (o, n, t)
//  Array o
//  Array n
//  double t
function nLetRotateYZ (o, n, t) {
let c = cos (t), s = sin (t);  //double
let n21 = n[4], n22 = n[5], n23 = n[ 6], n24 = n[ 7];  //double
let n31 = n[8], n32 = n[9], n33 = n[10], n34 = n[11];  //double
o[ 0] = n[ 0];
o[ 1] = n[ 1];
o[ 2] = n[ 2];
o[ 3] = n[ 3];
o[ 4] = c * n21 - s * n31;
o[ 5] = c * n22 - s * n32;
o[ 6] = c * n23 - s * n33;
o[ 7] = c * n24 - s * n34;
o[ 8] = s * n21 + c * n31;
o[ 9] = s * n22 + c * n32;
o[10] = s * n23 + c * n33;
o[11] = s * n24 + c * n34;
return o;
}

//o = nNewRotateYZ (n, t)
//  Array o
//  Array n
//  double t
function nNewRotateYZ (n, t) {
let c = cos (t), s = sin (t);  //double
let n21 = n[4], n22 = n[5], n23 = n[ 6], n24 = n[ 7];  //double
let n31 = n[8], n32 = n[9], n33 = n[10], n34 = n[11];  //double
return [n[ 0],             n[ 1],             n[ 2],             n[ 3],
c * n21 - s * n31, c * n22 - s * n32, c * n23 - s * n33, c * n24 - s * n34,
s * n21 + c * n31, s * n22 + c * n32, s * n23 + c * n33, s * n24 + c * n34];
}

//------------------------------------------------------------------------
//rotateZX 回転(+z→+x)
//
//    [ cos(t) 0 sin(t) 0]   [x]   [sin(t)*z+cos(t)*x]
//    [   0    1   0    0] * [y] = [        y        ]
//    [-sin(t) 0 cos(t) 0]   [z]   [cos(t)*z-sin(t)*x]
//    [   0    0   0    1]   [1]   [        1        ]
//
//    [ cos(t) 0 sin(t) 0]   [n11 n12 n13 n14]   [sin(t)*n31+cos(t)*n11 sin(t)*n32+cos(t)*n12 sin(t)*n33+cos(t)*n13 sin(t)*n34+cos(t)*n14]
//    [   0    1    0   0] * [n21 n22 n23 n24] = [         n21                   n22                   n23                   n24         ]
//    [-sin(t) 0 cos(t) 0]   [n31 n32 n33 n34]   [cos(t)*n31-sin(t)*n11 cos(t)*n32-sin(t)*n12 cos(t)*n33-sin(t)*n13 cos(t)*n34-sin(t)*n14]
//    [0    0      0    1]   [ 0   0   0   1 ]   [          0                     0                     0                     1          ]
//

//o = nLetIRotateZX (o, t)
//  Array o
//  double t
function nLetIRotateZX (o, t) {
let c = cos (t), s = sin (t);  //double
o[ 0] = c;
o[ 1] = 0;
o[ 2] = s;
o[ 3] = 0;
o[ 4] = 0;
o[ 5] = 1;
o[ 6] = 0;
o[ 7] = 0;
o[ 8] = -s;
o[ 9] = 0;
o[10] = c;
o[11] = 0;
return o;
}

//o = nNewIRotateZX (t)
//  Array o
//  double t
function nNewIRotateZX (t) {
let c = cos (t), s = sin (t);  //double
return [c,  0, s, 0,
0,  1, 0, 0,
-s, 0, c, 0];
}

//n = nRotateZX (n, t)
//  Array n
//  double t
function nRotateZX (n, t) {
let c = cos (t), s = sin (t);  //double
let n31 = n[8], n32 = n[9], n33 = n[10], n34 = n[11];  //double
let n11 = n[0], n12 = n[1], n13 = n[ 2], n14 = n[ 3];  //double
n[ 0] = s * n31 + c * n11;
n[ 1] = s * n32 + c * n12;
n[ 2] = s * n33 + c * n13;
n[ 3] = s * n34 + c * n14;
n[ 8] = c * n31 - s * n11;
n[ 9] = c * n32 - s * n12;
n[10] = c * n33 - s * n13;
n[11] = c * n34 - s * n14;
return n;
}

//o = nLetRotateZX (o, n, t)
//  Array o
//  Array n
//  double t
function nLetRotateZX (o, n, t) {
let c = cos (t), s = sin (t);  //double
let n31 = n[8], n32 = n[9], n33 = n[10], n34 = n[11];  //double
let n11 = n[0], n12 = n[1], n13 = n[ 2], n14 = n[ 3];  //double
o[ 0] = s * n31 + c * n11;
o[ 1] = s * n32 + c * n12;
o[ 2] = s * n33 + c * n13;
o[ 3] = s * n34 + c * n14;
o[ 4] = n[ 4];
o[ 5] = n[ 5];
o[ 6] = n[ 6];
o[ 7] = n[ 7];
o[ 8] = c * n31 - s * n11;
o[ 9] = c * n32 - s * n12;
o[10] = c * n33 - s * n13;
o[11] = c * n34 - s * n14;
return o;
}

//o = nNewRotateZX (n, t)
//  Array o
//  Array n
//  double t
function nNewRotateZX (n, t) {
let c = cos (t), s = sin (t);  //double
let n31 = n[8], n32 = n[9], n33 = n[10], n34 = n[11];  //double
let n11 = n[0], n12 = n[1], n13 = n[ 2], n14 = n[ 3];  //double
return [s * n31 + c * n11, s * n32 + c * n12, s * n33 + c * n13, s * n34 + c * n14,
n[ 4],             n[ 5],             n[ 6],             n[ 7],
c * n31 - s * n11, c * n32 - s * n12, c * n33 - s * n13, c * n34 - s * n14];
}

//------------------------------------------------------------------------
//rotationComponent 回転成分
//
//    [n11 n12 n13 n14]     [n11 n12 n13 0]
//    [n21 n22 n23 n24] ==> [n21 n22 n23 0]
//    [n31 n32 n33 n34]     [n31 n32 n33 0]
//    [ 0   0   0   1 ]     [ 0   0   0  1]
//

//o = nRotationComponent (o)
//  Array o
function nRotationComponent (o) {
o[ 3] = 0;
o[ 7] = 0;
o[11] = 0;
return o;
}

//o = nLetRotationComponent (o, n)
//  Array o
//  Array n
function nLetRotationComponent (o, n) {
o[ 0] = n[ 0];
o[ 1] = n[ 1];
o[ 2] = n[ 2];
o[ 3] = 0;
o[ 4] = n[ 4];
o[ 5] = n[ 5];
o[ 6] = n[ 6];
o[ 7] = 0;
o[ 8] = n[ 8];
o[ 9] = n[ 9];
o[10] = n[10];
o[11] = 0;
return o;
}

//o = nNewRotationComponent (n)
//  Array o
//  Array n
function nNewRotationComponent (n) {
return [n[ 0], n[ 1], n[ 2], 0,
n[ 4], n[ 5], n[ 6], 0,
n[ 8], n[ 9], n[10], 0];
}

//------------------------------------------------------------------------
//scale 拡大縮小
//
//    [p 0 0 0]   [x]   [p*x]
//    [0 q 0 0] * [y] = [q*y]
//    [0 0 r 0]   [z]   [r*z]
//    [0 0 0 1]   [1]   [ 1 ]
//
//    [p 0 0 0]   [n11 n12 n13 n14]   [p*n11 p*n12 p*n13 p*n14]
//    [0 q 0 0] * [n21 n22 n23 n24] = [q*n21 q*n22 q*n23 q*n24]
//    [0 0 r 0]   [n31 n32 n33 n34]   [r*n31 r*n32 r*n33 r*n34]
//    [0 0 0 1]   [ 0   0   0   1 ]   [  0     0     0     1  ]
//

//o = nLetIScaleS (o, s)
//  Array o
//  double s
function nLetIScaleS (o, s) {
o[ 0] = s;
o[ 1] = 0;
o[ 2] = 0;
o[ 3] = 0;
o[ 4] = 0;
o[ 5] = s;
o[ 6] = 0;
o[ 7] = 0;
o[ 8] = 0;
o[ 9] = 0;
o[10] = s;
o[11] = 0;
return o;
}

//o = nNewIScaleS (s)
//  Array o
//  double s
function nNewIScaleS (s) {
return [s, 0, 0, 0,
0, s, 0, 0,
0, 0, s, 0];
}

//o = nLetIScaleX (o, p)
//  Array o
//  double p
function nLetIScaleX (o, p) {
o[ 0] = p;
o[ 1] = 0;
o[ 2] = 0;
o[ 3] = 0;
o[ 4] = 0;
o[ 5] = 1;
o[ 6] = 0;
o[ 7] = 0;
o[ 8] = 0;
o[ 9] = 0;
o[10] = 1;
o[11] = 0;
return o;
}

//o = nNewIScaleX (p)
//  Array o
//  double p
function nNewIScaleX (p) {
return [p, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0];
}

//o = nLetIScaleY (o, q)
//  Array o
//  double q
function nLetIScaleY (o, q) {
o[ 0] = 1;
o[ 1] = 0;
o[ 2] = 0;
o[ 3] = 0;
o[ 4] = 0;
o[ 5] = q;
o[ 6] = 0;
o[ 7] = 0;
o[ 8] = 0;
o[ 9] = 0;
o[10] = 1;
o[11] = 0;
return o;
}

//o = nNewIScaleY (q)
//  Array o
//  double q
function nNewIScaleY (q) {
return [1, 0, 0, 0,
0, q, 0, 0,
0, 0, 1, 0];
}

//o = nLetIScaleZ (o, r)
//  Array o
//  double r
function nLetIScaleZ (o, r) {
o[ 0] = 1;
o[ 1] = 0;
o[ 2] = 0;
o[ 3] = 0;
o[ 4] = 0;
o[ 5] = 1;
o[ 6] = 0;
o[ 7] = 0;
o[ 8] = 0;
o[ 9] = 0;
o[10] = r;
o[11] = 0;
return o;
}

//o = nNewIScaleZ (r)
//  Array o
//  double r
function nNewIScaleZ (r) {
return [1, 0, 0, 0,
0, 1, 0, 0,
0, 0, r, 0];
}

//o = nLetIScaleXYZ (o, p, q, r)
//  Array o
//  double p
//  double q
//  double r
function nLetIScaleXYZ (o, p, q, r) {
o[ 0] = p;
o[ 1] = 0;
o[ 2] = 0;
o[ 3] = 0;
o[ 4] = 0;
o[ 5] = q;
o[ 6] = 0;
o[ 7] = 0;
o[ 8] = 0;
o[ 9] = 0;
o[10] = r;
o[11] = 0;
return o;
}

//o = nNewIScaleXYZ (p, q, r)
//  Array o
//  double p
//  double q
//  double r
function nNewIScaleXYZ (p, q, r) {
return [p, 0, 0, 0,
0, q, 0, 0,
0, 0, r, 0];
}

//n = nScaleS (n, s)
//  Array n
//  double s
function nScaleS (n, s) {
n[ 0] *= s;
n[ 1] *= s;
n[ 2] *= s;
n[ 3] *= s;
n[ 4] *= s;
n[ 5] *= s;
n[ 6] *= s;
n[ 7] *= s;
n[ 8] *= s;
n[ 9] *= s;
n[10] *= s;
n[11] *= s;
return n;
}

//o = nLetScaleS (o, n, s)
//  Array o
//  Array n
//  double s
function nLetScaleS (o, n, s) {
o[ 0] = n[ 0] * s;
o[ 1] = n[ 1] * s;
o[ 2] = n[ 2] * s;
o[ 3] = n[ 3] * s;
o[ 4] = n[ 4] * s;
o[ 5] = n[ 5] * s;
o[ 6] = n[ 6] * s;
o[ 7] = n[ 7] * s;
o[ 8] = n[ 8] * s;
o[ 9] = n[ 9] * s;
o[10] = n[10] * s;
o[11] = n[11] * s;
return o;
}

//o = nNewScaleS (n, s)
//  Array o
//  Array n
//  double s
function nNewScaleS (n, s) {
return [n[ 0] * s, n[ 1] * s, n[ 2] * s, n[ 3] * s,
n[ 4] * s, n[ 5] * s, n[ 6] * s, n[ 7] * s,
n[ 8] * s, n[ 9] * s, n[10] * s, n[11] * s];
}

//n = nScaleW (n, w)
//  Array n
//  Array w
function nScaleW (n, w) {
n[ 0] *= w[0];
n[ 1] *= w[0];
n[ 2] *= w[0];
n[ 3] *= w[0];
n[ 4] *= w[1];
n[ 5] *= w[1];
n[ 6] *= w[1];
n[ 7] *= w[1];
n[ 8] *= w[2];
n[ 9] *= w[2];
n[10] *= w[2];
n[11] *= w[2];
return n;
}

//o = nLetScaleW (o, n, w)
//  Array o
//  Array n
//  Array w
function nLetScaleW (o, n, w) {
o[ 0] = n[ 0] * w[0];
o[ 1] = n[ 1] * w[0];
o[ 2] = n[ 2] * w[0];
o[ 3] = n[ 3] * w[0];
o[ 4] = n[ 4] * w[1];
o[ 5] = n[ 5] * w[1];
o[ 6] = n[ 6] * w[1];
o[ 7] = n[ 7] * w[1];
o[ 8] = n[ 8] * w[2];
o[ 9] = n[ 9] * w[2];
o[10] = n[10] * w[2];
o[11] = n[11] * w[2];
return o;
}

//o = nNewScaleW (n, w)
//  Array o
//  Array n
//  Array w
function nNewScaleW (n, w) {
return [n[ 0] * w[0], n[ 1] * w[0], n[ 2] * w[0], n[ 3] * w[0],
n[ 4] * w[1], n[ 5] * w[1], n[ 6] * w[1], n[ 7] * w[1],
n[ 8] * w[2], n[ 9] * w[2], n[10] * w[2], n[11] * w[2]];
}

//n = nScaleX (n, p)
//  Array n
//  double p
function nScaleX (n, p) {
n[ 0] *= p;
n[ 1] *= p;
n[ 2] *= p;
n[ 3] *= p;
return n;
}

//o = nLetScaleX (o, n, p)
//  Array o
//  Array n
//  double p
function nLetScaleX (o, n, p) {
o[ 0] = n[ 0] * p;
o[ 1] = n[ 1] * p;
o[ 2] = n[ 2] * p;
o[ 3] = n[ 3] * p;
o[ 4] = n[ 4];
o[ 5] = n[ 5];
o[ 6] = n[ 6];
o[ 7] = n[ 7];
o[ 8] = n[ 8];
o[ 9] = n[ 9];
o[10] = n[10];
o[11] = n[11];
return o;
}

//o = nNewScaleX (n, p)
//  Array o
//  Array n
//  double p
function nNewScaleX (n, p) {
return [n[ 0] * p, n[ 1] * p, n[ 2] * p, n[ 3] * p,
n[ 4],     n[ 5],     n[ 6],     n[ 7],
n[ 8],     n[ 9],     n[10],     n[11]];
}

//n = nScaleY (n, q)
//  Array n
//  double q
function nScaleY (n, q) {
n[ 4] *= q;
n[ 5] *= q;
n[ 6] *= q;
n[ 7] *= q;
return n;
}

//o = nLetScaleY (o, n, q)
//  Array o
//  Array n
//  double q
function nLetScaleY (o, n, q) {
o[ 0] = n[ 0];
o[ 1] = n[ 1];
o[ 2] = n[ 2];
o[ 3] = n[ 3];
o[ 4] = n[ 4] * q;
o[ 5] = n[ 5] * q;
o[ 6] = n[ 6] * q;
o[ 7] = n[ 7] * q;
o[ 8] = n[ 8];
o[ 9] = n[ 9];
o[10] = n[10];
o[11] = n[11];
return o;
}

//o = nNewScaleY (n, q)
//  Array o
//  Array n
//  double q
function nNewScaleY (n, q) {
return [n[ 0],     n[ 1],     n[ 2],     n[ 3],
n[ 4] * q, n[ 5] * q, n[ 6] * q, n[ 7] * q,
n[ 8],     n[ 9],     n[10],     n[11]];
}

//n = nScaleZ (n, r)
//  Array n
//  double r
function nScaleZ (n, r) {
n[ 8] *= r;
n[ 9] *= r;
n[10] *= r;
n[11] *= r;
return n;
}

//o = nLetScaleZ (o, n, r)
//  Array o
//  Array n
//  double r
function nLetScaleZ (o, n, r) {
o[ 0] = n[ 0];
o[ 1] = n[ 1];
o[ 2] = n[ 2];
o[ 3] = n[ 3];
o[ 4] = n[ 4];
o[ 5] = n[ 5];
o[ 6] = n[ 6];
o[ 7] = n[ 7];
o[ 8] = n[ 8] * r;
o[ 9] = n[ 9] * r;
o[10] = n[10] * r;
o[11] = n[11] * r;
return o;
}

//o = nNewScaleZ (n, r)
//  Array o
//  Array n
//  double r
function nNewScaleZ (n, r) {
return [n[ 0],     n[ 1],     n[ 2],     n[ 3],
n[ 4],     n[ 5],     n[ 6],     n[ 7],
n[ 8] * r, n[ 9] * r, n[10] * r, n[11] * r];
}

//n = nScaleXYZ (n, p, q, r)
//  Array n
//  double p
//  double q
//  double r
function nScaleXYZ (n, p, q, r) {
n[ 0] *= p;
n[ 1] *= p;
n[ 2] *= p;
n[ 3] *= p;
n[ 4] *= q;
n[ 5] *= q;
n[ 6] *= q;
n[ 7] *= q;
n[ 8] *= r;
n[ 9] *= r;
n[10] *= r;
n[11] *= r;
return n;
}

//o = nLetScaleXYZ (o, n, p, q, r)
//  Array o
//  Array n
//  double p
//  double q
//  double r
function nLetScaleXYZ (o, n, p, q, r) {
o[ 0] = n[ 0] * p;
o[ 1] = n[ 1] * p;
o[ 2] = n[ 2] * p;
o[ 3] = n[ 3] * p;
o[ 4] = n[ 4] * q;
o[ 5] = n[ 5] * q;
o[ 6] = n[ 6] * q;
o[ 7] = n[ 7] * q;
o[ 8] = n[ 8] * r;
o[ 9] = n[ 9] * r;
o[10] = n[10] * r;
o[11] = n[11] * r;
return o;
}

//o = nNewScaleXYZ (n, p, q, r)
//  Array o
//  Array n
//  double p
//  double q
//  double r
function nNewScaleXYZ (n, p, q, r) {
return [n[ 0] * p, n[ 1] * p, n[ 2] * p, n[ 3] * p,
n[ 4] * q, n[ 5] * q, n[ 6] * q, n[ 7] * q,
n[ 8] * r, n[ 9] * r, n[10] * r, n[11] * r];
}

//------------------------------------------------------------------------
//translate 平行移動
//
//    [1 0 0 d]   [x]   [x+d]
//    [0 1 0 e] * [y] = [y+e]
//    [0 0 1 f]   [z]   [z+f]
//    [0 0 0 1]   [1]   [ 1 ]
//
//    [1 0 0 d]   [n11 n12 n13 n14]   [n11 n12 n13 n14+d]
//    [0 1 0 e] * [n21 n22 n23 n24] = [n21 n22 n23 n24+e]
//    [0 0 1 f]   [n31 n32 n33 n34]   [n31 n32 n33 n34+f]
//    [0 0 0 1]   [ 0   0   0   1 ]   [ 0   0   0    1  ]
//

//o = nLetITranslateW (o, w)
//  Array n
//  Array w
function nLetITranslateW (o, w) {
o[ 0] = 1;
o[ 1] = 0;
o[ 2] = 0;
o[ 3] = w[0];
o[ 4] = 0;
o[ 5] = 1;
o[ 6] = 0;
o[ 7] = w[1];
o[ 8] = 0;
o[ 9] = 0;
o[10] = 1;
o[11] = w[2];
return o;
}

//o = nNewITranslateW (w)
//  Array n
//  Array w
function nNewITranslateW (w) {
return [1, 0, 0, w[0],
0, 1, 0, w[1],
0, 0, 1, w[2]];
}

//o = nLetITranslateX (o, d)
//  Array n
//  double d
function nLetITranslateX (o, d) {
o[ 0] = 1;
o[ 1] = 0;
o[ 2] = 0;
o[ 3] = d;
o[ 4] = 0;
o[ 5] = 1;
o[ 6] = 0;
o[ 7] = 0;
o[ 8] = 0;
o[ 9] = 0;
o[10] = 1;
o[11] = 0;
return o;
}

//o = nNewITranslateX (d)
//  Array n
//  double d
function nNewITranslateX (d) {
return [1, 0, 0, d,
0, 1, 0, 0,
0, 0, 1, 0];
}

//o = nLetITranslateY (o, e)
//  Array n
//  double e
function nLetITranslateY (o, e) {
o[ 0] = 1;
o[ 1] = 0;
o[ 2] = 0;
o[ 3] = 0;
o[ 4] = 0;
o[ 5] = 1;
o[ 6] = 0;
o[ 7] = e;
o[ 8] = 0;
o[ 9] = 0;
o[10] = 1;
o[11] = 0;
return o;
}

//o = nNewITranslateY (e)
//  Array n
//  double e
function nNewITranslateY (e) {
return [1, 0, 0, 0,
0, 1, 0, e,```