• ベストアンサー

canvasで完全二分木を描画したいのですが

JavaScriptのcanvasを使って、画像の様な完全二分木を描画したいです。 木の深さをrとし、rは任意で変更できるようにしたいと考えています。 canvasのサイズは1000x1000程度で、r=4くらいまで対応できるものであれば幸いです。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

//その2: ほぼここからは、やっつけで書いたので綺麗ではありません。                    var tree = NTree.create (5); //ここを弄る! NTree.create (4,3) とかでもおもしろい?        tree.setAutoNumber (tree.seed, 1);                           (function (tree) {          var canvas = document.querySelector ('canvas');          var ctx = canvas.getContext('2d');          var r = 10;          var mx = canvas.width;          var my = canvas.height;          var stepY = tree.getMaxDepth () + 1;         var nd = tree.getAllNodes ();         var i, j, cx, cy, d, row, n, s, c;        var gnd = [ ];              for (i = 0; n = nd[i]; i += 1) {      d = tree.getDepth (n);     if ('undefined' === typeof gnd[d])    gnd[d] = [ ];    gnd[d].push (n);   }   for (i = 0; row = gnd[i]; i += 1) { cy = my / stepY * i + r; for (j = 0; n = row[j]; j += 1) { cx = mx / (row.length) / 2 + (mx / row.length * j); n.x = cx; n.y = cy; } } ctx.textAlign = "center"; ctx.textBaseline ="middle";  ctx.font = Math.floor (r * 1.4) +"px 'Times New Roman'";      for (i = 0; n = nd[i]; i += 1) {    cx = n.x;     cy = n.y;      for (j = 0; c = n.child[j]; j += 1) {       ctx.beginPath ();        ctx.moveTo (cx, cy);        ctx.lineTo (c.x, c.y)         ctx.stroke ();         }          ctx.beginPath ();          ctx.strokeStyle = 'rgb(0,0,0)';          ctx.fillStyle = 'rgb(255, 255, 255)';          ctx.arc (cx, cy, r, 0, Math.PI*2);          ctx.fill ();          ctx.fillStyle = 'rgb(0, 0,0)';          ctx.fillText(n.number + '', cx, cy + r/ 8);         ctx.stroke ();         }                }) (tree);            </script>     

すると、全ての回答が全文表示されます。

その他の回答 (1)

回答No.1

あけおめことよろ。 無駄に長いので分割しました。 全角空白は半角に置換してください。 <!DOCTYPE html> <meta charset="utf-8"> <title>n木分</title> </head> <body>  <canvas width="1000" height="300"></canvas>      <script>               (function () {              function Node (parent) {        this.parent = parent;         this.child = new Array ();         }                   //_________                              function NTree (seed) {          this.seed = seed;          }                         function grow (n) {        var seed = this.seed;       var buf = find (seed, []);      var ary = [ ], i, c, j;         if (0 === buf.length)    buf = [seed];    for (i = 0; c = buf[i]; i += 1) for (j = 0; j < n; j += 1) c.child[j] = new Node (c); } function firstNode (n) { return n.child[0] ? n.child[0]: null; } function nextSibling (n) {  var p = n.parent, no;   var c = p.child;       if (p)     if (no = c.indexOf (n) + 1)      if (no < c.length)       return c[no];               return null;         }                            function getAllNodes (node) {          if (1 > arguments.length)          node = this.seed;                    var rst = [ ];          var n, b = node;                  B:        while (n = b)        if (! (rst.push (n), b = firstNode (n)))       while (! (b = nextSibling (n)))      if (node === (n = n.parent))     break B;        return rst;   }   function maxDepth (mx, n) { return Math.max (this.getDepth (n), mx); } function getMaxDepth (node) { if (1 > arguments.length) node = this.seed; return getAllNodes.call (this).reduce (maxDepth.bind (this), 0);  }         function getDepth (node) {     var cnt = 0;      var p = node;              while (p = p.parent)        cnt += 1;                 return cnt;          }                              function setNumber (nd, i) {          nd.number = this + i;          }                           function setAutoNumber (node, no) {        switch (arguments.length) {        case 0 :       node = this.seed;      case 1 :     no = 0;    }      var nd = getAllNodes.call (this, node);  var gd = [ ], d, i, n; for (i = 0; n = nd[i]; i += 1) { d = this.getDepth (n); if ('undefined' === typeof gd[d]) gd[d] = [ ]; gd[d].push (n); } Array.prototype.concat.apply ([], gd) .forEach (setNumber, no); }           function find (node, buf) {     var child = node.child;             for (var i = 0, c; c = child[i]; i += 1)        hasChildNodes (c)        ? find (c, buf)         : buf.push (c);                   return buf;          }                              function hasChildNodes (node) {          return !! node.child.length;          }                         function create (depth, n) {        if (2 > arguments.length)       n = 2;           var seed = new Node (null);    var tree = new NTree (seed);    var i;    for (i = 0; i < depth; i += 1) tree.grow (n); return tree; } NTree.prototype.grow = grow; NTree.prototype.getAllNodes = getAllNodes; NTree.prototype.getMaxDepth = getMaxDepth; NTree.prototype.getDepth = getDepth; NTree.prototype.setAutoNumber = setAutoNumber;     NTree.create = create;       this.NTree = NTree;     }) ();

すると、全ての回答が全文表示されます。

関連するQ&A