예제 #1
0
        private static ISpatialIndexNode <IExtents, TItem> findLeastExpandedChild(
            IEnumerable <ISpatialIndexNode <IExtents, TItem> > children,
            ComputationExtents currentBounds,
            Double leastExpandedArea,
            Double leastExpandedChildArea)
        {
            ISpatialIndexNode <IExtents, TItem> leastExpandedChild = null;

            foreach (ISpatialIndexNode <IExtents, TItem> child in children)
            {
                ComputationExtents childBounds = child.Bounds != null
                                                        ? new ComputationExtents(child.Bounds)
                                                        : new ComputationExtents();
                ComputationExtents candidateRegion = childBounds.Union(currentBounds);

                Double candidateRegionArea = candidateRegion.Area;
                Double childArea           = childBounds.Area;
                Double expandedArea        = candidateRegionArea - childArea;

                if (expandedArea < leastExpandedArea)
                {
                    leastExpandedChild     = child;
                    leastExpandedChildArea = childArea;
                    leastExpandedArea      = expandedArea;
                }
                else if (expandedArea == leastExpandedArea &&
                         childArea < leastExpandedChildArea)
                {
                    leastExpandedChild     = child;
                    leastExpandedChildArea = childArea;
                }
            }

            return(leastExpandedChild);
        }
예제 #2
0
        private GroupBoundsLeastEnlarged pickNext(IList <IBoundable <IExtents> > entries,
                                                  ComputationExtents group1Bounds,
                                                  ComputationExtents group2Bounds,
                                                  out IBoundable <IExtents> entry)
        {
            Double maxArealDifference          = -1;
            GroupBoundsLeastEnlarged group     = GroupBoundsLeastEnlarged.Tie;
            IBoundable <IExtents>    nextEntry = null;

            foreach (IBoundable <IExtents> e in entries)
            {
                ComputationExtents bounds     = new ComputationExtents(e.Bounds);
                ComputationExtents group1Join = bounds.Union(group1Bounds);
                ComputationExtents group2Join = bounds.Union(group2Bounds);

                Double arealDifferenceGroup1 = Math.Abs(
                    group1Join.Area - group1Bounds.Area);

                Double arealDifferenceGroup2 = Math.Abs(
                    group2Join.Area - group2Bounds.Area);

                Double differenceInAreas = Math.Abs(arealDifferenceGroup1 - arealDifferenceGroup2);

                if (differenceInAreas > maxArealDifference)
                {
                    maxArealDifference = differenceInAreas;
                    nextEntry          = e;

                    if (arealDifferenceGroup1 < arealDifferenceGroup2)
                    {
                        group = GroupBoundsLeastEnlarged.Group1;
                    }
                    else if (arealDifferenceGroup2 < arealDifferenceGroup1)
                    {
                        group = GroupBoundsLeastEnlarged.Group2;
                    }
                }
            }

            entries.Remove(nextEntry);
            entry = nextEntry;
            return(group);
        }
예제 #3
0
        private static void pickSeeds(IList <IBoundable <IExtents> > items,
                                      IBoundable <IExtents>[] group1,
                                      IBoundable <IExtents>[] group2)
        {
            Int32  group1Count = 0, group2Count = 0;
            Double largestWaste = -1;

            ComputationExtents[] allExtents = new ComputationExtents[items.Count];

            Int32 itemCount = items.Count;

            // read the bounds into local structures only once
            // for speed
            for (Int32 i = 0; i < itemCount; i++)
            {
                allExtents[i] = new ComputationExtents(items[i].Bounds);
            }

            Int32 seed1Index = -1, seed2Index = -1;

            for (Int32 i = 0; i < itemCount; i++)
            {
                for (int j = 0; j < itemCount; j++)
                {
                    if (i == j)
                    {
                        continue;
                    }

                    ComputationExtents e1 = allExtents[i];
                    ComputationExtents e2 = allExtents[j];
                    ComputationExtents minBoundingRectangle = e1.Union(e2);
                    ComputationExtents intersection         = e1.Intersection(e2);

                    Double minBoundingArea = minBoundingRectangle.Area;
                    Double entry1Area      = e1.Area;
                    Double entry2Area      = e2.Area;

                    Double waste = (minBoundingArea - entry1Area - entry2Area)
                                   + intersection.Area;

                    if (group1Count == 0 && group2Count == 0)
                    {
                        group1[group1Count++] = items[i];
                        group2[group2Count++] = items[j];
                        seed1Index            = i;
                        seed2Index            = j;
                        largestWaste          = waste;
                        continue;
                    }

                    if (waste > largestWaste)
                    {
                        group1[0]    = items[i];
                        group2[0]    = items[j];
                        seed1Index   = i;
                        seed2Index   = j;
                        largestWaste = waste;
                    }
                }
            }

            if (seed1Index > seed2Index)
            {
                items.RemoveAt(seed1Index);
                items.RemoveAt(seed2Index);
            }
            else
            {
                items.RemoveAt(seed2Index);
                items.RemoveAt(seed1Index);
            }
        }