/// <summary> /// 更新节点 /// </summary> public void Update() { if (parent == null) { return; } if (CheckState(parent) == PFQuadNodeState.In) { if (parent.children == null) { return; } int index; index = point.x <= (parent.rect.x + parent.rect.x1) / 2 ? 0 : 1; index = point.y <= (parent.rect.y + parent.rect.y1) / 2 ? index : index + 2; if (CheckState(parent.children[index]) != PFQuadNodeState.In) { return; } } PFQuadTree tempParent = parent; parent.RemoveQuadNode(this); tempParent.root.AddQuadNode(this); tempParent.Update(); }
void InitRuntime(PFQuadTree root, PFQuadTree parent, PFRect rect, int depath) { this.root = root == null ? this : root; this.parent = parent; this.rect = rect; this.depath = depath; quadLinkedList.Clear(); }
public void ReleaseToCache() { parent = null; if (quadLinkedList.Count > 0) { Debug.Fail("清理树节点异常:不应该存在PFIQuadNode"); } ResetRuntime(); }
public PFQuadTree(PFQuadTree root, PFQuadTree parent, PFRect rect, int depath) { this.rect = rect; this.root = root == null ? this : root; this.parent = parent; children = null; this.depath = depath; quadLinkedList = new LinkedList <PFQuadCircle>(); }
/// <summary> /// 回收子节点 /// </summary> /// <param name="parentQuadLinkedList"></param> void RecycleQuadNodesFromChildren(PFQuadTree quadTree, LinkedList <PFQuadCircle> parentQuadLinkedList) { if (children == null) { foreach (var quadNode in quadLinkedList) { parentQuadLinkedList.AddLast(quadNode); quadNode.parent = quadTree; quadNode.parentLinkNode = parentQuadLinkedList.Last; } quadLinkedList.Clear(); return; } foreach (var quadTress in children) { quadTress.RecycleQuadNodesFromChildren(quadTree, parentQuadLinkedList); } }
public static void __FindNearQuadNodes(PFQuadTree quadTree, PFIQuadNode quadNode, List <PFQuadCircle> tempList) { if (quadTree.quadLinkedList.Count > 0) { foreach (var tempQuadNode in quadTree.quadLinkedList) { tempList.Add(tempQuadNode); } } if (quadNode.parent == quadTree) { return; } if (quadTree.children != null) { int index; index = quadNode.point.x <= (quadTree.rect.x + quadTree.rect.x1) / 2 ? 0 : 1; index = quadNode.point.y <= (quadTree.rect.y + quadTree.rect.y1) / 2 ? index : index + 2; __FindNearQuadNodes(quadTree.children[index], quadNode, tempList); } }
/// <summary> ///判断节点与区域的关系 /// </summary> /// <param name="quadTree"></param> /// <returns></returns> public override PFQuadNodeState CheckState(PFQuadTree quadTree) { if ((point.x - radius >= quadTree.rect.x) && (point.x + radius <= quadTree.rect.x1) && (point.y - radius >= quadTree.rect.y) && (point.y + radius <= quadTree.rect.y1) ) { return(PFQuadNodeState.In); } else { if (PFMathIntersection.RectCircleIntersect(quadTree.rect, point, radius)) { return(PFQuadNodeState.Intersect); } else { return(PFQuadNodeState.Out); } } }
public abstract PFQuadNodeState CheckState(PFQuadTree quadTree);
/// <summary> /// 添加节点 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="quadNode">节点</param> public PFQuadNodeState AddQuadNode(PFQuadCircle quadNode) { PFQuadNodeState state = quadNode.CheckState(this); int index = 0; switch (state) { //在自己范围内,如果在子节点内,则由子节点持有。如果与子节点相交或者不存在子节点,则自己持有 case PFQuadNodeState.In: if (children != null) { index = quadNode.point.x <= (rect.x + rect.x1) / 2 ? 0 : 1; index = quadNode.point.y <= (rect.y + rect.y1) / 2 ? index : index + 2; switch (children[index].AddQuadNode(quadNode)) { case (PFQuadNodeState.In): return(PFQuadNodeState.In); case (PFQuadNodeState.Intersect): break; case (PFQuadNodeState.Out): Debug.Fail("AddQuadNode 异常:子节点状态OUT"); return(PFQuadNodeState.Out); } } quadLinkedList.AddLast(quadNode); quadNode.parentLinkNode = quadLinkedList.Last; quadNode.parent = this; break; //相交则不保存,由父节点继续持有 case PFQuadNodeState.Intersect: if (parent == null) { UnityEngine.Debug.LogError("AddQuadNode 异常:节点不在根数节点内"); } break; case PFQuadNodeState.Out: UnityEngine.Debug.LogError("AddQuadNode 异常:状态OUT"); break; } //如果数量超过容纳范围,则将当前格子分裂4块 if ((children == null) && (quadLinkedList.Count > PATH_FINDER_CONTAIN_NUMBER)) { children = new PFQuadTree[4]; for (int i = 0; i < 4; i++) { int x = rect.x + (rect.x1 - rect.x) / 2 * (i % 2); int y = rect.y + (rect.y1 - rect.y) / 2 * (i / 2); int x1 = x + (rect.x1 - rect.x) / 2; int y1 = y + (rect.y1 - rect.y) / 2; children[i] = MctCacheManager.GetInstantiateFromCache <PFQuadTree>(); if (children[i] != null) { children[i].InitRuntime(root, this, new PFRect(x, y, x1, y1), depath + 1); } else { children[i] = new PFQuadTree(root, this, new PFRect(x, y, x1, y1), depath + 1); } } //将父节点的节点转到子节点 LinkedListNode <PFQuadCircle> node; LinkedListNode <PFQuadCircle> nodeNext; node = quadLinkedList.First; while (node != null) { nodeNext = node.Next; PFQuadCircle tempQuadNode = node.Value; index = tempQuadNode.point.x <= (rect.x + rect.x1) / 2 ? 0 : 1; index = tempQuadNode.point.y <= (rect.y + rect.y1) / 2 ? index : index + 2; switch (children[index].AddQuadNode(tempQuadNode)) { case (PFQuadNodeState.In): quadLinkedList.Remove(node); break; case (PFQuadNodeState.Intersect): break; case (PFQuadNodeState.Out): Debug.Fail("AddQuadNode 异常:分配子节点状态OUT"); break; } node = nodeNext; } } return(state); }
public void FindNearQuadNodes(PFQuadCircle quadNode, List <PFQuadCircle> tempList) { PFQuadTree quadTree = root; __FindNearQuadNodes(root, quadNode, tempList); }