/** * Find all possible orientations for an item * @param Item $item * @param OrientatedItem|null $prevItem * @param int $widthLeft * @param int $lengthLeft * @param int $depthLeft * @return OrientatedItem[] */ protected function findPossibleOrientations(Item $item, OrientatedItem $prevItem = null, $widthLeft, $lengthLeft, $depthLeft) { $orientations = []; //Special case items that are the same as what we just packed - keep orientation if ($prevItem && $prevItem->getItem() == $item) { $orientations[] = new OrientatedItem($item, $prevItem->getWidth(), $prevItem->getLength(), $prevItem->getDepth()); } else { //simple 2D rotation $orientations[] = new OrientatedItem($item, $item->getWidth(), $item->getLength(), $item->getDepth()); $orientations[] = new OrientatedItem($item, $item->getLength(), $item->getWidth(), $item->getDepth()); //add 3D rotation if we're allowed if (!$item->getKeepFlat()) { $orientations[] = new OrientatedItem($item, $item->getWidth(), $item->getDepth(), $item->getLength()); $orientations[] = new OrientatedItem($item, $item->getLength(), $item->getDepth(), $item->getWidth()); $orientations[] = new OrientatedItem($item, $item->getDepth(), $item->getWidth(), $item->getLength()); $orientations[] = new OrientatedItem($item, $item->getDepth(), $item->getLength(), $item->getWidth()); } } //remove any that simply don't fit return array_filter($orientations, function (OrientatedItem $i) use($widthLeft, $lengthLeft, $depthLeft) { return $i->getWidth() <= $widthLeft && $i->getLength() <= $lengthLeft && $i->getDepth() <= $depthLeft; }); }