void queryEleRecursion(QuadTreeNode node, QuadTreeElement ele, List<QuadTreeElement> ret) { if(node.m_isLeaf) { ret.AddRange(node.m_elementList); return; } float mid_vertical = (node.m_region.yMax + node.m_region.yMin) / 2; float mid_horizontal = (node.m_region.left + node.m_region.right) / 2; if (ele.lat > mid_vertical) { if (ele.lng > mid_horizontal) { queryEleRecursion(node.m_ru, ele, ret); } else { queryEleRecursion(node.m_lu, ele, ret); } } else { if (ele.lng > mid_horizontal) { queryEleRecursion(node.m_rb, ele, ret); } else { queryEleRecursion(node.m_lb, ele, ret); } } }
/** * 插入元素 * 1.判断是否已分裂,已分裂的选择适合的子结点,插入; * 2.未分裂的查看是否过载,过载的分裂结点,重新插入; * 3.未过载的直接添加 * * @param node * @param ele * todo 使用元素原地址,避免重新分配内存造成的效率浪费 */ void InsertElementRecursion(QuadTreeNode node, QuadTreeElement ele) { if (node.m_isLeaf) { if (node.m_elementList.Count > MAX_ELE_NUM) { splitNode(node); InsertElementRecursion(node, ele); } else { // todo 点排重(不排重的话如果相同的点数目大于 MAX_ELE_NUM, 会造成无限循环分裂) // struct ElePoint *ele_ptr = (struct ElePoint *) malloc(sizeof(struct ElePoint)); // ele_ptr->lat = ele.lat; // ele_ptr->lng = ele.lng; // strcpy(ele_ptr->desc, ele.desc); // node->ele_list[node->ele_num] = ele_ptr; // node->ele_num++; foreach (var iter in node.m_elementList) { if(iter.lat == ele.lat && iter.lng == ele.lng) { Debug.LogError("重复点,有可能造成堆栈溢出"); } } node.m_elementList.Add(ele); } return; } float mid_vertical = (node.m_region.yMax + node.m_region.yMin) / 2; float mid_horizontal = (node.m_region.left + node.m_region.right) / 2; if (ele.lat > mid_vertical) { if (ele.lng > mid_horizontal) { InsertElementRecursion(node.m_ru, ele); } else { InsertElementRecursion(node.m_lu, ele); } } else { if (ele.lng > mid_horizontal) { InsertElementRecursion(node.m_rb, ele); } else { InsertElementRecursion(node.m_lb, ele); } } }
public static void Test() { QuadTree quadTree = new QuadTree(); quadTree.Init(-90, 90, -180, 180); Dictionary<Vector2, int> posDic = new Dictionary<Vector2, int>(); System.Random random = new System.Random(0); for (int i = 0; i < 100000; i++) { Vector2 pos = new Vector2(); pos.x = (float)(random.Next() % 360 - 180 + (float)(random.Next() % 1000) / 1000); pos.y = (float)(random.Next() % 180 - 90 + (float)(random.Next() % 1000) / 1000); if (posDic.ContainsKey(pos)) { posDic[pos] += 1; } else { QuadTreeElement element = new QuadTreeElement(); element.lng = pos.x; element.lat = pos.y; //Debug.Log("尝试InsertElement " + i.ToString() + " " + element.lng + " " + element.lat); quadTree.InsertElement(element); posDic.Add(pos, 1); } } QuadTreeElement test = new QuadTreeElement(); test.lng = -24f; test.lat = -45.4f; List<QuadTreeElement> retList = quadTree.queryEle(test); Debug.Log("附近有 " + retList.Count + " 个点"); foreach(var iter in retList) { Debug.Log(iter.lng + " " + iter.lat); } }
void InsertElement(QuadTreeElement element) { InsertElementRecursion(m_root, element); }
void deleteEle(QuadTreeElement ele) { /** * 1.遍历元素列表,删除对应元素 * 2.检查兄弟象限元素总数,不超过最大量时组合兄弟象限 */ }
List<QuadTreeElement> queryEle(QuadTreeElement element) { List<QuadTreeElement> ret = new List<QuadTreeElement>(); queryEleRecursion(m_root, element, ret); return ret; }