/// <summary> /// Quick (O(n log n)) and accurate collision detection /// </summary> /// <param name="labels"></param> public static void QuickAccurateCollisionDetectionMethod(List<BaseLabel> labels) { // find minimum / maximum coordinates double minX = double.MaxValue; double maxX = double.MinValue; double minY = double.MaxValue; double maxY = double.MinValue; foreach (BaseLabel l in labels) { ProperBox box = new ProperBox(l.Box); if (box.Left < minX) minX = box.Left; if (box.Right > maxX) maxX = box.Right; if (box.Bottom > maxY) maxY = box.Bottom; if (box.Top < minY) minY = box.Top; } // sort by area (highest priority first, followed by low area to maximize the amount of labels displayed) var sortedLabels = labels.OrderByDescending(label => label.Priority).ThenBy(label => label.Box.Width * label.Box.Height); // make visible if it does not collide with other labels. Uses a quadtree and is therefore fast O(n log n) QuadtreeNode<ProperBox> quadTree = new QuadtreeNode<ProperBox>(minX, maxX, minY, maxY, new LabelBoxContainmentChecker(), 0, 10); foreach (BaseLabel l in sortedLabels) { if (!l.Show) continue; if (quadTree.CollidesWithAny(new ProperBox(l.Box))) { l.Show = false; } else { ProperBox box = new ProperBox(l.Box); quadTree.Insert(box); } } }
public void Insert(Body body) { if (!aabb.Contains(body.shape.aabb)) { return; } if (bodies.Count < capacity) { bodies.Add(body); } else { if (!subdivided) { Subdivide(); } northeast.Insert(body); northwest.Insert(body); southeast.Insert(body); southwest.Insert(body); } }
public override void Build(AABB aabb, List <Body> bodies) { potentialCollisionCount = 0; rootNode = new QuadtreeNode(aabb, capacity); bodies.ForEach(body => rootNode.Insert(body)); }
public void Insert(Rect rect, T obj) { root.Insert(new DataEntry <T, Rect>(obj, rect)); _count++; }