private static void DumpQuadrant <T>(String label, IMesQuadrant <T> q, LogWriter w) where T : class { if (q != null) { w.Open("Quadrant"); w.WriteAttribute("Name", label); q.Dump(w); w.Close(); } }
/// <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 MesQuadrant(IMesQuadrant <T> parent, RectangleF 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; }
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); } }