public void RTreeQuery_IncrementalRectangles() { const int RectsCount = 1000; const int RegionSize = 1000; const int RectSize = 10; for (int seed = 0; seed < 1; ++seed) { var rects = new Rectangle[RectsCount]; var rand = new Random(seed); for (int i = 0; i < RectsCount; ++i) { rects[i] = new Rectangle(new Point(rand.Next(RegionSize), rand.Next(RegionSize))); } // create rTree with just the first rectangle var l = new List<KeyValuePair<Rectangle, Rectangle>> { new KeyValuePair<Rectangle, Rectangle>(rects[0], rects[0]) }; var queryTree = new RTree<Rectangle>(l); // add remaining rectangles 10 at a time for (int a = 1, b = 10; b < RectsCount; a = b, b += 10) { for (int i = a; i < b; ++i) { queryTree.Add(rects[i], rects[i]); } Assert.AreEqual(queryTree.GetAllLeaves().Count(), b, "did we lose leaves?"); Assert.AreEqual(queryTree.GetAllIntersecting( new Rectangle(0, 0, RegionSize + RectSize, RegionSize + RectSize)).Count(), b, "are all leaves inside the max range?"); Assert.AreEqual(queryTree.GetAllIntersecting(new Rectangle(-2, -2, -1, -1)).Count(), 0, "should be no leaves inside this rectangle!"); var query = new Rectangle(rand.Next(RegionSize), rand.Next(RegionSize), rand.Next(RegionSize), rand.Next(RegionSize)); var checkList = (from r in rects.Take(b) where query.Intersects(r) select r).ToList(); var checkSet = new HashSet<Rectangle>(checkList); var result = queryTree.GetAllIntersecting(query).ToList(); Assert.AreEqual(result.Count, checkList.Count, "result and check are different sizes: seed={0}", seed); foreach (var r in result) { Assert.IsTrue(query.Intersects(r), "rect doesn't intersect query: seed={0}, rect={1}, query={2}", seed, r, query); Assert.IsTrue(checkSet.Contains(r), "check set does not contain rect: seed={0}", seed); } } } }
static void DebugVerifyRectsDisjoint(Rectangle rect1, Rectangle rect2, double dblPaddingX, double dblPaddingY, double dblEpsilon) { rect1.PadWidth(dblPaddingX/2.0 - dblEpsilon); rect1.PadHeight(dblPaddingY/2.0 - dblEpsilon); rect2.PadWidth(dblPaddingX/2.0 - dblEpsilon); rect2.PadHeight(dblPaddingY/2.0 - dblEpsilon); Debug.Assert(!rect1.Intersects(rect2)); }
public void RTreeQuery_Rectangles() { const int Seeds = 100; const int RectCount = 1000; const int RegionSize = 1000; const int RectSize = 10; for (int seed = 0; seed < Seeds; ++seed) { var rects = new Rectangle[RectCount]; var rand = new Random(seed); for (int i = 0; i < RectCount; ++i) { rects[i] = new Rectangle(rand.Next(RegionSize), rand.Next(RegionSize), new Point(RectSize, RectSize)); } var bsptree = new RTree<Rectangle>( from r in rects select new KeyValuePair<Rectangle, Rectangle>(r, r)); Assert.AreEqual(bsptree.GetAllLeaves().Count(), RectCount); Assert.AreEqual(bsptree.GetAllIntersecting(new Rectangle(0, 0, RegionSize + RectSize, RegionSize + RectSize)).Count(), RectCount); Assert.AreEqual(bsptree.GetAllIntersecting(new Rectangle(-2, -2, -1, -1)).Count(), 0); var query = new Rectangle(rand.Next(RegionSize), rand.Next(RegionSize), rand.Next(RegionSize), rand.Next(RegionSize)); var checkList = (from r in rects where query.Intersects(r) select r).ToList(); var checkSet = new HashSet<Rectangle>(checkList); var result = bsptree.GetAllIntersecting(query).ToList(); Assert.AreEqual(result.Count, checkList.Count, "result and check are different sizes: seed={0}", seed); foreach (var r in result) { Assert.IsTrue(query.Intersects(r), "rect doesn't intersect query: seed={0}, rect={1}, query={2}", seed, r, query); Assert.IsTrue(checkSet.Contains(r), "check set does not contain rect: seed={0}", seed); } } }
/// <summary> /// Returns the distance between two given rectangles or zero if they intersect. /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> static double GetDistanceRects(Rectangle a, Rectangle b) { if (a.Intersects(b)) return 0; double dx = 0, dy = 0; if (a.Right < b.Left) { dx = a.Left - b.Right; } else if (b.Right < a.Left) { dx = a.Left - b.Right; } if (a.Top < b.Bottom) { dy = b.Bottom - a.Top; } else if (b.Top < a.Bottom) { dy = a.Bottom - b.Top; } double euclid = Math.Sqrt(dx*dx + dy*dy); return euclid; }
static bool CurveOverlapsBox(ICurve curve, ref Rectangle box, Polyline boxPolyline) { // if the curve bounding box doesn't intersect the invalidated region then no overlap! if (!box.Intersects(curve.BoundingBox)) { return false; } // if either end of the curve is inside the box then there is definitely overlap! if (box.Contains(curve.Start) || box.Contains(curve.End)) { return true; } // we have already determined that the curve is close but not fully contained so now we // need to check for a more expensive intersection return Curve.CurveCurveIntersectionOne(boxPolyline, curve, false) != null; }
void SelectEntitiesForDraggingWithRectangle(MsaglMouseEventArgs args) { var rect = new Rectangle(mouseDownGraphPoint, viewer.ScreenToSource(args)); foreach (IViewerNode node in ViewerNodes()) if (rect.Intersects(node.Node.BoundingBox)) SelectObjectForDragging(node); args.Handled = true; }
RectangleNode<Node> FindClusterNodeRecurse(RectangleNode<Node> node, Node cluster, Rectangle previousBox) { if (node.UserData != null) return node.UserData == cluster ? node : null; RectangleNode<Node> n0=null; if (previousBox.Intersects(node.Left.Rectangle)) n0 = FindClusterNodeRecurse(node.Left, cluster, previousBox); if (n0 != null) return n0; if (previousBox.Intersects(node.Right.Rectangle)) return FindClusterNodeRecurse(node.Right, cluster, previousBox); return null; }
/// <summary> /// Returns the intersection of two rectangles. /// </summary> /// <param name="rect1"></param> /// <param name="rect2"></param> /// <returns></returns> public static Rectangle Intersect(Rectangle rect1,Rectangle rect2) { if (rect1.Intersects(rect2)) return new Rectangle(new Point(Math.Max(rect1.Left, rect2.Left), Math.Max(rect1.Bottom, rect2.Bottom)), new Point(Math.Min(rect1.Right, rect2.Right), Math.Min(rect1.Top, rect2.Top))); return Rectangle.CreateAnEmptyBox(); }