soimy / maxrects-packer

A max rectangle 2d bin packer npm-module for packing glyphs or images into multiple sprite-sheet/atlas

Home Page:https://soimy.github.io/maxrects-packer/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Packing result is worse when rotation allowed

odrick opened this issue · comments

Related to odrick/free-tex-packer-core#14

Data to reproduce:


maxWidth: 1780
maxHeight: 1780
padding: 0
options: {
    "smart": true,
    "pot": false,
    "square": false,
    "allowRotation": false,
    "logic": 1
}
input

[
    {
        "width": 18,
        "height": 209
    },
    {
        "width": 50,
        "height": 215
    },
    {
        "width": 81,
        "height": 219
    },
    {
        "width": 115,
        "height": 221
    },
    {
        "width": 149,
        "height": 225
    },
    {
        "width": 177,
        "height": 227
    },
    {
        "width": 192,
        "height": 231
    },
    {
        "width": 207,
        "height": 233
    },
    {
        "width": 221,
        "height": 235
    },
    {
        "width": 236,
        "height": 219
    },
    {
        "width": 252,
        "height": 199
    },
    {
        "width": 271,
        "height": 203
    },
    {
        "width": 317,
        "height": 218
    },
    {
        "width": 326,
        "height": 240
    },
    {
        "width": 334,
        "height": 267
    },
    {
        "width": 336,
        "height": 295
    },
    {
        "width": 359,
        "height": 290
    },
    {
        "width": 379,
        "height": 284
    },
    {
        "width": 389,
        "height": 259
    },
    {
        "width": 92,
        "height": 209
    },
    {
        "width": 94,
        "height": 228
    },
    {
        "width": 106,
        "height": 247
    },
    {
        "width": 119,
        "height": 267
    },
    {
        "width": 131,
        "height": 287
    },
    {
        "width": 139,
        "height": 301
    },
    {
        "width": 150,
        "height": 215
    },
    {
        "width": 163,
        "height": 213
    },
    {
        "width": 166,
        "height": 213
    },
    {
        "width": 152,
        "height": 215
    },
    {
        "width": 138,
        "height": 218
    },
    {
        "width": 132,
        "height": 220
    },
    {
        "width": 129,
        "height": 221
    },
    {
        "width": 136,
        "height": 223
    },
    {
        "width": 138,
        "height": 225
    },
    {
        "width": 138,
        "height": 226
    },
    {
        "width": 134,
        "height": 226
    },
    {
        "width": 128,
        "height": 222
    },
    {
        "width": 122,
        "height": 219
    },
    {
        "width": 115,
        "height": 216
    },
    {
        "width": 108,
        "height": 215
    },
    {
        "width": 111,
        "height": 215
    },
    {
        "width": 120,
        "height": 216
    },
    {
        "width": 131,
        "height": 214
    },
    {
        "width": 141,
        "height": 212
    },
    {
        "width": 141,
        "height": 210
    },
    {
        "width": 143,
        "height": 209
    },
    {
        "width": 168,
        "height": 208
    },
    {
        "width": 227,
        "height": 206
    },
    {
        "width": 259,
        "height": 205
    },
    {
        "width": 262,
        "height": 204
    },
    {
        "width": 291,
        "height": 202
    },
    {
        "width": 309,
        "height": 201
    },
    {
        "width": 326,
        "height": 200
    },
    {
        "width": 341,
        "height": 199
    },
    {
        "width": 317,
        "height": 200
    },
    {
        "width": 289,
        "height": 197
    },
    {
        "width": 262,
        "height": 154
    },
    {
        "width": 234,
        "height": 68
    },
    {
        "width": 206,
        "height": 29
    },
    {
        "width": 180,
        "height": 20
    },
    {
        "width": 151,
        "height": 20
    },
    {
        "width": 122,
        "height": 18
    },
    {
        "width": 96,
        "height": 16
    },
    {
        "width": 95,
        "height": 16
    },
    {
        "width": 95,
        "height": 16
    },
    {
        "width": 93,
        "height": 15
    }
]

result width: 1596
result height: 1756
result area: 2802576


maxWidth: 1780
maxHeight: 1780
padding: 0
options: {
    "smart": true,
    "pot": false,
    "square": false,
    "allowRotation": true,
    "logic": 1
}

input: same

result width: 1660
result height: 1759
result area: 2919940


So, packing result area is worse when rotation allowed. However, this should not be.

@odrick Allow rotation will not give the best efficiency result every time. But might be reasonable to do a benchmark with/without allow rotation.

Take a look at the efficiency test code:

test('combined best of', () => {
let heading = ["#", "size"].concat(AREA_CANDIDATES.map(c => c.name));
let results1 = EDGE_CANDIDATES.map(candidate => meassureEfficiency(candidate.factory));
let results2 = AREA_CANDIDATES.map(candidate => meassureEfficiency(candidate.factory));
let results = results1.map((scenario, scenarioIndex) => scenario.map((result1, resultIndex) => {
const result2 = results2[scenarioIndex][resultIndex];
if (result1.bins < result2.bins) {
result1.method = "E";
return result1;
} else if (result1.bins > result2.bins) {
result2.method = "A";
return result2;
} else if (result1.efficieny > result2.efficieny) {
result1.method = "E";
return result1;
} else if (result1.efficieny < result2.efficieny) {
result2.method = "A";
return result2;
} else {
result1.method = "";
return result1;
}
}));
let rows = createRows(results);
console.log(new AsciiTable({ heading, rows }).toString());
});
});
function meassureEfficiency (factory) {
return SCENARIOS.map((scenario, i) => {
let packer = factory();
packer.addArray(scenario);
let bins = packer.bins.length;
let rectSize = rectSizeSum[i];
let usedSize = packer.bins.reduce((memo, bin) => memo + bin.width * bin.height, 0);
let efficieny = rectSize / usedSize;
return {bins, rectSize, usedSize, efficieny};
});
}

Ok, I`m understood. Thanks!