public QuadNode GetSubNode(QuadNode node, QuadData data) { QuadNode sub = null; for (int i = 0; i < MAX_QUADRANT; ++i) { if (false == isRegionCross(node.Sub[i].mbr, data.mbr)) { continue; } sub = node.Sub[i]; break; } return(sub); }
// 初始化四叉树范围 public void Init(MBR mbr) { if (null != _root) { return; } _root = new QuadNode(); _root.mbr = mbr; _root.Quadrant = EQuadrant.ROOT; _root.Level = 0; // debug LevelCnt = new Dictionary <int, int>(); TotalCnt = 0; CorssCircleTestCnt = 0; // debug }
// 添加 public bool Add(QuadData data) { // 节点node数量判定 // 寻找符合节点插入 bool success = false; QuadNode tmp = _root; do { bool addToParentNode = false; // 当前节点child个数小于最大child个数,并且没有分裂过 if (tmp.Cnt + 1 <= MAX_DATA_CNT && null == tmp.Sub) { addToParentNode = true; } // 节点个数<MAX_DATA_CNT && 为分裂的 // 多象限内直接插入本节点 if (addToParentNode || isInMultipleSub(tmp, data)) { // 加入本节点 var n1 = tmp.Child; tmp.Child = data; data.Next = n1; tmp.Cnt++; TotalCnt++; addLevelCnt(tmp.Level); success = true; // 跳出 break; } else { split(tmp); // 获取插入的指定象限, tmp = GetSubNode(tmp, data); } }while (true); return(success); }
private void ForeachNode(QuadNode node, List <QuadData> lst) { if (null == node) { return; } if (null == lst) { return; } Queue <QuadNode> nodes = new Queue <QuadNode>(); nodes.Enqueue(node); var tmp = node; do { tmp = nodes.Dequeue(); var n1 = tmp.Child; while (null != n1) { lst.Add(n1); n1 = n1.Next; } if (null != tmp.Sub) { for (int i = 0; i < MAX_QUADRANT; ++i) { nodes.Enqueue(tmp.Sub[i]); } } } while (nodes.Count > 0); }
// 象限分裂 // 分裂后,node节点的数据,尝试插入到子象限内 private void split(QuadNode node) { // 已经分裂过了 if (null != node.Sub) { return; } // 分裂为四个象限 /* | | | UL | UR | --------------------- | | LL | LR | | */ // mbr = (x,z,w,l) var mbr = node.mbr; float hw = (mbr.right - mbr.left) * 0.5f; float hl = (mbr.top - mbr.bottom) * 0.5f; var mbr_ur = new MBR(mbr.right - hw, mbr.right, mbr.top, mbr.top - hl); var mbr_ul = new MBR(mbr.left, mbr.left + hw, mbr.top, mbr.top - hl); var mbr_ll = new MBR(mbr.left, mbr.left + hw, mbr.bottom + hl, mbr.bottom); var mbr_lr = new MBR(mbr.right - hw, mbr.right, mbr.bottom + hl, mbr.bottom); node.Sub = new QuadNode[4]; node.Sub[0] = new QuadNode() { Level = node.Level + 1, Quadrant = EQuadrant.UR, Cnt = 0, mbr = mbr_ur, Child = null, Sub = null, }; node.Sub[1] = new QuadNode() { Level = node.Level + 1, Quadrant = EQuadrant.UL, Cnt = 0, mbr = mbr_ul, Child = null, Sub = null, }; node.Sub[2] = new QuadNode() { Level = node.Level + 1, Quadrant = EQuadrant.LL, Cnt = 0, mbr = mbr_ll, Child = null, Sub = null, }; node.Sub[3] = new QuadNode() { Level = node.Level + 1, Quadrant = EQuadrant.LR, Cnt = 0, mbr = mbr_lr, Child = null, Sub = null, }; if (node.Level + 1 > Current_Max_Level) { Current_Max_Level = node.Level + 1; } // 尝试插入当前节点的child TotalCnt -= node.Cnt; LevelCnt[node.Level] -= node.Cnt; node.Cnt = 0; if (node.Child != null) { var tmp = node.Child; var tmp1 = tmp.Next; node.Child = null; while (null != tmp) { Add(tmp); tmp = tmp1; if (null != tmp) { tmp1 = tmp.Next; tmp.Next = null; } } } }