示例#1
0
        bool SplitFreeNode(BinPackRect freeNode, BinPackRect usedNode)
        {
            // test if the rects even intersect
            bool insideX = usedNode.X <freeNode.Right && usedNode.Right> freeNode.X;
            bool insideY = usedNode.Y <freeNode.Bottom && usedNode.Bottom> freeNode.Y;

            if (!insideX || !insideY)
            {
                return(false);
            }

            if (insideX)
            {
                // new node at the top side of the used node
                if (usedNode.Y > freeNode.Y && usedNode.Y < freeNode.Bottom)
                {
                    BinPackRect newNode = freeNode;
                    newNode.Height = usedNode.Y - newNode.Y;
                    freeList.Add(newNode);
                }

                // new node at the bottom side of the used node
                if (usedNode.Bottom < freeNode.Bottom)
                {
                    BinPackRect newNode = freeNode;
                    newNode.Y      = usedNode.Bottom;
                    newNode.Height = freeNode.Bottom - usedNode.Bottom;
                    freeList.Add(newNode);
                }
            }

            if (insideY)
            {
                // new node at the left side of the used node
                if (usedNode.X > freeNode.X && usedNode.X < freeNode.Right)
                {
                    BinPackRect newNode = freeNode;
                    newNode.Width = usedNode.X - newNode.X;
                    freeList.Add(newNode);
                }

                // new node at the right side of the used node
                if (usedNode.Right < freeNode.Right)
                {
                    BinPackRect newNode = freeNode;
                    newNode.X     = usedNode.Right;
                    newNode.Width = freeNode.Right - usedNode.Right;
                    freeList.Add(newNode);
                }
            }

            return(true);
        }
示例#2
0
        public BinPackRect Insert(int width, int height)
        {
            var bestNode     = new BinPackRect();
            int bestShortFit = int.MaxValue;
            int bestLongFit  = int.MaxValue;

            int count = freeList.Count;

            for (int i = 0; i < count; i++)
            {
                // try to place the rect
                BinPackRect rect = freeList[i];
                if (rect.Width < width || rect.Height < height)
                {
                    continue;
                }

                int leftoverX = Math.Abs(rect.Width - width);
                int leftoverY = Math.Abs(rect.Height - height);
                int shortFit  = Math.Min(leftoverX, leftoverY);
                int longFit   = Math.Max(leftoverX, leftoverY);

                if (shortFit < bestShortFit || (shortFit == bestShortFit && longFit < bestLongFit))
                {
                    bestNode     = new BinPackRect(rect.X, rect.Y, width, height);
                    bestShortFit = shortFit;
                    bestLongFit  = longFit;
                }
            }

            if (bestNode.Height == 0)
            {
                return(bestNode);
            }

            // split out free areas into smaller ones
            for (int i = 0; i < count; i++)
            {
                if (SplitFreeNode(freeList[i], bestNode))
                {
                    freeList.RemoveAt(i);
                    i--;
                    count--;
                }
            }

            // prune the freelist
            for (int i = 0; i < freeList.Count; i++)
            {
                for (int j = i + 1; j < freeList.Count; j++)
                {
                    BinPackRect idata = freeList[i];
                    BinPackRect jdata = freeList[j];
                    if (jdata.Contains(idata))
                    {
                        freeList.RemoveAt(i);
                        i--;
                        break;
                    }

                    if (idata.Contains(jdata))
                    {
                        freeList.RemoveAt(j);
                        j--;
                    }
                }
            }

            return(bestNode);
        }
示例#3
0
 public bool Contains(BinPackRect rect)
 {
     return(rect.X >= X && rect.Y >= Y &&
            rect.Right <= Right && rect.Bottom <= Bottom);
 }