/// <summary> /// Remove the given node from this Quadrant. /// </summary> /// <param name="node">The node to remove</param> /// <returns>Returns true if the node was found and removed.</returns> public Boolean RemoveNode(T node) { Boolean rc = false; if (Nodes != null) { IMesQuadNode <T> p = Nodes; while (!p.Next.Node.Equals(node) && p.Next != Nodes) { p = p.Next; } if (p.Next.Node.Equals(node)) { rc = true; IMesQuadNode <T> n = p.Next; if (p == n) { // list goes to empty Nodes = null; } else { if (Nodes == n) { Nodes = p; } p.Next = n.Next; } } } return(rc); }
/// <summary> /// Walk the given linked list of QuadNodes and check them against the given bounds. /// Add all nodes that intersect the bounds in to the list. /// </summary> /// <param name="last">The last QuadNode in a circularly linked list</param> /// <param name="nodes">The resulting nodes are added to this list</param> /// <param name="bounds">The bounds to test against each node</param> public void GetIntersectingNodes(IMesQuadNode <T> last, IList <IMesQuadNode <T> > nodes, RectangleF bounds) { if (last != null) { IMesQuadNode <T> n = last; do { n = n.Next; // first node. if (n.Bounds.IntersectsWith(bounds)) { nodes.Add(n); } } while (n != last); } }
/// <summary> /// Walk the given linked list and test each node against the given bounds/ /// </summary> /// <param name="last">The last node in the circularly linked list.</param> /// <param name="bounds">Bounds to test</param> /// <returns>Return true if a node in the list intersects the bounds</returns> public Boolean HasIntersectingNodes(IMesQuadNode <T> last, RectangleF bounds) { if (last != null) { IMesQuadNode <T> n = last; do { n = n.Next; // first node. if (n.Bounds.IntersectsWith(bounds)) { return(true); } } while (n != last); } return(false); }
public static void Dump <T>(this IMesQuadrant <T> source, LogWriter w) where T : class { w.WriteAttribute("Bounds", source.Bounds.ToString()); if (source.Nodes != null) { IMesQuadNode <T> n = source.Nodes; do { n = n.Next; // first node. w.Open("node"); w.WriteAttribute("Bounds", n.Bounds.ToString()); w.Close(); } while (n != source.Nodes); } DumpQuadrant("TopLeft", source.TopLeft, w); DumpQuadrant("TopRight", source.TopRight, w); DumpQuadrant("BottomLeft", source.BottomLeft, w); DumpQuadrant("BottomRight", source.BottomRight, w); }
/// <summary> /// Insert the given node /// </summary> /// <param name="node">The node </param> /// <param name="bounds">The bounds of that node</param> /// <returns></returns> public IMesQuadrant <T> Insert(T node, RectangleF 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"); } Single w = Bounds.Width / 2; if (w == 0) { w = 1; } Single 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. RectangleF topLeft = new RectangleF(Bounds.Left, Bounds.Top, w, h); RectangleF topRight = new RectangleF(Bounds.Left + w, Bounds.Top, w, h); RectangleF bottomLeft = new RectangleF(Bounds.Left, Bounds.Top + h, w, h); RectangleF bottomRight = new RectangleF(Bounds.Left + w, Bounds.Top + h, w, h); IMesQuadrant <T> child = null; // See if any child quadrants completely contain this node. if (topLeft.Contains(bounds)) { if (TopLeft == null) { TopLeft = new MesQuadrant <T>(this, topLeft); } child = TopLeft; } else if (topRight.Contains(bounds)) { if (TopRight == null) { TopRight = new MesQuadrant <T>(this, topRight); } child = TopRight; } else if (bottomLeft.Contains(bounds)) { if (BottomLeft == null) { BottomLeft = new MesQuadrant <T>(this, bottomLeft); } child = BottomLeft; } else if (bottomRight.Contains(bounds)) { if (BottomRight == null) { BottomRight = new MesQuadrant <T>(this, bottomRight); } child = BottomRight; } if (child != null) { return(child.Insert(node, bounds)); } else { MesQuadNode <T> n = new MesQuadNode <T>(node, bounds); if (Nodes == null) { n.Next = n; } else { // link up in circular link list. IMesQuadNode <T> x = Nodes; n.Next = x.Next; x.Next = n; } Nodes = n; return(this); } }