ref: 671771e4799498d22262f134274e804461a90e40
parent: 89218bb4e4e3c8a02acbac70b6abd658fd18a3f3
author: Halfwit <michaelmisch1985@gmail.com>
date: Sun Nov 6 16:55:49 PST 2016
Slight refactoring before changing resizing algorithm
--- a/binpack.c
+++ b/binpack.c
@@ -26,25 +26,21 @@
};
size_t
-create_rect(struct input r[])
-{
+create_rect(struct input r[]) {
size_t length = 0;
char line[50] = "";
-
+
for (unsigned i = 0; fgets(line, sizeof(line), stdin); ++i) {
sscanf(line, "%d %d %d %d %lx", &r[i].min_w, &r[i].min_h, &r[i].max_w, &r[i].max_h, &r[i].wid);
length++;
}
-
return length;
}
/* (max bin size - blob size) / 2 */
void
-center(const size_t length, struct output r[], struct mbin mb)
-{
+center(const size_t length, struct output r[], struct mbin mb) {
unsigned w = 0, h = 0;
-
for (size_t i = 0; i < length; i++) {
if (w < (r[i].w + r[i].x))
w = r[i].w + r[i].x;
@@ -57,12 +53,11 @@
}
}
-/* given set of bins, arrange them smallest to largest w*h */
+/* arrange rectangles smallest to largest w*h */
void
-sort_bins(struct bins b[], size_t *bin_count)
-{
+sort_bins(struct bins b[], size_t *bin_count) {
struct bins temp;
-
+
for (unsigned i = 1; i < *bin_count; i++) {
for (unsigned j = 0; j < *bin_count - i; j++) {
if ((b[j + 1].w * b[j + 1].h) > (b[j].w * b[j].h)) {
@@ -74,7 +69,7 @@
}
}
-/* arrange rectangles largest to smallest, normalized some over min/max */
+/* arrange rectangles largest to smallest */
void
sort_input(struct input r[], const size_t length)
{
@@ -94,7 +89,7 @@
void
create_bins(struct bins bin[], struct output out[], size_t i, size_t j, size_t *bin_count, struct mbin mb)
{
- /* New bins based on subsection of old */
+ /* Local variables */
unsigned x, y, w, h;
x = bin[j].x;
y = bin[j].y;
@@ -125,7 +120,6 @@
else {
bin[j].w = 0;
bin[j].h = 0;
- *bin_count -= 1;
}
}
@@ -136,10 +130,11 @@
out[i] = (struct output){bin[j].x + (mb.gaps / 2), bin[j].y + (mb.gaps / 2), r[i].min_w, r[i].min_h, r[i].wid};
}
+/* Main algorithm */
bool
pack_bin(struct output out[], struct input r[], const size_t length, unsigned *bin_width, unsigned *bin_height, struct mbin mb)
{
- /* Main algorithm */
+ /* initialize bins */
struct bins bin[100];
for (int i = 0; i < 100; i++) {
bin[i] = (struct bins){0, 0, 0, 0};
@@ -146,7 +141,7 @@
}
/* default bin */
- bin[0] = (struct bins){ 0, 0, *bin_width + mb.gaps, *bin_height + mb.gaps};
+ bin[0] = (struct bins){ 0, 0, *bin_width + mb.gaps, *bin_height + mb.gaps};
size_t bin_count = 1;
bool rect_fits;
@@ -165,15 +160,8 @@
break;
}
}
-
- /* Grow main bin if possible */
- if (rect_fits == false) {
- if (mb.x > *bin_width)
- *bin_width += 2;
- if (mb.y > *bin_height)
- *bin_height += 2;
- return true;
- }
+ if (rect_fits == false)
+ return true;
}
return false;
}
@@ -181,9 +169,9 @@
bool
resize(struct output out[], struct input r[], const size_t length, unsigned *bin_width, unsigned *bin_height, struct mbin mb, size_t index)
{
- /* When a bin fills all the space available, pack_bin */
for (size_t i = index; i < length; i++) {
unsigned limitcheck = 0;
+
while (pack_bin(out, r, length, bin_width, bin_height, mb)) {
if (limitcheck == mb.x)
return false;
@@ -210,15 +198,6 @@
}
return ((h < mb.y + (mb.gaps / 2)) && (w < mb.x + (mb.gaps / 2)));
- /*
- if (h >= mb.y + (mb.gaps / 2))
- return false;
-
- if (w >= mb.x + (mb.gaps / 2))
- return false;
-
- return true;
- */
}
int
@@ -229,24 +208,24 @@
int c;
while ((c = getopt(argc, argv, "hg:x:y:")) != -1) {
switch (c) {
- /* read in, all vars unsigned int */
- case 'g': {
- sscanf(optarg, "%u", &mb.gaps);
- break;
- }
- case 'x': {
- sscanf(optarg, "%u", &mb.x);
- break;
- }
- case 'y': {
- sscanf(optarg, "%u", &mb.y);
- break;
- }
- case 'h': {
- fputs("Usage: bin_pack -x screen_width -y screen_height -g gaps\n", stderr);
- return EXIT_SUCCESS;
- }
+ /* read in, all vars unsigned int */
+ case 'g': {
+ sscanf(optarg, "%u", &mb.gaps);
+ break;
}
+ case 'x': {
+ sscanf(optarg, "%u", &mb.x);
+ break;
+ }
+ case 'y': {
+ sscanf(optarg, "%u", &mb.y);
+ break;
+ }
+ case 'h': {
+ fprintf(stderr, "Usage: %s -x screen_width -y screen_height -g gaps\n", argv[0]);
+ return EXIT_SUCCESS;
+ }
+ }
}
struct input r[100];
@@ -263,8 +242,11 @@
unsigned bin_width = mb.x;
unsigned bin_height = mb.y;
-
- /* If we have no large windows */
+ /* TODO: We're going to instead use a binary search approach
+ * to find a size for each bin, so the large windows optimization
+ * can be omitted
+ */
+ /* Test if we can use maximums on all windows */
bool no_large_windows = true;
for (size_t i = 0; i < length; i++) {
struct input temp = r[i];
@@ -283,23 +265,21 @@
bin_width = r[0].min_w;
bin_height = r[0].min_h;
- while (pack_bin(out, r, length, &bin_width, &bin_height, mb)) {
- /* if we've ran this long, something is up */
+ while (pack_bin(out, r, length, &bin_width, &bin_height, mb)) {
+ /* if we've ran this long, something is up */
+ if (limitcheck == mb.x)
+ return EXIT_FAILURE;
+
+ limitcheck++;
+ }
+
+ limitcheck = 0;
+ for (size_t i = 0; i < length; i++) {
+ /* Square out the blob as best as we can */
+ while (resize(out, r, length, &bin_width, &bin_height, mb, i)) {
if (limitcheck == mb.x)
return EXIT_FAILURE;
-
limitcheck++;
- }
-
- limitcheck = 0;
-
- for (size_t i = 0; i < length; i++) {
- /* Square out the blob as best as we can */
- while (resize(out, r, length, &bin_width, &bin_height, mb, i)) {
- if (limitcheck == mb.x)
- return EXIT_FAILURE;
-
- limitcheck++;
}
}
}