private void filterSelfSubAreas(List <IntegerRectangle> areas) { for (int i = areas.Count - 1; i >= 0; i--) { IntegerRectangle filtered = areas[i]; for (int j = areas.Count - 1; j >= 0; j--) { if (i != j) { IntegerRectangle area = areas[j]; if (filtered.x >= area.x && filtered.y >= area.y && filtered.right <= area.right && filtered.bottom <= area.bottom) { freeRectangle(filtered); IntegerRectangle topOfStack = areas.Pop(); if (i < areas.Count) { // Move the one on the top to the freed position areas[i] = topOfStack; } break; } } } } }
public IntegerRectangle GetRectangle(int index, IntegerRectangle rectangle) { IntegerRectangle inserted = m_InsertedRectangles[index]; rectangle.x = inserted.x; rectangle.y = inserted.y; rectangle.width = inserted.width; rectangle.height = inserted.height; return(rectangle); }
public IntegerRectangle AllocateIntegerRectangle(int x, int y, int width, int height) { if (m_IntegerRectangleList.Count > 0) { IntegerRectangle rectangle = m_IntegerRectangleList.Pop(); rectangle.x = x; rectangle.y = y; rectangle.width = width; rectangle.height = height; } return(new IntegerRectangle(x, y, width, height)); }
public int packRectangles(bool sort = true) { if (sort) { mInsertList.Sort((emp1, emp2) => emp1.width.CompareTo(emp2.width)); } while (mInsertList.Count > 0) { SortableSize sortableSize = mInsertList.Pop(); int width = sortableSize.width; int height = sortableSize.height; int index = getFreeAreaIndex(width, height); if (index >= 0) { IntegerRectangle freeArea = mFreeAreas[index]; IntegerRectangle target = allocateRectangle(freeArea.x, freeArea.y, width, height); target.id = sortableSize.id; // Generate the new free areas, these are parts of the old ones intersected or touched by the target generateNewFreeAreas(target, mFreeAreas, mNewFreeAreas); while (mNewFreeAreas.Count > 0) { mFreeAreas.Add(mNewFreeAreas.Pop()); } mInsertedRectangles.Add(target); if (target.right > mPackedWidth) { mPackedWidth = target.right; } if (target.bottom > mPackedHeight) { mPackedHeight = target.bottom; } } freeSize(sortableSize); } return(rectangleCount); }
private IntegerRectangle allocateRectangle(int x, int y, int width, int height) { if (mRectangleStack.Count > 0) { IntegerRectangle rectangle = mRectangleStack.Pop(); rectangle.x = x; rectangle.y = y; rectangle.width = width; rectangle.height = height; rectangle.right = x + width; rectangle.bottom = y + height; return(rectangle); } return(new IntegerRectangle(x, y, width, height)); }
private void generateDividedAreas(IntegerRectangle divider, IntegerRectangle area, List <IntegerRectangle> results) { int count = 0; int rightDelta = area.right - divider.right; if (rightDelta > 0) { results.Add(allocateRectangle(divider.right, area.y, rightDelta, area.height)); count++; } int leftDelta = divider.x - area.x; if (leftDelta > 0) { results.Add(allocateRectangle(area.x, area.y, leftDelta, area.height)); count++; } int bottomDelta = area.bottom - divider.bottom; if (bottomDelta > 0) { results.Add(allocateRectangle(area.x, divider.bottom, area.width, bottomDelta)); count++; } int topDelta = divider.y - area.y; if (topDelta > 0) { results.Add(allocateRectangle(area.x, area.y, area.width, topDelta)); count++; } if (count == 0 && (divider.width < area.width || divider.height < area.height)) { // Only touching the area, store the area itself results.Add(area); } else { freeRectangle(area); } }
public int PackRectangles(bool sort = true) { if (sort) { m_InsertList.Sort((emp1, emp2) => emp1.width.CompareTo(emp2.width)); } while (m_InsertList.Count > 0) { SortableSize sortableSize = m_InsertList.Pop(); int width = sortableSize.width; int height = sortableSize.height; int index = GetFreeAreaIndex(width, height);//根据W,H 得到下标 if (index >= 0) { IntegerRectangle freeArea = m_FreeAreas[index];//得到一个可以容纳target的Area IntegerRectangle target = RectanglePackerMgr.S.AllocateIntegerRectangle(freeArea.x, freeArea.y, width, height); target.id = sortableSize.id; // Generate the new free areas, these are parts of the old ones intersected or touched by the target GenerateNewFreeAreas(target, m_TempFreeAreas); while (m_TempFreeAreas.Count > 0) { m_FreeAreas.Add(m_TempFreeAreas.Pop()); } m_InsertedRectangles.Add(target); if (target.right > m_PackedWidth) { m_PackedWidth = target.right; } if (target.top > m_PackedHeight) { m_PackedHeight = target.top; } } RectanglePackerMgr.S.ReleaseSize(sortableSize); } return(rectangleCount); }
private int getFreeAreaIndex(int width, int height) { IntegerRectangle best = mOutsideRectangle; int index = -1; int paddedWidth = width + mPadding; int paddedHeight = height + mPadding; int count = mFreeAreas.Count; for (int i = count - 1; i >= 0; i--) { IntegerRectangle free = mFreeAreas[i]; if (free.x < mPackedWidth || free.y < mPackedHeight) { // Within the packed area, padding required if (free.x < best.x && paddedWidth <= free.width && paddedHeight <= free.height) { index = i; if ((paddedWidth == free.width && free.width <= free.height && free.right < mWidth) || (paddedHeight == free.height && free.height <= free.width)) { break; } best = free; } } else { // Outside the current packed area, no padding required if (free.x < best.x && width <= free.width && height <= free.height) { index = i; if ((width == free.width && free.width <= free.height && free.right < mWidth) || (height == free.height && free.height <= free.width)) { break; } best = free; } } } return(index); }
private void GenerateNewFreeAreas(IntegerRectangle target, List <IntegerRectangle> results) { // Increase dimensions by one to get the areas on right / bottom this rectangle touches // Also add the padding here int x = target.x; int y = target.y; int right = target.right + 1 + m_Padding; int top = target.top + 1 + m_Padding; IntegerRectangle targetWithPadding = null; if (m_Padding == 0) { targetWithPadding = target; } for (int i = m_FreeAreas.Count - 1; i >= 0; i--) { IntegerRectangle area = m_FreeAreas[i]; if (!(x >= area.right || right <= area.x || y >= area.top || top <= area.y)) { UnityEngine.Debug.LogError(target.x + ":" + area.x); if (targetWithPadding == null) { targetWithPadding = RectanglePackerMgr.S.AllocateIntegerRectangle(target.x, target.y, target.width + m_Padding, target.height + m_Padding); } GenerateDividedAreas(targetWithPadding, area, results); IntegerRectangle topOfStack = m_FreeAreas.Pop(); if (i < m_FreeAreas.Count) { // Move the one on the top to the freed position m_FreeAreas[i] = topOfStack; } } } if (targetWithPadding != null && targetWithPadding != target) { RectanglePackerMgr.S.ReleaseIntegerRectangle(targetWithPadding); } FilterSelfSubAreas(results); }
private void generateNewFreeAreas(IntegerRectangle target, List <IntegerRectangle> areas, List <IntegerRectangle> results) { // Increase dimensions by one to get the areas on right / bottom this rectangle touches // Also add the padding here int x = target.x; int y = target.y; int right = target.right + 1 + mPadding; int bottom = target.bottom + 1 + mPadding; IntegerRectangle targetWithPadding = null; if (mPadding == 0) { targetWithPadding = target; } for (int i = areas.Count - 1; i >= 0; i--) { IntegerRectangle area = areas[i]; if (!(x >= area.right || right <= area.x || y >= area.bottom || bottom <= area.y)) { if (targetWithPadding == null) { targetWithPadding = allocateRectangle(target.x, target.y, target.width + mPadding, target.height + mPadding); } generateDividedAreas(targetWithPadding, area, results); IntegerRectangle topOfStack = areas.Pop(); if (i < areas.Count) { // Move the one on the top to the freed position areas[i] = topOfStack; } } } if (targetWithPadding != null && targetWithPadding != target) { freeRectangle(targetWithPadding); } filterSelfSubAreas(results); }
public RectanglePacker(int width, int height, int padding = 0) { mOutsideRectangle = new IntegerRectangle(width + 1, height + 1, 0, 0); reset(width, height, padding); }
private void freeRectangle(IntegerRectangle rectangle) { mRectangleStack.Add(rectangle); }
public int getRectangleId(int index) { IntegerRectangle inserted = mInsertedRectangles[index]; return(inserted.id); }
// public int packedWidth { get { return mPackedWidth; } } // public int packedHeight { get { return mPackedHeight; } } // public int padding { get { return mPadding; } } public RectanglePacker(int width, int height, int padding = 0) { mOutsideRectangle = RectanglePackerMgr.S.AllocateIntegerRectangle(width + 1, height + 1, 0, 0); Reset(width, height, padding); }
public void ReleaseIntegerRectangle(IntegerRectangle rectangle) { m_IntegerRectangleList.Add(rectangle); }