Exemplo n.º 1
0
 /**
  * Pack as many items as possible into specific given box
  * @param ArtatusBox      $aBox
  * @param ArtatusItemList $aItems
  * @return ArtatusPackedBox packed box
  */
 public function packIntoBox(ArtatusBox $aBox, ArtatusItemList $aItems)
 {
     if ($this->debug) {
         echo "evaluating box {$aBox->getReference()}";
     }
     $packedItems = new ArtatusItemList();
     $remainingDepth = $aBox->getInnerDepth();
     $remainingWeight = $aBox->getMaxWeight() - $aBox->getEmptyWeight();
     $remainingWidth = $aBox->getInnerWidth();
     $remainingLength = $aBox->getInnerLength();
     $layerWidth = $layerLength = $layerDepth = 0;
     while (!$aItems->isEmpty()) {
         $itemToPack = $aItems->top();
         if ($itemToPack->getDepth() > ($layerDepth ?: $remainingDepth) || $itemToPack->getWeight() > $remainingWeight) {
             break;
         }
         if ($this->debug) {
             echo "evaluating item {$itemToPack->getDescription()}";
             echo "remaining width: {$remainingWidth}, length: {$remainingLength}, depth: {$remainingDepth}";
             echo "layerWidth: {$layerWidth}, layerLength: {$layerLength}, layerDepth: {$layerDepth}";
         }
         $itemWidth = $itemToPack->getWidth();
         $itemLength = $itemToPack->getLength();
         $fitsSameGap = min($remainingWidth - $itemWidth, $remainingLength - $itemLength);
         $fitsRotatedGap = min($remainingWidth - $itemLength, $remainingLength - $itemWidth);
         if ($fitsSameGap >= 0 || $fitsRotatedGap >= 0) {
             $packedItems->insert($aItems->extract());
             $remainingWeight -= $itemToPack->getWeight();
             if ($fitsRotatedGap < 0 || $fitsSameGap <= $fitsRotatedGap || !$aItems->isEmpty() && $aItems->top() == $itemToPack && $remainingLength >= 2 * $itemLength) {
                 if ($this->debug) {
                     echo "fits (better) unrotated";
                 }
                 $remainingLength -= $itemLength;
                 $layerWidth += $itemWidth;
                 $layerLength += $itemLength;
             } else {
                 if ($this->debug) {
                     echo "fits (better) rotated";
                 }
                 $remainingLength -= $itemWidth;
                 $layerWidth += $itemLength;
                 $layerLength += $itemWidth;
             }
             $layerDepth = max($layerDepth, $itemToPack->getDepth());
             //greater than 0, items will always be less deep
         } else {
             if (!$layerWidth) {
                 if ($this->debug) {
                     echo "doesn't fit on layer even when empty";
                 }
                 break;
             }
             $remainingWidth = min(floor($layerWidth * 1.1), $aBox->getInnerWidth());
             $remainingLength = min(floor($layerLength * 1.1), $aBox->getInnerLength());
             $remainingDepth -= $layerDepth;
             $layerWidth = $layerLength = $layerDepth = 0;
             if ($this->debug) {
                 echo "doesn't fit, so starting next vertical layer";
             }
         }
     }
     if ($this->debug) {
         echo "done with this box";
     }
     return new ArtatusPackedBox($aBox, $packedItems, $remainingWidth, $remainingLength, $remainingDepth, $remainingWeight);
 }
Exemplo n.º 2
0
$packer->addBox(new ArtatusBox('No. 5 box', 300, 300, 10, 10, 296, 296, 8, 1000));
$packer->addBox(new ArtatusBox('No. 6 box', 300, 300, 10, 10, 296, 296, 8, 1000));
$packer->addItem(new ArtatusItem('Item 1', 250, 250, 2, 200));
$packer->addItem(new ArtatusItem('Item 2', 250, 250, 2, 200));
$packer->addItem(new ArtatusItem('Item 3', 250, 250, 2, 200));
$packedBoxes = $packer->pack();
echo "These items fitted into " . count($packedBoxes) . " box(es)" . PHP_EOL;
foreach ($packedBoxes as $packedBox) {
    $boxType = $packedBox->getBox();
    // your own box object, in this case BasicBox
    echo "This box is a {$boxType->getReference()}, it is {$boxType->getOuterWidth()}mm wide, {$boxType->getOuterLength()}mm long and {$boxType->getOuterDepth()}mm high" . PHP_EOL;
    echo "The combined weight of this box and the items inside it is {$packedBox->getWeight()}g" . PHP_EOL;
    echo "The items in this box are:" . PHP_EOL;
    $itemsInTheBox = $packedBox->getItems();
    foreach ($itemsInTheBox as $item) {
        // your own item object, in this case BasicItem
        echo $item->getDescription() . PHP_EOL;
    }
    echo PHP_EOL;
}
/*
 * To just see if a selection of items will fit into one specific box
 */
$box = new ArtatusBox('Le box', 300, 300, 10, 10, 296, 296, 8, 1000);
$items = new ArtatusItemList();
$items->insert(new ArtatusItem('Item 1', 297, 296, 2, 200));
$items->insert(new ArtatusItem('Item 2', 297, 296, 2, 500));
$items->insert(new ArtatusItem('Item 3', 296, 296, 4, 290));
$packer = new ArtatusPacker();
$packedBox = $packer->packIntoBox($box, $items);
/* $packedBox->getItems() contains the items that fit */