2015-02-01 2 views
2

캔버스에 이진 트리를 그리려하고 있습니다. 양식에서 데이터가 전송됩니다. 데이터는 트리를 삽입하는 텍스트, y 축에서 x 축 위치의 위치입니다.캔버스에 이진 트리를 그릴 때 노드가 겹치다

   (0,0) 
       / \ 
      (-1,1)  (1,1) 
     / \ / \ 
     (-2,2) (0,2) (0,2) (2,2) 

:

나는 "x 축과 y 축 위치", 나는 이진 트리의 노드의 배열 말은, 나는 그래픽 예제를 명확 가능한 설명하려고합니다 말을

이것은 루트가 위치 (0,0)에 있고 왼쪽 자식이 위치 (-1,1) (깊이가 증가하지만 너비가 감소 함), 오른쪽 자식 (1,1) 등입니다. . 문제는 어떤 위치에서 다른 부모의 두 노드가 일치하고 그 중 하나가 다른 노드와 겹칠 것입니다.

서버 측에서 이진 트리를 가로 지르는 동안 쌍이 형성되기 때문에 (이 구성 요소는 두 번째 구성 요소에 1을 더하는 현재 노드의 하위 노드로 이동합니다. 그 아이가 왼쪽에 있다면 첫 번째 구성 요소에 1이 남아 있지만 그 아이가 오른쪽에 있으면 첫 번째 구성 요소에 1을 더한다).

내 캔버스 코드는 다음과 같습니다

   var TreeDrawer = (function(){ 
        var _depth = 20 
         , _breadth = 15 
         , _rootX = width/2 
         , _rootY = 50 
         ; 

        var _context = getContext("2d"); 

        _context.textAlign = "center"; 
        _context.fillStyle = "black"; 
        _context.font = "16px Verdana"; 


        var _getX = function (x) { 
         return _rootX + (x * 80); 
        } 

        var _getY = function(y) { 
         return _rootY + (y * 50); 
        } 

        var _drawText = function(partialText, x, y) { 

         console.log(x, y); 
         _context.fillText(partialText, x, y); 
        } 

        return { 
         drawRoot: function (value) { 
          _drawText(value, _rootX, _rootY); 
         }, 

         drawNode: function(value, x, y) { 
          _drawText(value, _getX(x), _getY(y)); 
         } 
        } 
       }); 

       var _tree = new TreeDrawer(); 
       _tree.drawRoot("Raíz"); 
       _tree.drawNode("Nodo", -1, 1); 
       _tree.drawNode("Nodo", 1, 1); 

       _tree.drawNode("Nodo", -2, 2); 
       _tree.drawNode("Nodo", 0, 2); 

       _tree.drawNode("Nodo", 2, 2); 
       _tree.drawNode("Nodo", 0, 2); 

그래서, 질문은 : 나는이 문제를 해결하기 위해 무엇을 할 수 있는지, 즉 중복없이 나무를 플롯.

PS : 내 프로젝트는 C로 작성되어 있기 때문에 내가 (Qt를 사용) ++ 라이브러리를하지 않기 때문에 라이브러리가 작동하지 않습니다

  • .
  • 이 예제에서는 노드를 명시 적으로 삽입하고 있습니다. 즉, _tree.drawNode ("Node", 0,2) 메서드를 두 번 호출하고 있으므로 노드가 겹치는 것입니다. 내 말은,이 상황에서 나무를 조정하는 내부 방법을 만들고 싶습니다 (어떤 것이 서버 측에서 오는 입력인지는 모르겠습니다).
  • 도움이된다면 몇 장의 잎이 나무를 가질 수 있는지 선험적으로 결정할 수 있습니다.
+1

상대 위치 (0, 0)의 왼쪽 자식이 (-1, 1) 대신에 행을 사용하여 인덱싱 된 위치를 사용할 수 있습니다. 예를 들어, 노드가 두 개인 행은 (0, 1) --- (1,1)이고 다음 노드는 (0, 2) --- (1, 2) ---입니다. (2, 2) --- (3, 2)이다. 이렇게하면 고유 노드 위치가 보장됩니다. – Azeirah

답변

1

조금 해킹되었지만 작동하는 것 같습니다. 노드는 stepX 크기와 행 당 노드 수에 따라 부분적으로 겹칠 수 있습니다.

설명 된 것처럼 상대 위치 지정을 사용하는 대신. 다음과 같이

  (0,0) 
      / \ 
     (-1,1)  (1,1) 
    / \ / \ 
    (-2,2) (0,2) (0,2) (2,2) 

나는, 절대 위치를 사용하고 있습니다 :

  (0,0) 
      / \ 
     (0,1)  (1,1) 
    / \ / \ 
    (0,2) (1,2) (2,2) (3,2) 

var TreeDrawer = (function(){ 
    var _depth = 15 
    , _breadth = 16 
    , _rootX = canvas.width/2 
    , _rootY = 59 
    ; 

    _context.textAlign = "center"; 
    _context.fillStyle = "black"; 
    _context.font = "16px Verdana"; 

    var _drawText = function(partialText, x, y) { 
     _context.fillText(partialText, x, y); 
    } 

    return { 
     drawRoot: function (value) { 
      _drawText(value, _rootX, _rootY); 
     }, 
     drawNode: function(value, row, position) { 
      var stepX = 56; 
      var stepY = 32; 
      // subtract half from x for symmetry 
      var half = (Math.pow(2, row) * stepX)/2; 
      var x = _rootX + (stepX/2) + (stepX * position) - half; 
      var y = _rootY + (stepY * row); 
      _drawText(value, x, y); 
     } 
    } 
}); 

var _tree = TreeDrawer(); 
var root = "Raiz"; 
var rows = [ 
    new Array(2).fill("nodo"), 
    new Array(4).fill("nodo"), 
    new Array(8).fill("nodo"), 
    new Array(16).fill("nodo")]; 

_tree.drawRoot(root); 
rows.forEach(function (row, rowIndex) { 
    row.forEach(function (node, index) { 
     // the root is row zero, so I add 1 for the normal nodes. 
     _tree.drawNode(node, rowIndex + 1, index); 
    }); 
}); 

Overlap with longer text example

편집 : 난 그냥 지금이 분할 효과를 달성하지 않는 것을 볼, 그것은 hardto 것 많은 행을 나누기를 계속할 때마다 텍스트 공간은 매번 절반으로 줄입니다.

관련 문제