Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Diagonal rotations #610

Open
colinmollenhour opened this issue May 15, 2024 · 5 comments
Open

Diagonal rotations #610

colinmollenhour opened this issue May 15, 2024 · 5 comments

Comments

@colinmollenhour
Copy link
Contributor

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
Copy link

timint commented May 23, 2024

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
Copy link
Owner

dvdoug commented May 27, 2024

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
Copy link

Swahjak commented Aug 5, 2024

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
Copy link
Contributor Author

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
Copy link
Owner

dvdoug commented Aug 11, 2024

@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

// having packed layers, there may be tall, narrow gaps at the ends that can be utilised
$maxLayerWidth = max(array_map(static fn (PackedLayer $layer) => $layer->getEndX(), $layers));
$layers[] = $this->layerPacker->packLayer($items, $this->getPackedItemList($layers), $maxLayerWidth, 0, 0, $boxWidth, $boxLength, $this->box->getInnerDepth(), $this->box->getInnerDepth(), false, null);
$maxLayerLength = max(array_map(static fn (PackedLayer $layer) => $layer->getEndY(), $layers));
$layers[] = $this->layerPacker->packLayer($items, $this->getPackedItemList($layers), 0, $maxLayerLength, 0, $boxWidth, $boxLength, $this->box->getInnerDepth(), $this->box->getInnerDepth(), false, null);
, that's probably the best place to put an initial version of this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants