private static void FirstWalk(LeafNode currentNode, int currentLevel) { currentNode.LeftSibling = GetPrevNodeAtLevel( currentLevel ); SetPrevNodeAtLevel( currentLevel, currentNode ); currentNode.Modifier = 0; if( currentNode.IsLeaf() || (currentLevel == MaxLevelDepth) ) { if( currentNode.HasLeftSibling() ) { currentNode.PreliminaryLocation = currentNode.GetLeftSibling().PreliminaryLocation + HorizontalSiblingSeparationFine + CalcAverageNodeSize( currentNode.GetLeftSibling(), currentNode ); } else { currentNode.PreliminaryLocation = 0; } } else { var rightMostNode = currentNode.GetFirstChild(); var leftMostNode = rightMostNode; FirstWalk( leftMostNode, currentLevel + 1 ); while ( rightMostNode.HasRightSibling() ) { rightMostNode = rightMostNode.GetRightSibling(); FirstWalk( rightMostNode, currentLevel + 1 ); } var midpoint = (leftMostNode.PreliminaryLocation + rightMostNode.PreliminaryLocation) / 2; if( currentNode.HasLeftSibling() ) { currentNode.PreliminaryLocation = currentNode.GetLeftSibling().PreliminaryLocation + HorizontalSiblingSeparationFine + CalcAverageNodeSize( currentNode.GetLeftSibling(), currentNode ); currentNode.Modifier = currentNode.PreliminaryLocation - midpoint; Apportion( currentNode, currentLevel ); } else { currentNode.PreliminaryLocation = midpoint; } } }
private static void Apportion(LeafNode currentNode, int currentLevel) { var leftMostNode = currentNode.GetFirstChild(); var neighbor = leftMostNode.LeftNeighbor(); uint compareDepth = 1; var depthToStop = (uint) (MaxLevelDepth - currentLevel); while ( leftMostNode != null && neighbor != null && compareDepth <= depthToStop ) { float leftModsum = 0; float rightModsum = 0; var ancestorLeftMost = leftMostNode; var ancestorNeighbor = neighbor; for ( var i = 0; i < compareDepth; i++ ) { ancestorLeftMost = ancestorLeftMost.GetParent(); ancestorNeighbor = ancestorNeighbor.GetParent(); rightModsum += ancestorLeftMost.Modifier; leftModsum += ancestorNeighbor.Modifier; } var distance = neighbor.PreliminaryLocation + leftModsum + HorizontalSubtreeSeparationCoarse + CalcAverageNodeSize( leftMostNode, neighbor ) - (leftMostNode.PreliminaryLocation + rightModsum); if( distance > 0 ) { uint numLeftSiblings = 0; var tmp = currentNode; while ( tmp != null && tmp != ancestorNeighbor ) { numLeftSiblings++; tmp = tmp.GetLeftSibling(); } if( tmp == null ) return; var portion = distance / numLeftSiblings; for (tmp = currentNode; tmp != ancestorNeighbor; tmp = tmp.GetLeftSibling()) { tmp.PreliminaryLocation = tmp.PreliminaryLocation + distance; tmp.Modifier = tmp.Modifier + distance; distance -= portion; } } compareDepth++; leftMostNode = leftMostNode.IsLeaf() ? GetLeftMost( currentNode, 0, (int) compareDepth ) : leftMostNode.GetFirstChild(); neighbor = leftMostNode == null ? null : leftMostNode.LeftNeighbor(); } }