public void SearchEntities(DAreaRect AreaRect, double x, double y, double Radius, ref List <TValue> Objects, bool isPrecise = true) { if (QuadTree <TValue> .Intersect(m_Bounds, AreaRect)) { if (m_NorthWest != null) { m_NorthWest.SearchEntities(AreaRect, x, y, Radius, ref Objects, isPrecise: isPrecise); m_NorthEast.SearchEntities(AreaRect, x, y, Radius, ref Objects, isPrecise: isPrecise); m_SouthWest.SearchEntities(AreaRect, x, y, Radius, ref Objects, isPrecise: isPrecise); m_SouthEast.SearchEntities(AreaRect, x, y, Radius, ref Objects, isPrecise: isPrecise); } else { if (QuadTree <TValue> .InRect(m_Bounds, AreaRect)) { lock (AtomPlatformEntities) { if (AtomPlatformEntities.Count > 0) { Objects.AddRange(AtomPlatformEntities.Values); } // for (int i = 0; i < AtomPlatformEntities.Count; i++) // foreach (TValue atom in AtomPlatformEntities.Values) //foreach (string key in AtomPlatformEntities.Keys) //{ // TValue atom = AtomPlatformEntities[key]; // // TValue atom = AtomPlatformEntities.Values.ElementAt(i); // // TValue atom = AtomPlatformEntities.Values[i]; // Objects.Add(atom); //} } } else { if (isPrecise == true && Radius != 0 && (x != 0 || y != 0)) { lock (AtomPlatformEntities) { // for (int i = 0; i < AtomPlatformEntities.Count; i++) // foreach (TValue atom in AtomPlatformEntities.Values) foreach (string key in AtomPlatformEntities.Keys) { TValue atom = AtomPlatformEntities[key]; // TValue atom = AtomPlatformEntities.Values.ElementAt(i); // TValue atom = AtomPlatformEntities.Values[i]; // if (atom.Platform.PlatformCategoryId == enumPlatformId.SOLDIER) continue; double dist = TerrainService.MathEngine.CalcDistance(x, y, atom.x, atom.y); if (dist <= Radius) { Objects.Add(atom); } } } } else { lock (AtomPlatformEntities) { // for (int i = 0; i < AtomPlatformEntities.Count; i++) // foreach (TValue atom in AtomPlatformEntities.Values) foreach (string key in AtomPlatformEntities.Keys) { TValue atom = AtomPlatformEntities[key]; // TValue atom = AtomPlatformEntities.Values.ElementAt(i); // TValue atom = AtomPlatformEntities.Values[i]; if (QuadTree <TValue> .InRect(atom.x, atom.y, AreaRect)) { Objects.Add(atom); } } } } } } } }
public QuadTree(DAreaRect bounds, int level, QuadTree <TValue> parent, double x, double y) { if (m_BaseQuad == null) { m_BaseQuad = this; } m_Bounds = bounds; m_nLevel = level; // m_Parent = parent; //if (bounds.minX == bounds.maxX) //{ //} // m_sName = "L" + level + ":X=" + bounds.minX + "Y=" + bounds.maxY; bool isFound = false; if (Contains(x, y)) { isFound = true; } if (isFound == false) { return; } double distance = TerrainService.MathEngine.CalcDistance(m_Bounds.minX, m_Bounds.minY, m_Bounds.maxX, m_Bounds.maxY); if (level > 29) { return; } if (distance > 2000) { double dx = bounds.maxX - bounds.minX; double dy = bounds.maxY - bounds.minY; double nHalfHeight = dy / 2; double nHalfWidth = dx / 2; DAreaRect DRectNorthWest = new DAreaRect(bounds.minX, bounds.minY + nHalfHeight, bounds.minX + nHalfWidth, bounds.maxY); m_NorthWest = new QuadTree <TValue>(DRectNorthWest, level + 1, this, x, y); DAreaRect DRectNorthEast = new DAreaRect(bounds.minX + nHalfWidth, bounds.minY + nHalfHeight, bounds.maxX, bounds.maxY); m_NorthEast = new QuadTree <TValue>(DRectNorthEast, level + 1, this, x, y); DAreaRect DRectSouthWest = new DAreaRect(bounds.minX, bounds.minY, bounds.minX + nHalfWidth, bounds.minY + nHalfHeight); m_SouthWest = new QuadTree <TValue>(DRectSouthWest, level + 1, this, x, y); DAreaRect DRectSouthEast = new DAreaRect(bounds.minX + nHalfWidth, bounds.minY, bounds.maxX, bounds.minY + nHalfHeight); if (DRectSouthEast.minX == DRectSouthEast.maxX) { } m_SouthEast = new QuadTree <TValue>(DRectSouthEast, level + 1, this, x, y); } }
public void AddObject(double x, double y, string objName, TValue obj) { // lock (AtomPlatformEntities) // this) { try { if (obj == null) { return; } if (obj.bVisibleToClient == false) { return; } if (Contains(x, y)) { // int nIndex = 0; //nIndex = AtomPlatformEntities.IndexOfKey(objName); if (m_NorthWest != null) { m_NorthWest.AddObject(x, y, objName, obj); m_NorthEast.AddObject(x, y, objName, obj); m_SouthWest.AddObject(x, y, objName, obj); m_SouthEast.AddObject(x, y, objName, obj); return; } lock (AtomPlatformEntities) // this) { bool isExist = AtomPlatformEntities.ContainsKey(objName); //if (nIndex < 0) if (isExist == false) { AtomPlatformEntities.Add(objName, obj); obj.QuadTreeBounds = m_Bounds; if (AtomPlatformEntities.Count > MAX_PER_NODE && m_nLevel < MAX_NODE_LEVEL) { double dx = m_Bounds.maxX - m_Bounds.minX; double dy = m_Bounds.maxY - m_Bounds.minY; double nHalfHeight = dy / 2; double nHalfWidth = dx / 2; DAreaRect DRectNorthWest = new DAreaRect(m_Bounds.minX, m_Bounds.minY + nHalfHeight, m_Bounds.minX + nHalfWidth, m_Bounds.maxY); m_NorthWest = new QuadTree <TValue>(DRectNorthWest, m_nLevel + 1, this); DAreaRect DRectNorthEast = new DAreaRect(m_Bounds.minX + nHalfWidth, m_Bounds.minY + nHalfHeight, m_Bounds.maxX, m_Bounds.maxY); m_NorthEast = new QuadTree <TValue>(DRectNorthEast, m_nLevel + 1, this); DAreaRect DRectSouthWest = new DAreaRect(m_Bounds.minX, m_Bounds.minY, m_Bounds.minX + nHalfWidth, m_Bounds.minY + nHalfHeight); m_SouthWest = new QuadTree <TValue>(DRectSouthWest, m_nLevel + 1, this); DAreaRect DRectSouthEast = new DAreaRect(m_Bounds.minX + nHalfWidth, m_Bounds.minY, m_Bounds.maxX, m_Bounds.minY + nHalfHeight); m_SouthEast = new QuadTree <TValue>(DRectSouthEast, m_nLevel + 1, this); foreach (TValue GroundEntity in AtomPlatformEntities.Values) { string PName = GroundEntity.Key; //GroundEntity.ParentName + "_" + GroundEntity.Number.ToString(); if (DRectNorthWest.Contains(GroundEntity.x, GroundEntity.y)) { lock (m_NorthWest.AtomPlatformEntities) { m_NorthWest.AtomPlatformEntities.Add(PName, GroundEntity); } obj.QuadTreeBounds = m_NorthWest.m_Bounds; } else if (DRectNorthEast.Contains(GroundEntity.x, GroundEntity.y)) { lock (m_NorthEast.AtomPlatformEntities) { m_NorthEast.AtomPlatformEntities.Add(PName, GroundEntity); } obj.QuadTreeBounds = m_NorthEast.m_Bounds; } else if (DRectSouthWest.Contains(GroundEntity.x, GroundEntity.y)) { lock (m_SouthWest.AtomPlatformEntities) { m_SouthWest.AtomPlatformEntities.Add(PName, GroundEntity); } obj.QuadTreeBounds = m_SouthWest.m_Bounds; } else if (DRectSouthEast.Contains(GroundEntity.x, GroundEntity.y)) { lock (m_SouthEast.AtomPlatformEntities) { m_SouthEast.AtomPlatformEntities.Add(PName, GroundEntity); } obj.QuadTreeBounds = m_SouthEast.m_Bounds; } } AtomPlatformEntities.Clear(); } } else { } } } else { //RemoveObject(objName, obj); //if (m_Parent != null) //{ // m_Parent.AddObject(x, y, objName, obj); //} } } catch (Exception ex) { // Log.WriteErrorToLog(ex, ""); } } }