generated from Husenap/cmake-project-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* basic setup * Formatted files using clang-format * added basic unit test * fixed compilation errer * use gcc-10 * use gcc-10 * use gcc-10 * updated actions * updated actions * updated actions * updated actions * updated actions * updated actions * updated actions * implemented basic packing algorithm * removed ranges include * fixed compilation errors * updated readme * updated readme Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
- Loading branch information
1 parent
5630493
commit a577138
Showing
21 changed files
with
255 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,24 @@ | ||
[![Build](https://github.com/Husenap/cmake-project-template/actions/workflows/build.yml/badge.svg)](https://github.com/Husenap/cmake-project-template/actions/workflows/build.yml) | ||
[![Build](https://github.com/Husenap/dubu-rect-pack/actions/workflows/build.yml/badge.svg)](https://github.com/Husenap/dubu-rect-pack/actions/workflows/build.yml) | ||
|
||
# cmake-project-template | ||
# dubu-rect-pack | ||
|
||
Basic C++ project template using CMake. | ||
C++ library for packing rectangles | ||
|
||
## Algorithm | ||
|
||
* When packing a new rect: it tries to find the smallest area it fits into. | ||
* When splitting: it prefers the split which yields the biggest area in one of the spaces. | ||
|
||
## Example Usage | ||
|
||
```cpp | ||
#include <dubu-rect-pack/dubu-rect-pack.hpp> | ||
|
||
int main() { | ||
dubu::rect_pack::Packer packer(256, 256); // create a space of 256x256 | ||
packer.Pack({100, 100}); // Rect{0, 0, 100, 100} | ||
packer.Pack({100, 100}); // Rect{100, 0, 100, 100} | ||
packer.Pack({1000, 100}); // std::nullopt, doesn't fit | ||
packer.Pack({56, 100}); // Rect{200, 0, 56, 100} | ||
} | ||
``` |
18 changes: 13 additions & 5 deletions
18
new_project_name/CMakeLists.txt → dubu_rect_pack/CMakeLists.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#pragma once | ||
|
||
#include "packer/Packer.hpp" | ||
#include "packer/Space.hpp" | ||
#include "packer/Types.hpp" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
#include "Packer.hpp" | ||
|
||
namespace dubu::rect_pack { | ||
|
||
Packer::Packer(int width, int height) { | ||
mSpaces.emplace_back(0, 0, width, height); | ||
} | ||
|
||
std::optional<Rect> Packer::Pack(Size rectangle) { | ||
for (auto it = mSpaces.crbegin(); it != mSpaces.crend(); ++it) { | ||
auto& space = *it; | ||
|
||
if (!space.CanFitRect(rectangle)) { | ||
continue; | ||
} | ||
|
||
const auto [occupied, newSpaces] = space.Split(rectangle); | ||
|
||
mSpaces.erase(it.base() - 1); | ||
|
||
std::move(std::begin(newSpaces), | ||
std::end(newSpaces), | ||
std::back_inserter(mSpaces)); | ||
|
||
std::sort(std::begin(mSpaces), | ||
std::end(mSpaces), | ||
[](const Space& lhs, const Space& rhs) { | ||
return lhs.Area() > rhs.Area(); | ||
}); | ||
|
||
return occupied; | ||
} | ||
|
||
return std::nullopt; | ||
} | ||
|
||
} // namespace dubu::rect_pack |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#pragma once | ||
|
||
#include "Space.hpp" | ||
|
||
namespace dubu::rect_pack { | ||
|
||
class Packer { | ||
public: | ||
Packer(int width, int height); | ||
|
||
std::optional<Rect> Pack(Size rectangle); | ||
|
||
private: | ||
std::vector<Space> mSpaces; | ||
}; | ||
|
||
} // namespace dubu::rect_pack |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
#include "Space.hpp" | ||
|
||
namespace dubu::rect_pack { | ||
|
||
Space::Space(std::uint32_t left, | ||
std::uint32_t top, | ||
std::uint32_t width, | ||
std::uint32_t height) | ||
: mLeft(left) | ||
, mTop(top) | ||
, mWidth(width) | ||
, mHeight(height) | ||
, mArea(width * height) {} | ||
|
||
bool Space::CanFitRect(Size rectangle) const { | ||
return (rectangle.width <= mWidth) && (rectangle.height <= mHeight); | ||
} | ||
|
||
std::pair<Space, std::vector<Space>> Space::Split(Size rectangle) const { | ||
assert(rectangle.width <= mWidth); | ||
assert(rectangle.height <= mHeight); | ||
|
||
if (rectangle.width == mWidth && rectangle.height == mHeight) { | ||
return {*this, {}}; | ||
} else if (rectangle.width == mWidth) { | ||
return {Space(mLeft, mTop, mWidth, rectangle.height), | ||
{Space(mLeft, | ||
mTop + rectangle.height, | ||
mWidth, | ||
mHeight - rectangle.height)}}; | ||
} else if (rectangle.height == mHeight) { | ||
return {Space(mLeft, mTop, rectangle.width, mHeight), | ||
{Space(mLeft + rectangle.width, | ||
mTop, | ||
mWidth - rectangle.width, | ||
mHeight)}}; | ||
} else { | ||
Space newSpace(mLeft, mTop, rectangle.width, rectangle.height); | ||
Space bottomSpace( | ||
mLeft, mTop + rectangle.height, mWidth, mHeight - rectangle.height); | ||
Space rightSpace( | ||
mLeft + rectangle.width, mTop, mWidth - rectangle.width, mHeight); | ||
|
||
if (bottomSpace.Area() >= rightSpace.Area()) { | ||
return {newSpace, | ||
{bottomSpace, | ||
Space(mLeft + rectangle.width, | ||
mTop, | ||
mWidth - rectangle.width, | ||
rectangle.height)}}; | ||
} else { | ||
return {newSpace, | ||
{rightSpace, | ||
Space(mLeft, | ||
mTop + rectangle.height, | ||
rectangle.width, | ||
mHeight - rectangle.height)}}; | ||
} | ||
} | ||
} | ||
|
||
} // namespace dubu::rect_pack |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#pragma once | ||
|
||
#include "Types.hpp" | ||
|
||
namespace dubu::rect_pack { | ||
|
||
class Space { | ||
public: | ||
explicit Space(std::uint32_t left, | ||
std::uint32_t top, | ||
std::uint32_t width, | ||
std::uint32_t height); | ||
|
||
bool CanFitRect(Size rectangle) const; | ||
|
||
std::pair<Space, std::vector<Space>> Split(Size rectangle) const; | ||
|
||
std::uint32_t Area() const { return mArea; } | ||
|
||
operator Rect() const { return Rect{mLeft, mTop, mWidth, mHeight}; } | ||
|
||
private: | ||
std::uint32_t mLeft; | ||
std::uint32_t mTop; | ||
std::uint32_t mWidth; | ||
std::uint32_t mHeight; | ||
std::uint32_t mArea; | ||
}; | ||
|
||
} // namespace dubu::rect_pack |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
#pragma once | ||
|
||
#include <cstdint> | ||
|
||
namespace dubu::rect_pack { | ||
|
||
struct Size { | ||
std::uint32_t width = {}; | ||
std::uint32_t height = {}; | ||
}; | ||
|
||
struct Rect { | ||
std::uint32_t x = {}; | ||
std::uint32_t y = {}; | ||
std::uint32_t w = {}; | ||
std::uint32_t h = {}; | ||
|
||
bool operator==(const Rect& rhs) const { | ||
return x == rhs.x && y == rhs.y && w == rhs.w && h == rhs.h; | ||
} | ||
}; | ||
|
||
} // namespace dubu::rect_pack |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#pragma once | ||
|
||
#include <algorithm> | ||
#include <cassert> | ||
#include <cstdint> | ||
#include <iterator> | ||
#include <optional> | ||
#include <vector> |
3 changes: 2 additions & 1 deletion
3
new_project_name_test/CMakeLists.txt → dubu_rect_pack_test/CMakeLists.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#include <dubu_rect_pack/dubu_rect_pack.hpp> | ||
#include <gtest/gtest.h> | ||
|
||
using namespace dubu::rect_pack; | ||
|
||
TEST(dubu_rect_pack, pack_single_rect) { | ||
{ | ||
dubu::rect_pack::Packer packer(256, 256); | ||
EXPECT_EQ(packer.Pack({256, 256}), (Rect{0, 0, 256, 256})); | ||
} | ||
{ | ||
dubu::rect_pack::Packer packer(256, 256); | ||
EXPECT_EQ(packer.Pack({100, 100}), (Rect{0, 0, 100, 100})); | ||
} | ||
{ | ||
dubu::rect_pack::Packer packer(256, 256); | ||
EXPECT_EQ(packer.Pack({512, 512}), std::nullopt); | ||
} | ||
} | ||
|
||
TEST(dubu_rect_pack, pack_multiple_rects) { | ||
{ | ||
dubu::rect_pack::Packer packer(256, 256); | ||
EXPECT_EQ(packer.Pack({100, 100}), (Rect{0, 0, 100, 100})); | ||
EXPECT_EQ(packer.Pack({100, 100}), (Rect{100, 0, 100, 100})); | ||
EXPECT_EQ(packer.Pack({1000, 100}), std::nullopt); | ||
EXPECT_EQ(packer.Pack({56, 100}), (Rect{200, 0, 56, 100})); | ||
} | ||
} |
Empty file.
Empty file.
This file was deleted.
Oops, something went wrong.
Empty file.
Empty file.
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,5 @@ | ||
#! /bin/bash | ||
|
||
bash $(dirname $0)/build | ||
cd .build/ | ||
pushd .build/ | ||
env CTEST_OUTPUT_ON_FAILURE=1 ctest . "$@" | ||
cd .. |