-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsplit_packer.cpp
More file actions
40 lines (35 loc) · 1.5 KB
/
split_packer.cpp
File metadata and controls
40 lines (35 loc) · 1.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include "split_packer.hpp"
PackedRectNode::PackedRectNode(int x, int y, int w, int h) : top_left_x(x), top_left_y(y), w(w), h(h) {}
Block::Block(int w, int h) : w(w), h(h) {}
SplitPacker::SplitPacker(int width, int height) { root = std::make_shared<PackedRectNode>(0, 0, width, height); }
std::shared_ptr<PackedRectNode> SplitPacker::find_node_with_enough_space_rec(std::shared_ptr<PackedRectNode> node,
int width, int height) {
if (!node)
return nullptr;
if (node->used) {
auto right_node = find_node_with_enough_space_rec(node->right, width, height);
return right_node ? right_node : find_node_with_enough_space_rec(node->left, width, height);
} else if (width <= node->w && height <= node->h) {
node->used = true;
node->right =
std::make_shared<PackedRectNode>(node->top_left_x + width, node->top_left_y, node->w - width, height);
node->left =
std::make_shared<PackedRectNode>(node->top_left_x, node->top_left_y + height, node->w, node->h - height);
return node;
} else {
return nullptr;
}
}
void SplitPacker::fit(std::vector<Block> &blocks) {
for (auto &block : blocks) {
fit(block);
}
}
void SplitPacker::fit(Block &block) {
auto node = find_node_with_enough_space_rec(root, block.w, block.h);
if (node) {
block.packed_placement = *node;
} else {
block.packed_placement = std::nullopt;
}
}