←Previous | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | Next→
  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,
←Previous | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | Next→