```function mExchange (m) {
let m11 = m[0];
let m12 = m[1];
let m13 = m[2];
let m21 = m[3];
let m22 = m[4];
let m23 = m[5];
m[0] = m22;
m[1] = m21;
m[2] = m23;
m[3] = m12;
m[4] = m11;
m[5] = m13;
return m;
}

//o = mLetExchange (o, m)
function mLetExchange (o, m) {
o[ 0] = m[4];
o[ 1] = m[3];
o[ 2] = m[5];
o[ 3] = m[1];
o[ 4] = m[0];
o[ 5] = m[2];
return o;
}

//o = mNewExchange (m)
function mNewExchange (m) {
return [m[4], m[3], m[5],
m[1], m[0], m[2]];
}

//------------------------------------------------------------------------
//identity 恒等変換
//
//    [1 0 0]   [x]   [x]
//    [0 1 0] * [y] = [y]
//    [0 0 1]   [1]   [1]
//
//    [1 0 0]   [m11 m12 m13]   [m11 m12 m13]
//    [0 1 0] * [m21 m22 m23] = [m21 m22 m23]
//    [0 0 1]   [ 0   0   1 ]   [ 0   0   1 ]
//

//o = mLetIdentity (o)
//  Array o
function mLetIdentity (o) {
o[0] = 1;
o[1] = 0;
o[2] = 0;
o[3] = 0;
o[4] = 1;
o[5] = 0;
return o;
}

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

//------------------------------------------------------------------------
//inverse 逆変換
//
//    d = m11*m22-m12*m21
//
//    [m11 m12 m13]^-1   [ m22/d -m12/d (m12*m23-m13*m22)/d]
//    [m21 m22 m23]    = [-m21/d  m11/d (m13*m21-m11*m23)/d]
//    [ 0   0   1 ]      [   0      0            1         ]
//

//m = mInverse (m)
//  Array m
function mInverse (m) {
let m11 = m[0], m12 = m[1], m13 = m[2];  //double
let m21 = m[3], m22 = m[4], m23 = m[5];  //double
let d = m11 * m22 - m12 * m21;  //double
m[0] = m22 / d;
m[1] = -m12 / d;
m[2] = (m12 * m23 - m13 * m22) / d;
m[3] = -m21 / d;
m[4] = m11 / d;
m[5] = (m13 * m21 - m11 * m23) / d;
return m;
}

//o = mLetInverse (o, m)
//  Array o
//  Array m
function mLetInverse (o, m) {
let m11 = m[0], m12 = m[1], m13 = m[2];  //double
let m21 = m[3], m22 = m[4], m23 = m[5];  //double
let d = m11 * m22 - m12 * m21;  //double
o[0] = m22 / d;
o[1] = -m12 / d;
o[2] = (m12 * m23 - m13 * m22) / d;
o[3] = -m21 / d;
o[4] = m11 / d;
o[5] = (m13 * m21 - m11 * m23) / d;
return o;
}

//o = mNewInverse (m)
//  Array o
//  Array m
function mNewInverse (m) {
let m11 = m[0], m12 = m[1], m13 = m[2];  //double
let m21 = m[3], m22 = m[4], m23 = m[5];  //double
let d = m11 * m22 - m12 * m21;  //double
return [m22 / d,  -m12 / d, (m12 * m23 - m13 * m22) / d,
-m21 / d,  m11 / d, (m13 * m21 - m11 * m23) / d];
}

//------------------------------------------------------------------------
//rotate 回転(+x→+y)
//
//    [cos(t) -sin(t) 0]   [x]   [cos(t)*x-sin(t)*y]
//    [sin(t)  cos(t) 0] * [y] = [sin(t)*x+cos(t)*y]
//    [  0       0    1]   [1]   [        1        ]
//
//    [cos(t) -sin(t) 0]   [m11 m12 m13]   [cos(t)*m11-sin(t)*m21 cos(t)*m12-sin(t)*m22 cos(t)*m13-sin(t)*m23]
//    [sin(t)  cos(t) 0] * [m21 m22 m23] = [sin(t)*m11+cos(t)*m21 sin(t)*m12+cos(t)*m22 sin(t)*m13+cos(t)*m23]
//    [  0       0    1]   [ 0   0   1 ]   [          0                     0                     1          ]
//

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

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

//m = mRotate (m, t)
//  Array m
//  double t
function mRotate (m, t) {
let c = cos (t), s = sin (t);  //double
let m11 = m[0], m12 = m[1], m13 = m[2];  //double
let m21 = m[3], m22 = m[4], m23 = m[5];  //double
m[0] = c * m11 - s * m21;
m[1] = c * m12 - s * m22;
m[2] = c * m13 - s * m23;
m[3] = s * m11 + c * m21;
m[4] = s * m12 + c * m22;
m[5] = s * m13 + c * m23;
return m;
}

//o = mLetRotate (o, m, t)
//  Array o
//  Array m
//  double t
function mLetRotate (o, m, t) {
let c = cos (t), s = sin (t);  //double
let m11 = m[0], m12 = m[1], m13 = m[2];  //double
let m21 = m[3], m22 = m[4], m23 = m[5];  //double
o[0] = c * m11 - s * m21;
o[1] = c * m12 - s * m22;
o[2] = c * m13 - s * m23;
o[3] = s * m11 + c * m21;
o[4] = s * m12 + c * m22;
o[5] = s * m13 + c * m23;
return o;
}

//o = mNewRotate (m, t)
//  Array o
//  Array m
//  double t
function mNewRotate (m, t) {
let c = cos (t), s = sin (t);  //double
let m11 = m[0], m12 = m[1], m13 = m[2];  //double
let m21 = m[3], m22 = m[4], m23 = m[5];  //double
return [c * m11 - s * m21, c * m12 - s * m22, c * m13 - s * m23,
s * m11 + c * m21, s * m12 + c * m22, s * m13 + c * m23];
}

//------------------------------------------------------------------------
//rotationComponent 回転成分
//
//    [m11 m12 m13]     [m11 m12 0]
//    [m21 m22 m23] ==> [m21 m22 0]
//    [ 0   0   1 ]     [ 0   0  1]
//

//o = mRotationComponent (o)
//  Array o
function mRotationComponent (o) {
o[ 2] = 0;
o[ 5] = 0;
return o;
}

//o = mLetRotationComponent (o, m)
//  Array o
//  Array m
function mLetRotationComponent (o, m) {
o[ 0] = m[ 0];
o[ 1] = m[ 1];
o[ 2] = 0;
o[ 3] = m[ 3];
o[ 4] = m[ 4];
o[ 5] = 0;
return o;
}

//o = mNewRotationComponent (m)
//  Array o
//  Array m
function mNewRotationComponent (m) {
return [m[ 0], m[ 1], 0,
m[ 3], m[ 4], 0];
}

//------------------------------------------------------------------------
//scale 拡大縮小
//
//    [p 0 0]   [x]   [p*x]
//    [0 q 0] * [y] = [q*y]
//    [0 0 1]   [1]   [ 1 ]
//
//    [p 0 0]   [m11 m12 m13]   [p*m11 p*m12 p*m13]
//    [0 q 0] * [m21 m22 m23] = [q*m21 q*m22 q*m23]
//    [0 0 1]   [ 0   0   1 ]   [  0     0     1  ]
//

//o = mLetIScaleS (o, s)
//  Array o
//  double s
function mLetIScaleS (o, s) {
o[0] = s;
o[1] = 0;
o[2] = 0;
o[3] = 0;
o[4] = s;
o[5] = 0;
return o;
}

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

//o = mLetIScaleX (o, p)
//  Array o
//  double p
function mLetIScaleX (o, p) {
o[0] = p;
o[1] = 0;
o[2] = 0;
o[3] = 0;
o[4] = 1;
o[5] = 0;
return o;
}

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

//o = mLetIScaleY (o, q)
//  Array o
//  double q
function mLetIScaleY (o, q) {
o[0] = 1;
o[1] = 0;
o[2] = 0;
o[3] = 0;
o[4] = q;
o[5] = 0;
return o;
}

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

//m = mScaleS (m, s)
//  Array m
//  double s
function mScaleS (m, s) {
m[0] *= s;
m[1] *= s;
m[2] *= s;
m[3] *= s;
m[4] *= s;
m[5] *= s;
return m;
}

//o = mLetScaleS (o, m, s)
//  Array o
//  Array m
//  double s
function mLetScaleS (o, m, s) {
o[0] = m[0] * s;
o[1] = m[1] * s;
o[2] = m[2] * s;
o[3] = m[3] * s;
o[4] = m[4] * s;
o[5] = m[5] * s;
return o;
}

//o = mNewScaleS (m, s)
//  Array o
//  Array m
//  double s
function mNewScaleS (m, s) {
return [m[0] * s, m[1] * s, m[2] * s,
m[3] * s, m[4] * s, m[5] * s];
}

//m = mScaleV (m, v)
//  Array m
//  Array v
function mScaleV (m, v) {
let p = v[0];
let q = v[1];
m[0] *= p;
m[1] *= p;
m[2] *= p;
m[3] *= q;
m[4] *= q;
m[5] *= q;
return m;
}

//o = mLetScaleV (o, m, v)
//  Array o
//  Array m
//  Array v
function mLetScaleV (o, m, v) {
let p = v[0];
let q = v[1];
o[0] = m[0] * p;
o[1] = m[1] * p;
o[2] = m[2] * p;
o[3] = m[3] * q;
o[4] = m[4] * q;
o[5] = m[5] * q;
return o;
}

//o = mNewScaleV (m, v)
//  Array o
//  Array m
//  Array v
function mNewScaleV (m, v) {
let p = v[0];
let q = v[1];
return [m[0] * p, m[1] * p, m[2] * p,
m[3] * q, m[4] * q, m[5] * q];
}

//m = mScaleX (m, p)
//  Array m
//  double p
function mScaleX (m, p) {
m[0] *= p;
m[1] *= p;
m[2] *= p;
return m;
}

//o = mLetScaleX (o, m, p)
//  Array o
//  Array m
//  double p
function mLetScaleX (o, m, p) {
o[0] = m[0] * p;
o[1] = m[1] * p;
o[2] = m[2] * p;
o[3] = m[3];
o[4] = m[4];
o[5] = m[5];
return o;
}

//o = mNewScaleX (m, p)
//  Array o
//  Array m
//  double p
function mNewScaleX (m, p) {
return [m[0] * p, m[1] * p, m[2] * p,
m[3],     m[4],     m[5]];
}

//m = mScaleY (m, q)
//  Array m
//  double q
function mScaleY (m, q) {
m[3] *= q;
m[4] *= q;
m[5] *= q;
return m;
}

//o = mLetScaleY (o, m, q)
//  Array o
//  Array m
//  double q
function mLetScaleY (o, m, q) {
o[0] = m[0];
o[1] = m[1];
o[2] = m[2];
o[3] = m[3] * q;
o[4] = m[4] * q;
o[5] = m[5] * q;
return o;
}

//o = mNewScaleY (m, q)
//  Array o
//  Array m
//  double q
function mNewScaleY (m, q) {
return [m[0],     m[1],     m[2],
m[3] * q, m[4] * q, m[5] * q];
}

//m = mScaleXY (m, p, q)
//  Array m
//  double p
//  double q
function mScaleXY (m, p, q) {
m[0] *= p;
m[1] *= p;
m[2] *= p;
m[3] *= q;
m[4] *= q;
m[5] *= q;
return m;
}

//o = mLetScaleXY (o, m, p ,q)
//  Array o
//  Array m
//  double p
//  double q
function mLetScaleXY (o, m, p, q) {
o[0] = m[0] * p;
o[1] = m[1] * p;
o[2] = m[2] * p;
o[3] = m[3] * q;
o[4] = m[4] * q;
o[5] = m[5] * q;
return o;
}

//o = mNewScaleXY (m, p, q)
//  Array o
//  Array m
//  double p
//  double q
function mNewScaleXY (m, p, q) {
return [m[0] * p, m[1] * p, m[2] * p,
m[3] * q, m[4] * q, m[5] * q];
}

//------------------------------------------------------------------------
//translate 平行移動
//
//    [1 0 d]   [x]   [x+d]
//    [0 1 e] * [y] = [y+e]
//    [0 0 1]   [1]   [ 1 ]
//
//    [1 0 d]   [m11 m12 m13]   [m11 m12 m13+d]
//    [0 1 e] * [m21 m22 m23] = [m21 m22 m23+e]
//    [0 0 1]   [ 0   0   1 ]   [ 0   0    1  ]
//

//o = mLetITranslateV (o, v)
//  Array o
//  Array v
function mLetITranslateV (o, v) {
o[0] = 1;
o[1] = 0;
o[2] = v[0];
o[3] = 0;
o[4] = 1;
o[5] = v[1];
return o;
}

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

//o = mLetITranslateX (o, d)
//  Array o
//  double d
function mLetITranslateX (o, d) {
o[0] = 1;
o[1] = 0;
o[2] = d;
o[3] = 0;
o[4] = 1;
o[5] = 0;
return o;
}

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

//o = mLetITranslateY (o, e)
//  Array o
//  double e
function mLetITranslateY (o, e) {
o[0] = 1;
o[1] = 0;
o[2] = 0;
o[3] = 0;
o[4] = 1;
o[5] = e;
return o;
}

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

//o = mLetITranslateXY (o, d, e)
//  Array o
//  double d
//  double e
function mLetITranslateXY (o, d, e) {
o[0] = 1;
o[1] = 0;
o[2] = d;
o[3] = 0;
o[4] = 1;
o[5] = e;
return o;
}

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

//m = mTranslateV (m, v)
//  Array m
//  Array v
function mTranslateV (m, v) {
m[2] += v[0];
m[5] += v[1];
return m;
}

//o = mLetTranslateV (o, m, v)
//  Array o
//  Array m
//  Array v
function mLetTranslateV (o, m, v) {
o[0] = m[0];
o[1] = m[1];
o[2] = m[2] + v[0];
o[3] = m[3];
o[4] = m[4];
o[5] = m[5] + v[1];
return o;
}

//o = mNewTranslateV (m, v)
//  Array o
//  Array m
//  Array v
function mNewTranslateV (m, v) {
return [m[0], m[1], m[2] + v[0],
m[3], m[4], m[5] + v[1]];
}

//m = mTranslateX (m, d)
//  Array m
//  double d
function mTranslateX (m, d) {
m[2] += d;
return m;
}

//o = mLetTranslateX (o, m, d)
//  Array o
//  Array m
//  double d
function mLetTranslateX (o, m, d) {
o[0] = m[0];
o[1] = m[1];
o[2] = m[2] + d;
o[3] = m[3];
o[4] = m[4];
o[5] = m[5];
return o;
}

//o = mNewTranslateX (m, d)
//  Array o
//  Array m
//  double d
function mNewTranslateX (m, d) {
return [m[0], m[1], m[2] + d,
m[3], m[4], m[5]];
}

//m = mTranslateY (m, e)
//  Array m
//  double e
function mTranslateY (m, e) {
m[5] += e;
return m;
}

//o = mLetTranslateY (o, m, e)
//  Array o
//  Array m
//  double e
function mLetTranslateY (o, m, e) {
o[0] = m[0];
o[1] = m[1];
o[2] = m[2];
o[3] = m[3];
o[4] = m[4];
o[5] = m[5] + e;
return o;
}

//o = mNewTranslateY (m, e)
//  Array o
//  Array m
//  double e
function mNewTranslateY (m, e) {
return [m[0], m[1], m[2],
m[3], m[4], m[5] + e];
}

//m = mTranslateXY (m, d, e)
//  Array m
//  double d
//  double e
function mTranslateXY (m, d, e) {
m[2] += d;
m[5] += e;
return m;
}

//o = mLetTranslateXY (o, m, d, e)
//  Array o
//  Array m
//  double d
//  double e
function mLetTranslateXY (o, m, d, e) {
o[0] = m[0];
o[1] = m[1];
o[2] = m[2] + d;
o[3] = m[3];
o[4] = m[4];
o[5] = m[5] + e;
return o;
}

//o = mNewTranslateXY (m, d, e)
//  Array o
//  Array m
//  double d
//  double e
function mNewTranslateXY (m, d, e) {
return [m[0], m[1], m[2] + d,
m[3], m[4], m[5] + e];
}

//------------------------------------------------------------------------
//translationComponent 移動成分
//
//    [m11 m12 m13]     [1 0 m13]
//    [m21 m22 m23] ==> [0 1 m23]
//    [ 0   0   1 ]     [0 0  1 ]
//

//o = mTranslationComponent (o)
//  Array o
function mTranslationComponent (o) {
o[ 0] = 1;
o[ 1] = 0;
o[ 3] = 0;
o[ 4] = 1;
return o;
}

//o = mLetTranslationComponent (o, m)
//  Array o
//  Array m
function mLetTranslationComponent (o, m) {
o[ 0] = 1;
o[ 1] = 0;
o[ 2] = m[ 2];
o[ 3] = 0;
o[ 4] = 1;
o[ 5] = m[ 5];
return o;
}

//o = mNewTranslationComponent (m)
//  Array o
//  Array m
function mNewTranslationComponent (m) {
return [1, 0, m[ 2],
0, 1, m[ 5]];
}

//========================================================================
//空間アフィン変換(n～)
//
//    [n11 n12 n13 n14]   [n[0] n[1] n[ 2] n[ 3]]
//    [n21 n22 n23 n24] = [n[4] n[5] n[ 6] n[ 7]]
//    [n31 n32 n33 n34]   [n[8] n[9] n[10] n[11]]
//    [ 0   0   0   1 ]   [  0    0     0     1 ]
//
//    [n11 n12 n13 n14]   [x]   [n11*x+n12*y+n13*z+n14]
//    [n21 n22 n23 n24] * [y] = [n21*x+n22*y+n23*z+n24]
//    [n31 n32 n33 n34]   [z]   [n31*x+n32*y+n33*z+n34]
//    [ 0   0   0   1 ]   [1]   [          1          ]
//

//------------------------------------------------------------------------
//concatenate 連結
//
//    [a11 a12 a13 a14]   [n11 n12 n13 n14]   [a11*n11+a12*n21+a13*n31 a11*n12+a12*n22+a13*n32 a11*n13+a12*n23+a13*n33 a11*n14+a12*n24+a13*n34+a14]
//    [a21 a22 a23 a24] * [n21 n22 n23 n24] = [a21*n11+a22*n21+a23*n31 a21*n12+a22*n22+a23*n32 a21*n13+a22*n23+a23*n33 a21*n14+a22*n24+a23*n34+a24]
//    [a31 a32 a33 a34]   [n31 n32 n33 n34]   [a31*n11+a32*n21+a33*n31 a31*n12+a32*n22+a33*n32 a31*n13+a32*n23+a33*n33 a31*n14+a32*n24+a33*n34+a34]
//    [ 0   0   0   1 ]   [ 0   0   0   1 ]   [           0                       0                       0                         1             ]
//
//  a*n
//  引数の順序に注意

//n = nConcatenate (n, a)
//  Array n
//  Array a
function nConcatenate (n, a) {
let a11 = a[0], a12 = a[1], a13 = a[ 2], a14 = a[ 3];  //double
let a21 = a[4], a22 = a[5], a23 = a[ 6], a24 = a[ 7];  //double
let a31 = a[8], a32 = a[9], a33 = a[10], a34 = a[11];  //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
let n31 = n[8], n32 = n[9], n33 = n[10], n34 = n[11];  //double
n[ 0] = a11 * n11 + a12 * n21 + a13 * n31;
n[ 1] = a11 * n12 + a12 * n22 + a13 * n32;
n[ 2] = a11 * n13 + a12 * n23 + a13 * n33;
n[ 3] = a11 * n14 + a12 * n24 + a13 * n34 + a14;
n[ 4] = a21 * n11 + a22 * n21 + a23 * n31;
n[ 5] = a21 * n12 + a22 * n22 + a23 * n32;
n[ 6] = a21 * n13 + a22 * n23 + a23 * n33;
n[ 7] = a21 * n14 + a22 * n24 + a23 * n34 + a24;
n[ 8] = a31 * n11 + a32 * n21 + a33 * n31;
n[ 9] = a31 * n12 + a32 * n22 + a33 * n32;
n[10] = a31 * n13 + a32 * n23 + a33 * n33;
n[11] = a31 * n14 + a32 * n24 + a33 * n34 + a34;
return n;
}

//o = nLetConcatenate (o, n, a)
//  Array o
//  Array n
//  Array a
function nLetConcatenate (o, n, a) {
let a11 = a[0], a12 = a[1], a13 = a[ 2], a14 = a[ 3];  //double
let a21 = a[4], a22 = a[5], a23 = a[ 6], a24 = a[ 7];  //double
let a31 = a[8], a32 = a[9], a33 = a[10], a34 = a[11];  //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
let n31 = n[8], n32 = n[9], n33 = n[10], n34 = n[11];  //double
o[ 0] = a11 * n11 + a12 * n21 + a13 * n31;
o[ 1] = a11 * n12 + a12 * n22 + a13 * n32;
o[ 2] = a11 * n13 + a12 * n23 + a13 * n33;
o[ 3] = a11 * n14 + a12 * n24 + a13 * n34 + a14;
o[ 4] = a21 * n11 + a22 * n21 + a23 * n31;
o[ 5] = a21 * n12 + a22 * n22 + a23 * n32;
o[ 6] = a21 * n13 + a22 * n23 + a23 * n33;
o[ 7] = a21 * n14 + a22 * n24 + a23 * n34 + a24;
o[ 8] = a31 * n11 + a32 * n21 + a33 * n31;
o[ 9] = a31 * n12 + a32 * n22 + a33 * n32;
o[10] = a31 * n13 + a32 * n23 + a33 * n33;
o[11] = a31 * n14 + a32 * n24 + a33 * n34 + a34;
return o;
}

//o = nNewConcatenate (n, a)
//  Array o
//  Array n
//  Array a
function nNewConcatenate (n, a) {
let a11 = a[0], a12 = a[1], a13 = a[ 2], a14 = a[ 3];  //double
let a21 = a[4], a22 = a[5], a23 = a[ 6], a24 = a[ 7];  //double
let a31 = a[8], a32 = a[9], a33 = a[10], a34 = a[11];  //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
let n31 = n[8], n32 = n[9], n33 = n[10], n34 = n[11];  //double
return [a11 * n11 + a12 * n21 + a13 * n31,
a11 * n12 + a12 * n22 + a13 * n32,
a11 * n13 + a12 * n23 + a13 * n33,
a11 * n14 + a12 * n24 + a13 * n34 + a14,
a21 * n11 + a22 * n21 + a23 * n31,
a21 * n12 + a22 * n22 + a23 * n32,
a21 * n13 + a22 * n23 + a23 * n33,
a21 * n14 + a22 * n24 + a23 * n34 + a24,
a31 * n11 + a32 * n21 + a33 * n31,
a31 * n12 + a32 * n22 + a33 * n32,
a31 * n13 + a32 * n23 + a33 * n33,
a31 * n14 + a32 * n24 + a33 * n34 + a34];
}

//------------------------------------------------------------------------
//copy コピー

//o = nLetCopy (o, n)
//  Array o
//  Array n
function nLetCopy (o, n) {
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];
o[ 9] = n[ 9];
o[10] = n[10];
o[11] = n[11];
return o;
}

//o = nNewCopy (n)
//  Array o
//  Array n
function nNewCopy (n) {
return n.concat ();
}

//------------------------------------------------------------------------
//exchangeYZX 軸交換(+x→+y,+y→+z,+z→+x)
//
//    [n11 n12 n13 n14]     [n33 n31 n32 n34]
//    [n21 n22 n23 n24] ==> [n13 n11 n12 n14]
//    [n31 n32 n33 n34]     [n23 n21 n22 n24]
//    [ 0   0   0   1 ]     [ 0   0   0   1 ]
//

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

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

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

//------------------------------------------------------------------------
//exchangeZXY 軸交換(+x→+z,+y→+x,+z→+y)
//
//    [n11 n12 n13 n14]     [n22 n23 n21 n24]
//    [n21 n22 n23 n24] ==> [n32 n33 n31 n34]
//    [n31 n32 n33 n34]     [n12 n13 n11 n14]
//    [ 0   0   0   1 ]     [ 0   0   0   1 ]
//

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

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