Пример #1
0
        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);
        }
Пример #2
0
        public QuadTree(int subdivisionItemCountThreshold, int maxQuadDepth, IntRect2 bounds)
        {
            this.subdivisionItemCountThreshold = subdivisionItemCountThreshold;
            this.maxQuadDepth = maxQuadDepth;

            Root = new Node(0, bounds);
        }
Пример #3
0
        public void Insert(T item, IntRect2 regionRect)
        {
            var itemAndRect = new ItemAndRect {
                Item = item, Rect = regionRect
            };

            InsertToNode(Root, itemAndRect);
        }
Пример #4
0
 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;
 }
Пример #5
0
 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)
     });
 }
Пример #6
0
 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);
 }
Пример #7
0
        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));
        }
Пример #8
0
 public Node(int depth, IntRect2 rect)
 {
     Depth = depth;
     Rect  = rect;
 }