/**
  * Applies the middle out build procedure to the leaves of the tree. The leaf nodes should be the
  * ones that were created by createAnchorsHierarchy(). The process continues recursively for the
  * leaves created for each leaf of the given tree until for some leaf node <= m_MaxInstancesInLeaf
  * instances remain in the leaf.
  *
  * @param node The root of the tree.
  * @throws Exception If there is some problem in building the tree leaves.
  */
 protected void buildLeavesMiddleOut(BallNode node) throws Exception {
   if (node.m_Left != null && node.m_Right != null) { // if an internal node
     buildLeavesMiddleOut(node.m_Left);
     buildLeavesMiddleOut(node.m_Right);
   } else if (node.m_Left != null || node.m_Right != null) {
     throw new Exception("Invalid leaf assignment. Please check code");
   } else { // if node is a leaf
     BallNode n2 = buildTreeMiddleOut(node.m_Start, node.m_End);
     if (n2.m_Left != null && n2.m_Right != null) {
       node.m_Left = n2.m_Left;
       node.m_Right = n2.m_Right;
       buildLeavesMiddleOut(node);
       // the stopping condition in buildTreeMiddleOut will stop the recursion,
       // where it won't split a node at all, and we won't recurse here.
     } else if (n2.m_Left != null || n2.m_Right != null)
       throw new Exception("Invalid leaf assignment. Please check code");
   }
 }
  /**
   * Makes BallTreeNodes out of TempNodes.
   *
   * @param node The root TempNode
   * @param startidx The start of the portion of master index array the TempNodes are made from.
   * @param endidx The end of the portion of master index array the TempNodes are made from.
   * @param depth The depth in the tree where this root TempNode is made (needed when leaves of a
   *     tree deeper down are built middle out).
   * @return The root BallTreeNode.
   */
  protected BallNode makeBallTreeNodes(TempNode node, int startidx, int endidx, int depth) {
    BallNode ball = null;

    if (node.left != null && node.right != null) { // make an internal node
      ball = new BallNode(startidx, endidx, m_NumNodes, node.anchor, node.radius);
      m_NumNodes += 1;
      ball.m_Left =
          makeBallTreeNodes(
              node.left, startidx, startidx + node.left.points.length() - 1, depth + 1);
      ball.m_Right =
          makeBallTreeNodes(node.right, startidx + node.left.points.length(), endidx, depth + 1);
      m_MaxDepth++;
    } else { // make a leaf node
      ball = new BallNode(startidx, endidx, m_NumNodes, node.anchor, node.radius);
      m_NumNodes += 1;
      m_NumLeaves += 1;
    }
    return ball;
  }