/// <summary> /// Construct new Quadrant with a given bounds all nodes stored inside this quadrant /// will fit inside this bounds. /// </summary> /// <param name="parent">The parent quadrant (if any)</param> /// <param name="bounds">The bounds of this quadrant</param> public Quadrant(Quadrant <T> parent, Rect bounds) { Parent = parent; Debug.Assert(bounds.Width != 0 && bounds.Height != 0); if (bounds.Width == 0 || bounds.Height == 0) { // todo: localize throw new ArgumentException("Bounds of quadrant cannot be zero width or height"); } Bounds = bounds; }
/// <summary> /// Insert the given node /// </summary> /// <param name="node">The node </param> /// <param name="bounds">The bounds of that node</param> /// <returns></returns> internal Quadrant <T> Insert(T node, Rect bounds) { Debug.Assert(bounds.Width != 0 && bounds.Height != 0); if (bounds.Width == 0 || bounds.Height == 0) { // todo: localize throw new ArgumentException("Bounds of quadrant cannot be zero width or height"); } Double w = Bounds.Width / 2; if (w == 0) { w = 1; } Double h = Bounds.Height / 2; if (h == 0) { h = 1; } // assumption that the Rect struct is almost as fast as doing the operations // manually since Rect is a value type. Rect topLeft = new Rect(Bounds.Left, Bounds.Top, w, h); Rect topRight = new Rect(Bounds.Left + w, Bounds.Top, w, h); Rect bottomLeft = new Rect(Bounds.Left, Bounds.Top + h, w, h); Rect bottomRight = new Rect(Bounds.Left + w, Bounds.Top + h, w, h); Quadrant <T> child = null; // See if any child quadrants completely contain this node. if (topLeft.Contains(bounds)) { if (TopLeft == null) { TopLeft = new Quadrant <T>(this, topLeft); } child = TopLeft; } else if (topRight.Contains(bounds)) { if (TopRight == null) { TopRight = new Quadrant <T>(this, topRight); } child = TopRight; } else if (bottomLeft.Contains(bounds)) { if (BottomLeft == null) { BottomLeft = new Quadrant <T>(this, bottomLeft); } child = BottomLeft; } else if (bottomRight.Contains(bounds)) { if (BottomRight == null) { BottomRight = new Quadrant <T>(this, bottomRight); } child = BottomRight; } if (child != null) { return(child.Insert(node, bounds)); } else { QuadNode <T> n = new QuadNode <T>(node, bounds); if (Nodes == null) { n.Next = n; } else { // link up in circular link list. QuadNode <T> x = Nodes; n.Next = x.Next; x.Next = n; } Nodes = n; return(this); } }