0, 0, 1, 0];
}
function nLetITranslateZ (o, f) {
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] = f;
return o;
}
function nNewITranslateZ (f) {
return [1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, f];
}
function nLetITranslateXYZ (o, d, e, f) {
o[ 0] = 1;
o[ 1] = 0;
o[ 2] = 0;
o[ 3] = d;
o[ 4] = 0;
o[ 5] = 1;
o[ 6] = 0;
o[ 7] = e;
o[ 8] = 0;
o[ 9] = 0;
o[10] = 1;
o[11] = f;
return o;
}
function nNewITranslateXYZ (d, e, f) {
return [1, 0, 0, d,
0, 1, 0, e,
0, 0, 1, f];
}
function nTranslateW (n, w) {
n[ 3] += w[0];
n[ 7] += w[1];
n[11] += w[2];
return n;
}
function nLetTranslateW (o, n, w) {
o[ 0] = n[ 0];
o[ 1] = n[ 1];
o[ 2] = n[ 2];
o[ 3] = n[ 3] + w[0];
o[ 4] = n[ 4];
o[ 5] = n[ 5];
o[ 6] = n[ 6];
o[ 7] = n[ 7] + w[1];
o[ 8] = n[ 8];
o[ 9] = n[ 9];
o[10] = n[10];
o[11] = n[11] + w[2];
return o;
}
function nNewTranslateW (n, w) {
return [n[ 0], n[ 1], n[ 2], n[ 3] + w[0],
n[ 4], n[ 5], n[ 6], n[ 7] + w[1],
n[ 8], n[ 9], n[10], n[11] + w[2]];
}
function nTranslateX (n, d) {
n[ 3] += d;
return n;
}
function nLetTranslateX (o, n, d) {
o[ 0] = n[ 0];
o[ 1] = n[ 1];
o[ 2] = n[ 2];
o[ 3] = n[ 3] + d;
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;
}
function nNewTranslateX (n, d) {
return [n[ 0], n[ 1], n[ 2], n[ 3] + d,
n[ 4], n[ 5], n[ 6], n[ 7],
n[ 8], n[ 9], n[10], n[11]];
}
function nTranslateY (n, e) {
n[ 7] += e;
return n;
}
function nLetTranslateY (o, n, e) {
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] + e;
o[ 8] = n[ 8];
o[ 9] = n[ 9];
o[10] = n[10];
o[11] = n[11];
return o;
}
function nNewTranslateY (n, e) {
return [n[ 0], n[ 1], n[ 2], n[ 3],
n[ 4], n[ 5], n[ 6], n[ 7] + e,
n[ 8], n[ 9], n[10], n[11]];
}
function nTranslateZ (n, f) {
n[11] += f;
return n;
}
function nLetTranslateZ (o, n, f) {
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] + f;
return o;
}
function nNewTranslateZ (n, f) {
return [n[ 0], n[ 1], n[ 2], n[ 3],
n[ 4], n[ 5], n[ 6], n[ 7],
n[ 8], n[ 9], n[10], n[11] + f];
}
function nTranslateXYZ (n, d, e, f) {
n[ 3] += d;
n[ 7] += e;
n[11] += f;
return n;
}
function nLetTranslateXYZ (o, n, d, e, f) {
o[ 0] = n[ 0];
o[ 1] = n[ 1];
o[ 2] = n[ 2];
o[ 3] = n[ 3] + d;
o[ 4] = n[ 4];
o[ 5] = n[ 5];
o[ 6] = n[ 6];
o[ 7] = n[ 7] + e;
o[ 8] = n[ 8];
o[ 9] = n[ 9];
o[10] = n[10];
o[11] = n[11] + f;
return o;
}
function nNewTranslateXYZ (n, d, e, f) {
return [n[ 0], n[ 1], n[ 2], n[ 3] + d,
n[ 4], n[ 5], n[ 6], n[ 7] + e,
n[ 8], n[ 9], n[10], n[11] + f];
}
function nTranslationComponent (o) {
o[ 0] = 1;
o[ 1] = 0;
o[ 2] = 0;
o[ 4] = 0;
o[ 5] = 1;
o[ 6] = 0;
o[ 8] = 0;
o[ 9] = 0;
o[10] = 1;
return o;
}
function nLetTranslationComponent (o, n) {
o[ 0] = 1;
o[ 1] = 0;
o[ 2] = 0;
o[ 3] = n[ 3];
o[ 4] = 0;
o[ 5] = 1;
o[ 6] = 0;
o[ 7] = n[ 7];
o[ 8] = 0;
o[ 9] = 0;
o[10] = 1;
o[11] = n[11];
return o;
}
function nNewTranslationComponent (n) {
return [1, 0, 0, n[ 3],
0, 1, 0, n[ 7],
0, 0, 1, n[11]];
}
let pgStrokeLinecap = "butt";
let pgStrokeLinejoin = "bevel";
let pgStrokeMiterlimit = 4;
function pgPolyline (pl, linewidth) {
const step = rad (15);
let va = pl.pl$vertexArray;
let ea = pl.pl$edgeArray;
let wh = linewidth * 0.5;
let va2 = [];
let fa2 = [];
let wa = [];
for (let i = 0; i < ea.length; i++) {
wa[i] = [];
for (let j = 0; j < ea[i].length; j++) {
wa[i][j] = false;
}
}
let vn1 = 0;
let en12 = 0;
let vstart = 0;
loop:
for (;;) {
wa[vn1][en12] = true;
let vn2 = ea[vn1][en12];
let en21 = 0;
while (ea[vn2][en21] != vn1) {
en21++;
}
let en23 = en21 + 1 < ea[vn2].length ? en21 + 1 : 0;
let vn3 = ea[vn2][en23];
let v1 = va[vn1];
let v2 = va[vn2];
let v3 = va[vn3];
let h12 = vHat (vNewSubtractV (v2, v1));
let h23 = vHat (vNewSubtractV (v3, v2));
let a12 = vAzimuth (h12);
let a23 = vAzimuth (h23);
let a13 = a23 - a12 - floor ((a23 - a12 + PI) / TWOPI) * TWOPI;
if (a13 <= -PI || PI <= a13) {
if (pgStrokeLinecap == "square") {
va2.push (vTranslateV (vRotate (vScaleS ([1, -1], wh), a12), v2));
va2.push (vTranslateV (vRotate (vScaleS ([1, 1], wh), a12), v2));
} else {
let t1 = -PI / 2;
let t2 = PI / 2;
let n = pgStrokeLinecap == "round" ? max2 (1, roundn ((t2 - t1) / step)) : 1;
for (let i = 0; i <= n; i++) {
let t = (n - i) / n * t1 + i / n * t2;
va2.push (vTranslateV (vRotate (vScaleS ([cos (t), sin (t)], wh), a12), v2));
}
}
} else if (a13 == 0) {
} else if (a13 < 0 ||
(pgStrokeLinejoin == "miter" &&
2 * asin (1 / pgStrokeMiterlimit) < PI - a13)) {
va2.push (vTranslateV (vRotate (vScaleS ([-1 / tan (a13 * 0.5 - PI / 2), -1], wh), a12), v2));
} else {
let t1 = -PI / 2;
let t2 = -PI / 2 + a13;
let n = pgStrokeLinejoin == "round" ? max2 (1, roundn ((t2 - t1) / step)) : 1;
for (let i = 0; i <= n; i++) {
let t = (n - i) / n * t1 + i / n * t2;
va2.push (vTranslateV (vRotate (vScaleS ([cos (t), sin (t)], wh), a12), v2));
}
}
vn1 = vn2;
en12 = en23;
if (wa[vn1][en12]) {
let f2 = [];
for (let i = vstart; i < va2.length; i++) {
f2.push (i);
}
fa2.push (f2);
vstart = va2.length;
for (let i = 0; i < ea.length; i++) {
for (let j = 0; j < ea[i].length; j++) {
if (!wa[i][j]) {
vn1 = i;
en12 = j;
continue loop;
}
}
}
break;
}
}
return { pg$vertexArray: va2, pg$faceArray: fa2 };
}
function pgToString (pg) {
let va = pg.pg$vertexArray;
let fa = pg.pg$faceArray;
let s = "";
s += "{va:[";
for (let i = 0; i < va.length; i++) {
if (0 < i) {
s += ",";
}
s += "[" + va[i].join (",") + "]";
}
s += "],fa:[";
for (let i = 0; i < fa.length; i++) {
if (0 < i) {
s += ",";
}
s += "[" + fa[i].join (",") + "]";
}
s += "]}";
return s;
}
const RE_NUM = "([-+]?\\d+(?:\\.\\d*)?(?:[Ee][-+]?\\d+)?)";
function pgTurtle (str) {
const step = 5;
const eps = 1e-8;
let tx = 0;
let ty = 0;
let ta = 0;
let td = false;
let va = [];
let fa = [];
let vn = -1;
let fn = -1;
let rex = new RegExp ("\\s*(?:" +
"(a\\s*" + RE_NUM + ")|" +
"(cl\\s*" + RE_NUM + "\\s*,\\s*" + RE_NUM + ")|" +
"(cr\\s*" + RE_NUM + "\\s*,\\s*" + RE_NUM + ")|" +
"(d\\s*)|" +
"(f\\s*" + RE_NUM + ")|" +
"(j\\s*" + RE_NUM + "\\s*,\\s*" + RE_NUM + ")|" +
"(l\\s*" + RE_NUM + ")|" +
"(m\\s*" + RE_NUM + "\\s*,\\s*" + RE_NUM + ")|" +
"(r\\s*" + RE_NUM + ")|" +
"(u\\s*)" +
")", "g");
let mat;
while (mat = rex.exec (str)) {
if (mat[1]) {
ta = parseFloat (mat[2]);
ta -= floor (ta / 360) * 360;
} else if (mat[3]) {
let a = parseFloat (mat[4]);
let r = parseFloat (mat[5]);
let ox = tx - r * sin (rad (ta));
let oy = ty + r * cos (rad (ta));
let b1 = ta - 90;
ta += a;
let b2 = ta - 90;
ta -= floor (ta / 360) * 360;
if (td) {
let n = max2 (1, roundn ((b2 - b1) / step));
for (let i = 0; i < n; i++) {
let b = (n - i) / n * b1 + i / n * b2;
tx = ox + r * cos (rad (b));
ty = oy + r * sin (rad (b));
va[++vn] = [tx, ty];
fa[fn].push (vn);
}
}
tx = ox + r * cos (rad (b2));
ty = oy + r * sin (rad (b2));
} else if (mat[6]) {
let a = parseFloat (mat[7]);
let r = parseFloat (mat[8]);
let ox = tx + r * sin (rad (ta));
let oy = ty - r * cos (rad (ta));
let b1 = ta + 90;
ta -= a;
let b2 = ta + 90;
ta -= floor (ta / 360) * 360;
if (td) {
let n = max2 (1, roundn ((b1 - b2) / step));
for (let i = 0; i < n; i++) {
let b = (n - i) / n * b1 + i / n * b2;
tx = ox + r * cos (rad (b));
ty = oy + r * sin (rad (b));
va[++vn] = [tx, ty];
fa[fn].push (vn);
}
}
tx = ox + r * cos (rad (b2));
ty = oy + r * sin (rad (b2));
} else if (mat[9]) {
if (!td) {
td = true;
fa[++fn] = [];
}
} else if (mat[10]) {
if (td) {
va[++vn] = [tx, ty];
fa[fn].push (vn);
}
let d = parseFloat (mat[11]);
tx += d * cos (rad (ta));
ty += d * sin (rad (ta));
} else if (mat[12]) {
if (td) {
va[++vn] = [tx, ty];
fa[fn].push (vn);
}
tx = parseFloat (mat[13]);
ty = parseFloat (mat[14]);
} else if (mat[15]) {
ta += parseFloat (mat[16]);
ta -= floor (ta / 360) * 360;
} else if (mat[17]) {
if (td) {
va[++vn] = [tx, ty];
fa[fn].push (vn);
}
tx += parseFloat (mat[18]);
ty += parseFloat (mat[19]);
} else if (mat[20]) {
ta -= parseFloat (mat[21]);
ta -= floor (ta / 360) * 360;
} else if (mat[22]) {
if (td) {
let v = va[fa[fn][0]];
let vx = v[0];
let vy = v[1];
if (eps < abs (tx - vx) || eps < abs (ty - vy)) {
va[++vn] = [tx, ty];
fa[fn].push (vn);
}
tx = vx;
ty = vy;
ta = 0;
td = false;
}
}
}
if (td) {
let v = va[fa[fn][0]];
let vx = v[0];
let vy = v[1];
if (eps < abs (tx - vx) || eps < abs (ty - vy)) {
va[++vn] = [tx, ty];
fa[fn].push (vn);
}
tx = vx;
ty = vy;
ta = 0;
td = false;
}
return { pg$vertexArray: va, pg$faceArray: fa };
}
function phNew (va, fa, oa) {
return phMakeFields ({
ph$vertexArray: va,
ph$faceArray: fa,
ph$openArray: oa || null
});
}
function pgArea (va) {
let s = 0;
let v = va[0];
let x1 = v[0];
let y1 = v[1];
for (let i = va.length - 1; 0 <= i; i--) {
v = va[i];
let x0 = v[0];
let y0 = v[1];
s += (x0 - x1) * (y0 + y1);
x1 = x0;
y1 = y0;
}
return s * 0.5;
}
function phMakeFields (ph) {
const eps = 1e-4;
if (!ph.ph$openArray) {
let fa = ph.ph$faceArray;
let oa = [];
for (let i = 0; i < fa.length; i++) {
oa[i] = 0;
}
ph.ph$openArray = oa;
}
if (!ph.ph$normalArray) {
let va = ph.ph$vertexArray;
let fa = ph.ph$faceArray;
let na = [];
for (let i = 0; i < fa.length; i++) {
let f = fa[i];
let va1 = [];
for (let j = 0; j < f.length; j++) {
va1[j] = va[f[j]].concat ();
}
let a = va1[0];
let b = va1[1];
let c;
for (let j = 2; j < va1.length; j++) {
c = va1[j];
if (eps < wAreaOfTriangle (a, b, c)) {
break;
}
}
let n = wNewNormal (a, b, c);
let nx = n[0];
let ny = n[1];
let nz = n[2];
let n2x;
let n2y;
let n2z;
let va2 = [];
let r = hypot2 (nx, nz);
if (r < eps) {
n2x = nx;
n2y = ny;
n2z = nz;
for (let j = 0; j < va1.length; j++) {
va2[j] = va1[j].concat ();
}
} else {
let cxz = nz / r;
let sxz = nx / r;
for (let j = 0; j < va1.length; j++) {
let v = va1[j];
va2[j] = [cxz * v[0] - sxz * v[2],
v[1],
sxz * v[0] + cxz * v[2]];
}
n2x = cxz * nx - sxz * nz;
n2y = ny;
n2z = sxz * nx + cxz * nz;
}
let n3x;
let n3y;
let n3z;
let va3 = [];
let r2 = hypot2 (n2y, n2z);
if (r2 < eps) {
n3x = n2x;
n3y = n2y;
n3z = n2z;
for (let j = 0; j < va2.length; j++) {
va3[j] = va2[j].concat ();
}
} else {
let cyz = n2z / r2;
let syz = n2y / r2;
for (let j = 0; j < va2.length; j++) {
let v2 = va2[j];
va3[j] = [v2[0],
cyz * v2[1] - syz * v2[2],
syz * v2[1] + cyz * v2[2]];
}
n3x = n2x;
n3y = cyz * n2y - syz * n2z;
n3z = syz * n2y + cyz * n2z;
}
if (pgArea (va3) < 0) {
wReverse (n);
}
na[i] = n;
}
ph.ph$normalArray = na;
}
if (!ph.ph$reciprocalMatrix) {
let va = ph.ph$vertexArray;
let xmin = Infinity;
let ymin = Infinity;
let zmin = Infinity;
let xmax = -Infinity;
let ymax = -Infinity;
let zmax = -Infinity;
for (let i = 0; i < va.length; i++) {
let v = va[i];
let x = v[0];
let y = v[1];
let z = v[2];
if (x < xmin) {
xmin = x;
} else if (xmax < x) {
xmax = x;
}