Switch to the bottom-left picker for the Skyline Bin Packer

This commit is contained in:
Randy Heit 2016-01-10 21:54:28 -06:00
parent 4f0046105d
commit 670058fa3c
2 changed files with 71 additions and 1 deletions

View file

@ -119,7 +119,7 @@ Rect SkylineBinPack::Insert(int width, int height)
return newNode;
}
return InsertMinWaste(width, height);
return InsertBottomLeft(width, height);
}
bool SkylineBinPack::RectangleFits(int skylineNodeIndex, int width, int height, int &y) const
@ -254,6 +254,73 @@ void SkylineBinPack::MergeSkylines()
}
}
Rect SkylineBinPack::InsertBottomLeft(int width, int height)
{
int bestHeight;
int bestWidth;
int bestIndex;
Rect newNode = FindPositionForNewNodeBottomLeft(width, height, bestHeight, bestWidth, bestIndex);
if (bestIndex != -1)
{
assert(disjointRects.Disjoint(newNode));
// Perform the actual packing.
AddSkylineLevel(bestIndex, newNode);
usedSurfaceArea += width * height;
#ifdef _DEBUG
disjointRects.Add(newNode);
#endif
}
else
memset(&newNode, 0, sizeof(Rect));
return newNode;
}
Rect SkylineBinPack::FindPositionForNewNodeBottomLeft(int width, int height, int &bestHeight, int &bestWidth, int &bestIndex) const
{
bestHeight = INT_MAX;
bestIndex = -1;
// Used to break ties if there are nodes at the same level. Then pick the narrowest one.
bestWidth = INT_MAX;
Rect newNode = { 0, 0, 0, 0 };
for(unsigned i = 0; i < skyLine.Size(); ++i)
{
int y;
if (RectangleFits(i, width, height, y))
{
if (y + height < bestHeight || (y + height == bestHeight && skyLine[i].width < bestWidth))
{
bestHeight = y + height;
bestIndex = i;
bestWidth = skyLine[i].width;
newNode.x = skyLine[i].x;
newNode.y = y;
newNode.width = width;
newNode.height = height;
assert(disjointRects.Disjoint(newNode));
}
}
/* if (RectangleFits(i, height, width, y))
{
if (y + width < bestHeight || (y + width == bestHeight && skyLine[i].width < bestWidth))
{
bestHeight = y + width;
bestIndex = i;
bestWidth = skyLine[i].width;
newNode.x = skyLine[i].x;
newNode.y = y;
newNode.width = height;
newNode.height = width;
assert(disjointRects.Disjoint(newNode));
}
}
*/ }
return newNode;
}
Rect SkylineBinPack::InsertMinWaste(int width, int height)
{
int bestHeight;

View file

@ -72,7 +72,10 @@ private:
bool useWasteMap;
GuillotineBinPack wasteMap;
Rect InsertBottomLeft(int width, int height);
Rect InsertMinWaste(int width, int height);
Rect FindPositionForNewNodeBottomLeft(int width, int height, int &bestHeight, int &bestWidth, int &bestIndex) const;
Rect FindPositionForNewNodeMinWaste(int width, int height, int &bestHeight, int &bestWastedArea, int &bestIndex) const;
bool RectangleFits(int skylineNodeIndex, int width, int height, int &y) const;