dvdoug / BoxPacker

4D bin packing / knapsack problem solver
MIT License
600 stars 154 forks source link

Diagonal rotations #610

Open colinmollenhour opened 3 months ago

colinmollenhour commented 3 months ago

I know this isn't currently supported but just throwing this out there.. It looks fairly trivial to determine if a rectangle can fit within another rectangle using this formula (found here). So how hard would it be to use that to determine if an item could fit in 3D even if it took up the whole "layer" where it existed? It would be quite an advantage over other models that aren't capable of this at all and say that an item can't fit when it actually can.

timint commented 3 months ago

I'm just a user of this library but thought I could comment.

Checking a rotated item (rotated diagonally flat) should be fairly simple. Taking the diagonal as width and twice the height. I think the big question and complexity is when to do this comparison? In a thought experiment I think I would consider it as a last item fallback attempt. As diagnals in XYZ measures would consume more calculation volume unless somone found a way to deal with diagonally sliced spaces.

image

dvdoug commented 3 months ago

Definitely something for a last-pass only, as it's an inefficient use of space for the following items but at that point "any possible way that it can fit" definitely seems valid to me

Swahjak commented 1 month ago

Hi, I was curious if this is something that you have time / metal bandwidth for at some point in the foreseeable future? If not, would it be something that you would consider a PR for? And if so, could you give some pointers on where to start?

colinmollenhour commented 1 month ago

I think the big question and complexity is when to do this comparison?

We can't expect to get perfect results with this approach being an iterative improvement to the current solution. In my mind this is most valuable for small datasets and to just make sure there is a solution when otherwise there would not be one at all or the next box size up is massively bigger. Aside from stacking additional items of the same dimensions next to the item with the same rotation, which could be a special case, rotating the item would create spaces to the sides of the item that have infinite possible dimensions when converted back to square dimensions. However, even just picking one of the possible spaces or even none of them would be a big improvement over not being able to rotate at all. That's why my first idea was to just make any rotated item consume the entire layer (basically its outer bounding box). So I think the "when" would be only if there is no other way to fit it in the box.

dvdoug commented 3 weeks ago

@Swahjak I'm not likely to get to this soon because I'd want to build my version on top of a different set of internal data structures, but I do take PRs so if you want to have a go at this please feel free to try.

Backwards compatibility is important to me and I don't feel this feature is worth breaking it for so the existing cuboid width/length/depth outputs of a packing need to be kept please. If you can figure out a way to add the actual positioning and placement on top of that (e.g. additional methods) that's cool

The existing "last resort" code is here https://github.com/dvdoug/BoxPacker/blob/4e1731c5573dab6846a9c556ccfeaa8172ca4c41/src/VolumePacker.php#L177-L182, that's probably the best place to put an initial version of this