示例#1
0
        ImRect ScoreRect(int width, int height, FreeRectChoiceHeuristic method, ref int score1, ref int score2)
        {
            ImRect newNode = new ImRect();

            score1 = int.MaxValue;
            score2 = int.MaxValue;
            switch (method)
            {
            case FreeRectChoiceHeuristic.RectBestShortSideFit: newNode = FindPositionForNewNodeBestShortSideFit(width, height, ref score1, ref score2); break;

            case FreeRectChoiceHeuristic.RectBottomLeftRule: newNode = FindPositionForNewNodeBottomLeft(width, height, ref score1, ref score2); break;

            case FreeRectChoiceHeuristic.RectContactPointRule:
                newNode = FindPositionForNewNodeContactPoint(width, height, ref score1);
                score1  = -score1;    // Reverse since we are minimizing, but for contact point score bigger is better.
                break;

            case FreeRectChoiceHeuristic.RectBestLongSideFit: newNode = FindPositionForNewNodeBestLongSideFit(width, height, ref score2, ref score1); break;

            case FreeRectChoiceHeuristic.RectBestAreaFit: newNode = FindPositionForNewNodeBestAreaFit(width, height, ref score1, ref score2); break;
            }

            // Cannot fit the current rectangle.
            if (newNode.height == 0)
            {
                score1 = int.MaxValue;
                score2 = int.MaxValue;
            }

            return(newNode);
        }
示例#2
0
        bool SplitFreeNode(ImRect freeNode, ref ImRect usedNode)
        {
            // Test with SAT if the rectangles even intersect.
            if (usedNode.x >= freeNode.x + freeNode.width || usedNode.x + usedNode.width <= freeNode.x ||
                usedNode.y >= freeNode.y + freeNode.height || usedNode.y + usedNode.height <= freeNode.y)
            {
                return(false);
            }

            if (usedNode.x < freeNode.x + freeNode.width && usedNode.x + usedNode.width > freeNode.x)
            {
                // New node at the top side of the used node.
                if (usedNode.y > freeNode.y && usedNode.y < freeNode.y + freeNode.height)
                {
                    ImRect newNode = freeNode;
                    newNode.height = usedNode.y - newNode.y;
                    freeRectangles.Add(newNode);
                }

                // New node at the bottom side of the used node.
                if (usedNode.y + usedNode.height < freeNode.y + freeNode.height)
                {
                    ImRect newNode = freeNode;
                    newNode.y      = usedNode.y + usedNode.height;
                    newNode.height = freeNode.y + freeNode.height - (usedNode.y + usedNode.height);
                    freeRectangles.Add(newNode);
                }
            }

            if (usedNode.y < freeNode.y + freeNode.height && usedNode.y + usedNode.height > freeNode.y)
            {
                // New node at the left side of the used node.
                if (usedNode.x > freeNode.x && usedNode.x < freeNode.x + freeNode.width)
                {
                    ImRect newNode = freeNode;
                    newNode.width = usedNode.x - newNode.x;
                    freeRectangles.Add(newNode);
                }

                // New node at the right side of the used node.
                if (usedNode.x + usedNode.width < freeNode.x + freeNode.width)
                {
                    ImRect newNode = freeNode;
                    newNode.x     = usedNode.x + usedNode.width;
                    newNode.width = freeNode.x + freeNode.width - (usedNode.x + usedNode.width);
                    freeRectangles.Add(newNode);
                }
            }

            return(true);
        }
示例#3
0
        ImRect FindPositionForNewNodeBestAreaFit(int width, int height, ref int bestAreaFit, ref int bestShortSideFit)
        {
            ImRect bestNode = new ImRect();

            //memset(&bestNode, 0, sizeof(ImRect));

            bestAreaFit = int.MaxValue;

            for (int i = 0; i < freeRectangles.Count; ++i)
            {
                int areaFit = (int)freeRectangles[i].width * (int)freeRectangles[i].height - width * height;

                // Try to place the rectangle in upright (non-flipped) orientation.
                if (freeRectangles[i].width >= width && freeRectangles[i].height >= height)
                {
                    int leftoverHoriz = Math.Abs((int)freeRectangles[i].width - width);
                    int leftoverVert  = Math.Abs((int)freeRectangles[i].height - height);
                    int shortSideFit  = Math.Min(leftoverHoriz, leftoverVert);

                    if (areaFit < bestAreaFit || (areaFit == bestAreaFit && shortSideFit < bestShortSideFit))
                    {
                        bestNode.x       = freeRectangles[i].x;
                        bestNode.y       = freeRectangles[i].y;
                        bestNode.width   = width;
                        bestNode.height  = height;
                        bestShortSideFit = shortSideFit;
                        bestAreaFit      = areaFit;
                    }
                }

                if (allowRotations && freeRectangles[i].width >= height && freeRectangles[i].height >= width)
                {
                    int leftoverHoriz = Math.Abs((int)freeRectangles[i].width - height);
                    int leftoverVert  = Math.Abs((int)freeRectangles[i].height - width);
                    int shortSideFit  = Math.Min(leftoverHoriz, leftoverVert);

                    if (areaFit < bestAreaFit || (areaFit == bestAreaFit && shortSideFit < bestShortSideFit))
                    {
                        bestNode.x       = freeRectangles[i].x;
                        bestNode.y       = freeRectangles[i].y;
                        bestNode.width   = height;
                        bestNode.height  = width;
                        bestShortSideFit = shortSideFit;
                        bestAreaFit      = areaFit;
                    }
                }
            }
            return(bestNode);
        }
示例#4
0
        public void Insert(List <ImRect> rects, List <ImRect> dst, FreeRectChoiceHeuristic method)
        {
            dst.Clear();
            dst.AddRange(new ImRect[rects.Count]);

            var remaining = rects.Count;
            var completed = new bool[rects.Count];

            while (remaining > 0)
            {
                int    bestScore1    = int.MaxValue;
                int    bestScore2    = int.MaxValue;
                int    bestRectIndex = -1;
                ImRect bestNode      = new ImRect();

                for (int i = 0; i < rects.Count; ++i)
                {
                    if (!completed[i])
                    {
                        int    score1  = 0;
                        int    score2  = 0;
                        ImRect newNode = ScoreRect((int)rects[i].width, (int)rects[i].height, method, ref score1, ref score2);

                        if (score1 < bestScore1 || (score1 == bestScore1 && score2 < bestScore2))
                        {
                            bestScore1    = score1;
                            bestScore2    = score2;
                            bestNode      = newNode;
                            bestRectIndex = i;
                        }
                    }
                }

                if (bestRectIndex == -1)
                {
                    return;
                }

                PlaceRect(bestNode);
                completed[bestRectIndex] = true;
                dst[bestRectIndex]       = bestNode;
                remaining--;
                //rects.RemoveAt(bestRectIndex);
            }
        }
示例#5
0
        public void Init(int width, int height, bool rotations = true)
        {
            binWidth       = width;
            binHeight      = height;
            allowRotations = rotations;

            ImRect n = new ImRect();

            n.x      = 0;
            n.y      = 0;
            n.width  = width;
            n.height = height;

            usedRectangles.Clear();

            freeRectangles.Clear();
            freeRectangles.Add(n);
        }
示例#6
0
        void PlaceRect(ImRect node)
        {
            int numRectanglesToProcess = freeRectangles.Count;

            for (int i = 0; i < numRectanglesToProcess; ++i)
            {
                if (SplitFreeNode(freeRectangles[i], ref node))
                {
                    freeRectangles.RemoveAt(i);
                    --i;
                    --numRectanglesToProcess;
                }
            }

            PruneFreeList();

            usedRectangles.Add(node);
        }
示例#7
0
 public void Clip(ImRect clip)
 {
     if (Min.x < clip.Min.x)
     {
         Min.x = clip.Min.x;
     }
     if (Min.y < clip.Min.y)
     {
         Min.y = clip.Min.y;
     }
     if (Max.x > clip.Max.x)
     {
         Max.x = clip.Max.x;
     }
     if (Max.y > clip.Max.y)
     {
         Max.y = clip.Max.y;
     }
 }
示例#8
0
 public void Add(ImRect rhs)
 {
     if (Min.x > rhs.Min.x)
     {
         Min.x = rhs.Min.x;
     }
     if (Min.y > rhs.Min.y)
     {
         Min.y = rhs.Min.y;
     }
     if (Max.x < rhs.Max.x)
     {
         Max.x = rhs.Max.x;
     }
     if (Max.y < rhs.Max.y)
     {
         Max.y = rhs.Max.y;
     }
 }
示例#9
0
        public ImRect Insert(int width, int height, FreeRectChoiceHeuristic method)
        {
            ImRect newNode = new ImRect();
            int    score1  = 0; // Unused in this function. We don't need to know the score after finding the position.
            int    score2  = 0;

            switch (method)
            {
            case FreeRectChoiceHeuristic.RectBestShortSideFit: newNode = FindPositionForNewNodeBestShortSideFit(width, height, ref score1, ref score2); break;

            case FreeRectChoiceHeuristic.RectBottomLeftRule: newNode = FindPositionForNewNodeBottomLeft(width, height, ref score1, ref score2); break;

            case FreeRectChoiceHeuristic.RectContactPointRule: newNode = FindPositionForNewNodeContactPoint(width, height, ref score1); break;

            case FreeRectChoiceHeuristic.RectBestLongSideFit: newNode = FindPositionForNewNodeBestLongSideFit(width, height, ref score2, ref score1); break;

            case FreeRectChoiceHeuristic.RectBestAreaFit: newNode = FindPositionForNewNodeBestAreaFit(width, height, ref score1, ref score2); break;
            }

            if (newNode.height == 0)
            {
                return(newNode);
            }

            int numRectanglesToProcess = freeRectangles.Count;

            for (int i = 0; i < numRectanglesToProcess; ++i)
            {
                if (SplitFreeNode(freeRectangles[i], ref newNode))
                {
                    freeRectangles.RemoveAt(i);
                    --i;
                    --numRectanglesToProcess;
                }
            }

            PruneFreeList();

            usedRectangles.Add(newNode);
            return(newNode);
        }
示例#10
0
        ImRect FindPositionForNewNodeBottomLeft(int width, int height, ref int bestY, ref int bestX)
        {
            ImRect bestNode = new ImRect();

            //memset(bestNode, 0, sizeof(ImRect));

            bestY = int.MaxValue;

            for (int i = 0; i < freeRectangles.Count; ++i)
            {
                // Try to place the rectangle in upright (non-flipped) orientation.
                if (freeRectangles[i].width >= width && freeRectangles[i].height >= height)
                {
                    int topSideY = (int)freeRectangles[i].y + height;
                    if (topSideY < bestY || (topSideY == bestY && freeRectangles[i].x < bestX))
                    {
                        bestNode.x      = freeRectangles[i].x;
                        bestNode.y      = freeRectangles[i].y;
                        bestNode.width  = width;
                        bestNode.height = height;
                        bestY           = topSideY;
                        bestX           = (int)freeRectangles[i].x;
                    }
                }
                if (allowRotations && freeRectangles[i].width >= height && freeRectangles[i].height >= width)
                {
                    int topSideY = (int)freeRectangles[i].y + width;
                    if (topSideY < bestY || (topSideY == bestY && freeRectangles[i].x < bestX))
                    {
                        bestNode.x      = freeRectangles[i].x;
                        bestNode.y      = freeRectangles[i].y;
                        bestNode.width  = height;
                        bestNode.height = width;
                        bestY           = topSideY;
                        bestX           = (int)freeRectangles[i].x;
                    }
                }
            }
            return(bestNode);
        }
示例#11
0
        ImRect FindPositionForNewNodeContactPoint(int width, int height, ref int bestContactScore)
        {
            ImRect bestNode = new ImRect();

            //memset(&bestNode, 0, sizeof(ImRect));

            bestContactScore = -1;

            for (int i = 0; i < freeRectangles.Count; ++i)
            {
                // Try to place the rectangle in upright (non-flipped) orientation.
                if (freeRectangles[i].width >= width && freeRectangles[i].height >= height)
                {
                    int score = ContactPointScoreNode((int)freeRectangles[i].x, (int)freeRectangles[i].y, width, height);
                    if (score > bestContactScore)
                    {
                        bestNode.x       = (int)freeRectangles[i].x;
                        bestNode.y       = (int)freeRectangles[i].y;
                        bestNode.width   = width;
                        bestNode.height  = height;
                        bestContactScore = score;
                    }
                }
                if (allowRotations && freeRectangles[i].width >= height && freeRectangles[i].height >= width)
                {
                    int score = ContactPointScoreNode((int)freeRectangles[i].x, (int)freeRectangles[i].y, height, width);
                    if (score > bestContactScore)
                    {
                        bestNode.x       = (int)freeRectangles[i].x;
                        bestNode.y       = (int)freeRectangles[i].y;
                        bestNode.width   = height;
                        bestNode.height  = width;
                        bestContactScore = score;
                    }
                }
            }
            return(bestNode);
        }
示例#12
0
 bool IsContainedIn(ImRect a, ImRect b)
 {
     return(a.x >= b.x && a.y >= b.y &&
            a.x + a.width <= b.x + b.width &&
            a.y + a.height <= b.y + b.height);
 }
示例#13
0
 public bool Overlaps(ImRect r)
 {
     return(r.Min.y < Max.y && r.Max.y > Min.y && r.Min.x < Max.x && r.Max.x > Min.x);
 }
示例#14
0
 public bool Contains(ImRect r)
 {
     return(r.Min.x >= Min.x && r.Min.y >= Min.y && r.Max.x < Max.x && r.Max.y < Max.y);
 }