球面上にN個の点を均等に配置したい。その4
N個の数を数えてみたら、N個ではなかった。それを修正する。
黄金比を半分にし、点の間隔を2倍にした。
地球でいえば、南極点が出ないようにループの条件を変える。
将来的に速度を要求するので、それを優先して球体の点を生成するコードを書き直した。(結果から言えば、正確ではない。しかしここで妥協して次に進む)
これ以上の速度は期待できまい!
あんなに苦労したのに、コードに直すとたかだ数行ですむのね。
座標変換は、そもそもこれではダメだ。
追記
もしかして、これは3D花火に応用出来そうだ。
全方向へ均等に爆発させる。夏になるころに考えよう。
canvas を消すのではなく、alpha値を加え、薄く消していく。
これは、しだれ柳の花火に使えそう。
<!DOCTYPE html> <meta charset="UTF-8"> <title>test</title> <style> body, canvas { background : black; } </style> <body> <canvas width="1024" height="1024"></canvas> <script> function createSpherePoint (n /* 球体の点の数 */, r /*球体の半径*/) { if (arguments.length < 2 || n < 1) throw new Error; var A = Math.asin; var C = Math.cos; var S = Math.sin; var G = (Math.sqrt (5) + 1) / 4; var B = n + 0.5; var D = Math.PI * 2 * (G - 1); var F; // = フィナボッチ数 var R = [ ]; for (var a = 0, b = 1, c = n, d; --c; ) d = b, F = b += a, a = d; for (var a, b, c, d = -n, e = 0; d < n; d += 2) R[e++] = [ (b = C (a = A (d / B)) * r) * C (c = D * d), b * S (c) , S (a) * r ]; return R; } function draw (a, b) { var A = 0, B = 0; var ctx = a.getContext ('2d'); var x = 512; var y = 512; var w = +a.width; var h = +a.height; var DEG = Math.PI / 180; var z = 300; return function () { ctx.fillStyle = 'RGBA(0,0,0,.25)'; ctx.fillRect (0,0, w,h); for (var i = 0; i < b.length; i++) { var px = b[i][0]; var py = b[i][1]; var pz = b[i][2]; var deg0 = A * DEG; var deg1 = B * DEG; var sin = Math.sin (deg0); var cos = Math.cos (deg0); var sin2 = Math.sin (deg1); var cos2 = Math.cos (deg1); var tx = px * cos + pz * sin; var ty = py; var tz = px * sin - pz * cos; px = tx * cos2 + ty * sin2; py = tx * sin2 - ty * cos2; var zz = ( z + tz) / z; var sz = 5 * zz; ctx.fillStyle = '#c40'; ctx.fillRect (x + px * zz, y - py * zz, sz, sz); } A += 1.5; B += 0.1; }; } setInterval (draw ( document.querySelector ('canvas'), createSpherePoint (100, 200) ), 33); </script>