public ICollection <T> Query(Rectangle query) { var region = IntRect2.FromRectangle(query); var results = new HashSet <T>(); var s = new Stack <Node>(); s.Push(Root); while (s.Any()) { var node = s.Pop(); if (node.Rect.IntersectsWith(region)) { if (node.TopLeft == null) { foreach (var itemAndRect in node.ItemAndRects) { results.Add(itemAndRect.Item); } } else { s.Push(node.TopLeft); s.Push(node.TopRight); s.Push(node.BottomLeft); s.Push(node.BottomRight); } } } return(results); }
public QuadTree(int subdivisionItemCountThreshold, int maxQuadDepth, IntRect2 bounds) { this.subdivisionItemCountThreshold = subdivisionItemCountThreshold; this.maxQuadDepth = maxQuadDepth; Root = new Node(0, bounds); }
public void Insert(T item, IntRect2 regionRect) { var itemAndRect = new ItemAndRect { Item = item, Rect = regionRect }; InsertToNode(Root, itemAndRect); }
private BvhILS2(BvhILS2 first, BvhILS2 second, IntLineSegment2[] segments, int segmentsStartIndexInclusive, int segmentsEndIndexExclusive, IntRect2 bounds) { First = first; Second = second; Segments = segments; SegmentsStartIndexInclusive = segmentsStartIndexInclusive; SegmentsEndIndexExclusive = segmentsEndIndexExclusive; Bounds = bounds; }
public static IntRect2 BoundingRectangles(IntRect2 first, IntRect2 second) { return(new IntRect2 { Left = Math.Min(first.Left, second.Left), Top = Math.Min(first.Top, second.Top), Right = Math.Max(first.Right, second.Right), Bottom = Math.Max(first.Bottom, second.Bottom) }); }
public bool IntersectsWith(IntRect2 rect) { if (Right < rect.Left) { return(false); } if (Left > rect.Right) { return(false); } if (Bottom < rect.Top) { return(false); } if (Top > rect.Bottom) { return(false); } return(true); }
public static BvhILS2 Build(IEnumerable <IntLineSegment2> segmentEnumerable) { var inputSegments = segmentEnumerable.ToArray(); var inputSegmentMidpoints = inputSegments.Map(s => s.ComputeMidpoint()); var segmentIndices = Util.Generate(inputSegments.Length, i => i); var xComparer = Comparer <int> .Create((a, b) => inputSegmentMidpoints[a].X.CompareTo(inputSegmentMidpoints[b].X)); var yComparer = Comparer <int> .Create((a, b) => inputSegmentMidpoints[a].Y.CompareTo(inputSegmentMidpoints[b].Y)); var outputSegments = new IntLineSegment2[inputSegments.Length]; IntRect2 BoundingSegments(int startIndexInclusive, int endIndexExclusive) { cInt minX = cInt.MaxValue, minY = cInt.MaxValue, maxX = cInt.MinValue, maxY = cInt.MinValue; for (var i = startIndexInclusive; i < endIndexExclusive; i++) { if (inputSegments[segmentIndices[i]].First.X < minX) { minX = inputSegments[segmentIndices[i]].First.X; } if (inputSegments[segmentIndices[i]].Second.X < minX) { minX = inputSegments[segmentIndices[i]].Second.X; } if (inputSegments[segmentIndices[i]].First.Y < minY) { minY = inputSegments[segmentIndices[i]].First.Y; } if (inputSegments[segmentIndices[i]].Second.Y < minY) { minY = inputSegments[segmentIndices[i]].Second.Y; } if (maxX < inputSegments[segmentIndices[i]].First.X) { maxX = inputSegments[segmentIndices[i]].First.X; } if (maxX < inputSegments[segmentIndices[i]].Second.X) { maxX = inputSegments[segmentIndices[i]].Second.X; } if (maxY < inputSegments[segmentIndices[i]].First.Y) { maxY = inputSegments[segmentIndices[i]].First.Y; } if (maxY < inputSegments[segmentIndices[i]].Second.Y) { maxY = inputSegments[segmentIndices[i]].Second.Y; } } // ir2 is inclusive return(new IntRect2 { Left = minX, Top = minY, Right = maxX, Bottom = maxY }); } BvhILS2 BuildInternal(int startInclusive, int endExclusive, bool splitXElseY) { if (endExclusive - startInclusive < 16) { for (var i = startInclusive; i < endExclusive; i++) { outputSegments[i] = inputSegments[segmentIndices[i]]; } return(new BvhILS2(null, null, outputSegments, startInclusive, endExclusive, BoundingSegments(startInclusive, endExclusive))); } Array.Sort(segmentIndices, startInclusive, endExclusive - startInclusive, splitXElseY ? xComparer : yComparer); int midpoint = (startInclusive + endExclusive) / 2; var first = BuildInternal(startInclusive, midpoint, !splitXElseY); var second = BuildInternal(midpoint, endExclusive, !splitXElseY); var bounds = IntRect2.BoundingRectangles(first.Bounds, second.Bounds); return(new BvhILS2(first, second, outputSegments, startInclusive, endExclusive, bounds)); } return(BuildInternal(0, inputSegments.Length, true)); }
public Node(int depth, IntRect2 rect) { Depth = depth; Rect = rect; }