CANVASで網目模様を描く方法を教えて下さい.その3
動かしてみたら、球体と回転にミスがあることが判明。
OKWave にも投稿したし、これで安眠できる。めでたし、めでたし。
<!DOCTYPE html> <meta charset="UTF-8"> <title>3D</title> <style> canvas { background : #fff; } </style> <body> <canvas width="1024" height="512"></canvas> <script> function ball (r, n, n1) { var rst = [], a = [], b = [], c = []; var pi = Math.PI, sin = Math.sin, cos = Math.cos; var k = 2 * pi / n1, k2 = pi / n; var i, i_, j, s, r2, yb; var r2 = sin (k2) * r, h2 = cos (k2) * r, yr = r2, yt = h2; for (i = 0; i <= n1; i++) { s = k * i; a[i] = sin (s); b[i] = cos (s); } for (i = 0; i < n1; i++) { rst[i] = [ [0, r, 0], [a[i] * r2, h2, b[i] * r2], [a[i_= i +1 ] * r2, h2, b[i_] * r2] ]; c[i] = [ [a[i_ = i + 1] * r2, -h2, b[i_] * r2], [a[i] * r2, -h2, b[i] * r2], [0, -r, 0] ]; } for (i = 2; i < n; i++) { s = k2 * i; yr2 = sin (s) * r; yb = cos (s) * r; for (j = 0; j < n1; j++) { rst.push ([ [a[j] * yr, yt, b[j] * yr], [a[j] * yr2, yb, b[j] * yr2], [a[j+1] * yr2, yb, b[j+1] * yr2], [a[j+1] *yr, yt, b[j+1] * yr] ]); } yt = yb; yr = yr2; } return rst.concat (c); } function rotation3D (m, x, y, z) { var deg = Math.PI / 180, sin = Math.sin, cos = Math.cos; var xc = cos (x * deg), xs = sin (x * deg); var yc = cos (y * deg), ys = sin (y * deg); var zc = cos (z * deg), zs = sin (z * deg); var x0 = xc * yc, y0 = xc * ys * zs - xs * zc, z0 = xc * ys * zc + xs * zs; var x1 = xs * yc, y1 = xs * ys * zs + xc * zc, z1 = xs * ys * zc - xc * zs; var x2 = -ys, y2 = yc * zs, z2 = yc * zc; var i, j, a, b, c, d, e, s; var rst = []; for (i = 0; a = m[i]; rst[i++] = s) for (j = 0, s = []; b = a[j]; j++) s[j] = [ x0 * (c = b[0]) + y0 * (d = b[1]) + z0 * (e = b[2]), x1 * c + y1 * d + z1 * e, x2 * c + y2 * d + z2 * e ]; return rst; } //3Dの物体を2Dの座標へと変換する function cov3to2 (m, zz, sc) { var rst = [], a, b, c, s, i, j, t; for (i = 0; a = m[i]; rst[i++] = c) for (c = [], j = 0; b = a[j]; j++) c[j] = [b[0] / (t = (zz + b[2]) / sc), b[1] / t]; return rst; } function canvas_draw_create (c, o) { var ctx = c.getContext ('2d'); var x = c.width / 2 + o[0]; var y = c.height / 2 + o[1]; ctx.lineWidth = 1; ctx.strokeStyle = 'rgb(0,0,0)'; return { draw: function (a) {//面を描く ctx.beginPath (); ctx.moveTo (x + a[0][0], y - a[0][1]); for (i = 1; b = a[i++]; ) ctx.lineTo (x + b[0], y - b[1]); ctx.lineTo (x + a[0][0], y - a[0][1]); ctx.stroke(); }, cls: function () { ctx.fillRect (0,0, c.width, c.height); ctx.fillStyle = 'RGB(255,255,255)'; } }; } function draw (a, dw) { dw.cls (); for (var i = 0, b; b = a[i++]; ) {//面の3点だけでベクトルの外積の向きで判断 if (0 >= ((b[2][0] - b[1][0]) * (b[0][1] - b[1][1]) - (b[2][1] - b[1][1]) * (b[0][0] - b[1][0])) ) dw.draw (b); } } var hoge = (function _ (f, a, b, c) { var z = ball (15, 18, 36); var v = canvas_draw_create (document.querySelector ('canvas'), [0,0]); return function () { z = f (z, a, b, c); draw (cov3to2 (z, 50, 600), v); }; }) (rotation3D, .7, 1, .5); setInterval (hoge, 20); </script>