 Application Center - Maplesoft

# Stacking Patterns for Boxes within a Volume

You can switch back to the summary page by clicking here. Loading Patterns of Boxes Within a Volume

Lee R. Partin

23 December 2007

lpartin@chartertn.net

Copyright 2007, L R Partin

The model calculates potential loading patterns of boxes within a volume (a larger box).  It places the boxes within a given orderly pattern for the main filling of the volume.  It then tries to place more boxes in the remaining open spaces.  More boxes may be manually added by the user if sufficient free space remains after the automated filling process.  Several orientations are tested.

Restart

Restart the Maple kernel to prepare for the model calculations.

 > restart;

Application Coding

Miscellaneous Code

 > with(plottools): with(StringTools):

Pattern Module

The programming for the box filling pattern calculations is done within a module called Pattern.

 > module Pattern()  description "Calculate filling patterns for boxes within a given volume";  local i;  export Initialize, Stacks, Plot, Coordinates, Add;  Stacks:={};  Initialize:=proc() description "calculate and initialize a pattern object";    local j, makeStack, Pname, xBox, yBox, zBox, xVol, yVol, zVol,      newStack, xCount, yCount, zCount, Count, xOrigin, yOrigin,      zOrigin, test1, test2, test3, name1, name2, name3, name4,      name5, name6,      maxPt0, maxPtx, maxPty, maxPtz, direction,      xExtra, yExtra, zExtra, TrialCount, Trials, maxTrial,      TrialSelect, orient, boxes1, boxes2, boxes3, boxes4,      boxes5, boxes6, StacksL,      FreeSpace1, FreeSpace2;    makeStack:=proc(f::`name`,xBoxi,yBoxi,zBoxi,xVoli,yVoli,zVoli,               xCounti,yCounti,zCounti, Counti, xOrigini,               yOrigini, zOrigini)       description "make a stacking record";       f:=module() export xBox, yBox, zBox, xVol, yVol, zVol,            xCount, yCount, zCount, Count, xOrigin, yOrigin, zOrigin;          xBox:=xBoxi; yBox:=yBoxi; zBox:=zBoxi;          xVol:=xVoli; yVol:=yVoli; zVol:=zVoli;          xCount:=xCounti; yCount:=yCounti; zCount:=zCounti;          Count:=Counti; xOrigin:=xOrigini; yOrigin:=yOrigini;          zOrigin:=zOrigini;       end module;       f;    end proc;    if nargs<>10 then error "Initialize requires 10 arguments." fi;    Pname:=args;    if type(args,`numeric`) then xBox:=args       else error "Initialize argument 2 must be numeric for xBox" fi;    if type(args,`numeric`) then yBox:=args       else error "Initialize argument 3 must be numeric for yBox" fi;    if type(args,`numeric`) then zBox:=args       else error "Initialize argument 4 must be numeric for zBox" fi;    if type(args,`numeric`) then xVol:=args       else error "Initialize argument 5 must be numeric for xVol" fi;    if type(args,`numeric`) then yVol:=args       else error "Initialize argument 6 must be numeric for yVol" fi;    if type(args,`numeric`) then zVol:=args       else error "Initialize argument 7 must be numeric for zVol" fi;    if type(args,`name`) then test1:=args       else error "Initialize argument 8 must be a name (x, y or z) for the direction to first test for additional filling of the volume" fi;    if type(args,`name`) then test2:=args       else error "Initialize argument 9 must be a name (x, y or z) for the direction of the second test for additional filling of the volume" fi;    if type(args,`name`) then test3:=args       else error "Initialize argument 10 must be a name (x, y or z) for the direction of the third test for additional filling of the volume" fi;    if {test1,test2,test3} <> {x,y,z} then error "Initialize arguments 8, 9 and 10 must be x, y and z in any order" fi;    xOrigin:=0; yOrigin:=0; zOrigin:=0; # for initial volume fill    maxPt0:=[0,0,0];    maxPtx:=maxPt0; maxPty:=maxPt0; maxPtz:=maxPt0;    boxes1:=0; boxes2:=0; boxes3:=0; boxes4:=0; boxes5:=0; boxes6:=0;    StacksL:={};    # doing the initial volume filling from origin (0,0,0)    xCount:=trunc(xVol/xBox);    yCount:=trunc(yVol/yBox);    zCount:=trunc(zVol/zBox);    Count:=xCount*yCount*zCount;    boxes1:=Count;    i:=1;    name1:=convert(cat(Pname,"_",i),`name`);    newStack:=makeStack(name1, xBox, yBox, zBox, xVol, yVol,              zVol, xCount, yCount, zCount, Count, xOrigin, yOrigin,              zOrigin);    Stacks:=Stacks minus {newStack};    Stacks:=Stacks union {newStack};    StacksL:={newStack};    maxPt0:=[xCount*xBox, yCount*yBox, zCount*zBox];    printf("Stack Name: %s \n", name1);    printf("Stack Count = %d; %d x %d x %d \n", Count,           xCount, yCount, zCount);    printf("Maximum Point of Stack: x=%g, y=%g, z=%g \n",      xBox*xCount+xOrigin, yBox*yCount+yOrigin,      zBox*zCount+zOrigin);    # do the volume filling for the free volume in the three directions    FreeSpace1:=[0,0,0]; FreeSpace2:=[0,0,0];    for direction in [test1, test2, test3] do      if (direction=x and maxPt0maxPt0 then zExtra:=maxPt0        else zExtra:=zVol  fi;        if maxPty>maxPt0 then yExtra:=yVol-maxPty        else yExtra:=yVol  fi;        # find which way to orient the box to get the most to fit        j:=0;        maxTrial:=0;        TrialSelect:=0;        for orient in combinat[permute]([xBox,yBox,zBox]) do          j:=j+1;          TrialCount:=trunc(xExtra/orient)*trunc(yExtra/orient)               *trunc(zExtra/orient);          Trials[j]:=[orient,orient,orient,TrialCount];          if TrialCount>maxTrial then             TrialSelect:=j;             maxTrial:=TrialCount;          fi;           end do;        # create the new collection of boxes within the volume        if TrialSelect>0 then          xCount:=trunc(xExtra/Trials[TrialSelect]);          yCount:=trunc(yExtra/Trials[TrialSelect]);          zCount:=trunc(zExtra/Trials[TrialSelect]);          FreeSpace1:=xExtra-xCount*Trials[TrialSelect];          FreeSpace1:=yExtra-yCount*Trials[TrialSelect];          FreeSpace1:=zExtra-zCount*Trials[TrialSelect];          Count:=xCount*yCount*zCount;          boxes2:=Count;          i:=i+1;          name2:=convert(cat(Pname,"_",i),`name`);          maxPtx:=[xCount*Trials[TrialSelect],                   yCount*Trials[TrialSelect],                   zCount*Trials[TrialSelect]];          newStack:=makeStack(name2, Trials[TrialSelect],            Trials[TrialSelect], Trials[TrialSelect],            xVol, yVol, zVol, xCount, yCount, zCount,            Count, xVol-maxPtx, 0, 0);          Stacks:=Stacks minus {newStack};          Stacks:=Stacks union {newStack};          StacksL:=StacksL union {newStack};          printf("Stack Name: %s \n", name2);          printf("Stack Count = %d; %d x %d x %d \n", Count,                 xCount, yCount, zCount);        else          printf("no boxes fit in the space \n")        fi;         # try fitting more boxes into the space next to the boxes just entered into the volume        if FreeSpace1>=min(xBox,yBox,zBox) then          yExtra:=FreeSpace1;          # find which way to orient the box to get the most to fit          j:=0;          maxTrial:=0;          TrialSelect:=0;          for orient in combinat[permute]([xBox,yBox,zBox]) do            j:=j+1;            TrialCount:=trunc(xExtra/orient)               *trunc(yExtra/orient)               *trunc(zExtra/orient);            Trials[j]:=[orient,orient,orient,TrialCount];            if TrialCount>maxTrial then               TrialSelect:=j;               maxTrial:=TrialCount;            fi;             end do;          # create the new collection of boxes within the volume          if TrialSelect>0 then            xCount:=trunc(xExtra/Trials[TrialSelect]);            yCount:=trunc(yExtra/Trials[TrialSelect]);            zCount:=trunc(zExtra/Trials[TrialSelect]);            Count:=xCount*yCount*zCount;            boxes6:=Count;            i:=i+1;            name6:=convert(cat(Pname,"_",i),`name`);            maxPtx:=[xCount*Trials[TrialSelect],                     maxPtx+yCount*Trials[TrialSelect],                     zCount*Trials[TrialSelect]];            newStack:=makeStack(name6, Trials[TrialSelect],               Trials[TrialSelect], Trials[TrialSelect],               xVol, yVol, zVol, xCount, yCount, zCount,               Count, xVol-maxPtx,               maxPtx-yCount*Trials[TrialSelect], 0);            Stacks:=Stacks minus {newStack};            Stacks:=Stacks union {newStack};            StacksL:=StacksL union {newStack};            printf("Stack Name: %s \n", name6);            printf("Stack Count = %d; %d x %d x %d \n", Count,                   xCount, yCount, zCount);          fi;        fi;      fi;      if (direction=y and maxPt0maxPt0 then zExtra:=maxPt0        else zExtra:=zVol  fi;        if maxPtx>maxPt0 then xExtra:=xVol-maxPtx        else xExtra:=xVol  fi;        # find which way to orient the box to get the most to fit        j:=0;        maxTrial:=0;        TrialSelect:=0;        for orient in combinat[permute]([xBox,yBox,zBox]) do          j:=j+1;          TrialCount:=trunc(xExtra/orient)*trunc(yExtra/orient)               *trunc(zExtra/orient);          Trials[j]:=[orient,orient,orient,TrialCount];          if TrialCount>maxTrial then             TrialSelect:=j;             maxTrial:=TrialCount;          fi;           end do;        # create the new collection of boxes within the volume        if TrialSelect>0 then          xCount:=trunc(xExtra/Trials[TrialSelect]);          yCount:=trunc(yExtra/Trials[TrialSelect]);          zCount:=trunc(zExtra/Trials[TrialSelect]);          FreeSpace2:=xExtra-xCount*Trials[TrialSelect];          FreeSpace2:=yExtra-yCount*Trials[TrialSelect];          FreeSpace2:=zExtra-zCount*Trials[TrialSelect];          Count:=xCount*yCount*zCount;          boxes3:=Count;          i:=i+1;          name3:=convert(cat(Pname,"_",i),`name`);          maxPty:=[xCount*Trials[TrialSelect],                   yCount*Trials[TrialSelect],                   zCount*Trials[TrialSelect]];          newStack:=makeStack(name3, Trials[TrialSelect],            Trials[TrialSelect], Trials[TrialSelect],            xVol, yVol, zVol, xCount, yCount, zCount,            Count, 0, yVol-maxPty, 0);          Stacks:=Stacks minus {newStack};          Stacks:=Stacks union {newStack};          StacksL:=StacksL union {newStack};          printf("Stack Name: %s \n", name3);          printf("Stack Count = %d; %d x %d x %d \n", Count,                 xCount, yCount, zCount);        else          printf("no boxes fit in the space \n")        fi;        # try fitting more boxes into the space next to the boxes just entered into the volume        if FreeSpace2>=min(xBox,yBox,zBox) then          xExtra:=FreeSpace2;          # find which way to orient the box to get the most to fit          j:=0;          maxTrial:=0;          TrialSelect:=0;          for orient in combinat[permute]([xBox,yBox,zBox]) do            j:=j+1;            TrialCount:=trunc(xExtra/orient)               *trunc(yExtra/orient)               *trunc(zExtra/orient);            Trials[j]:=[orient,orient,orient,TrialCount];            if TrialCount>maxTrial then               TrialSelect:=j;               maxTrial:=TrialCount;            fi;             end do;          # create the new collection of boxes within the volume          if TrialSelect>0 then            xCount:=trunc(xExtra/Trials[TrialSelect]);            yCount:=trunc(yExtra/Trials[TrialSelect]);            zCount:=trunc(zExtra/Trials[TrialSelect]);            Count:=xCount*yCount*zCount;            boxes5:=Count;            i:=i+1;            name5:=convert(cat(Pname,"_",i),`name`);            maxPty:=[maxPty+xCount*Trials[TrialSelect],                     yCount*Trials[TrialSelect],                     zCount*Trials[TrialSelect]];            newStack:=makeStack(name5, Trials[TrialSelect],               Trials[TrialSelect], Trials[TrialSelect],               xVol, yVol, zVol, xCount, yCount, zCount,               Count, maxPty-xCount*Trials[TrialSelect],               yVol-maxPty, 0);            Stacks:=Stacks minus {newStack};            Stacks:=Stacks union {newStack};            StacksL:=StacksL union {newStack};            printf("Stack Name: %s \n", name5);            printf("Stack Count = %d; %d x %d x %d \n", Count,                   xCount, yCount, zCount);          fi;        fi;         fi;      if (direction=z and maxPt0maxPt0 then xExtra:= xVol-maxPtx        else xExtra:=xVol  fi;        if maxPty>maxPt0 then yExtra:=yVol-maxPty        else yExtra:=yVol  fi;        # find which way to orient the box to get the most to fit        j:=0;        maxTrial:=0;        TrialSelect:=0;        for orient in combinat[permute]([xBox,yBox,zBox]) do          j:=j+1;          TrialCount:=trunc(xExtra/orient)*trunc(yExtra/orient)               *trunc(zExtra/orient);          Trials[j]:=[orient,orient,orient,TrialCount];          if TrialCount>maxTrial then             TrialSelect:=j;             maxTrial:=TrialCount;          fi;           end do;        # create the new collection of boxes within the volume        if TrialSelect>0 then          xCount:=trunc(xExtra/Trials[TrialSelect]);          yCount:=trunc(yExtra/Trials[TrialSelect]);          zCount:=trunc(zExtra/Trials[TrialSelect]);          Count:=xCount*yCount*zCount;          boxes4:=Count;          i:=i+1;          name4:=convert(cat(Pname,"_",i),`name`);          newStack:=makeStack(name4, Trials[TrialSelect],            Trials[TrialSelect], Trials[TrialSelect],            xVol, yVol, zVol, xCount, yCount, zCount,            Count, 0, 0, maxPt0);          Stacks:=Stacks minus {newStack};          Stacks:=Stacks union {newStack};          StacksL:=StacksL union {newStack};          maxPtz:=[xCount*Trials[TrialSelect],                   yCount*Trials[TrialSelect],                   zCount*Trials[TrialSelect]];          printf("Stack Name: %s \n", name4);          printf("Stack Count = %d; %d x %d x %d \n", Count,                 xCount, yCount, zCount);        else          printf("no boxes fit in the space \n")        fi;      fi;    end do;              RETURN([sort(convert(StacksL,list)),            boxes1+boxes2+boxes3+boxes4+boxes5+boxes6]);  end proc;  Plot:=proc(Pvals::list)    description "create a 3D plot of the box patterns";      local i,i1,i2,i3,P,l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12,          x1,y1,z1,x2,y2,z2;    P:=Pvals;    if member(P,Stacks)=false then error "the first entry in the list has not been defined as a pattern" fi;    l1:=line([0,0,0],[P:-xVol,0,0],color=red);    l2:=line([P:-xVol,0,0],[P:-xVol,P:-yVol,0],color=red);    l3:=line([P:-xVol,P:-yVol,0],[0,P:-yVol,0],color=red);    l4:=line([0,P:-yVol,0],[0,0,0],color=red);    l5:=line([0,0,P:-zVol],[P:-xVol,0,P:-zVol],color=red);    l6:=line([P:-xVol,0,P:-zVol],[P:-xVol,P:-yVol,P:-zVol]             ,color=red);    l7:=line([P:-xVol,P:-yVol,P:-zVol],[0,P:-yVol,P:-zVol]             ,color=red);    l8:=line([0,P:-yVol,P:-zVol],[0,0,P:-zVol],color=red);    l9:=line([0,0,0],[0,0,P:-zVol],color=red);    l10:=line([P:-xVol,0,0],[P:-xVol,0,P:-zVol],color=red);    l11:=line([P:-xVol,P:-yVol,0],[P:-xVol,P:-yVol,P:-zVol]              ,color=red);    l12:=line([0,P:-yVol,0],[0,P:-yVol,P:-zVol],color=red);    i:=0;    for P in Pvals do         for i1 from 0 to P:-xCount-1 do      for i2 from 0 to P:-yCount-1 do       for i3 from 0 to P:-zCount-1 do        x1:=P:-xOrigin + i1*P:-xBox;        y1:=P:-yOrigin + i2*P:-yBox;        z1:=P:-zOrigin + i3*P:-zBox;        x2:=x1 + P:-xBox;        y2:=y1 + P:-yBox;        z2:=z1 + P:-zBox;        i:=i+1;        c||i:=cuboid([x1,y1,z1],[x2,y2,z2]);       end do;      end do;     end do;    end do;    plots[display]([seq(c||j,j=1..i),        l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12],        title="Box Patterns", scaling=constrained,        style=PATCH, axes=NORMAL);    end proc;  Coordinates:=proc()    description "return the starting and ending coordinates of a pattern";    local Pname, Start, Finish;    if nargs<>1 then error "Coordinate requires one argument." fi;    Pname:=args;    if member(Pname,Stacks)=false then       error("the first argument must be a name from existing patterns.")    fi;    Start:=[Pname:-xOrigin,Pname:-yOrigin,Pname:-zOrigin];    Finish:=[Start+Pname:-xCount*Pname:-xBox,             Start+Pname:-yCount*Pname:-yBox,             Start+Pname:-zCount*Pname:-zBox];    RETURN([Pname,Start,Finish]);      end proc;  Add:=proc()    description "add a new box filling pattern";    local i, j, Pname, Start, Finish, bases, nextItem, firstItem,          items, maxTrial, TrialSelect, orient, TrialCount, Trials,          xCount, yCount, zCount, Count, newStack, StacksL,          xExtra, yExtra, zExtra, BoxSum, makeStack;    makeStack:=proc(f::`name`,xBoxi,yBoxi,zBoxi,xVoli,yVoli,zVoli,               xCounti,yCounti,zCounti, Counti, xOrigini,               yOrigini, zOrigini)       description "make a stacking record";       f:=module() export xBox, yBox, zBox, xVol, yVol, zVol,            xCount, yCount, zCount, Count, xOrigin, yOrigin, zOrigin;          xBox:=xBoxi; yBox:=yBoxi; zBox:=zBoxi;          xVol:=xVoli; yVol:=yVoli; zVol:=zVoli;          xCount:=xCounti; yCount:=yCounti; zCount:=zCounti;          Count:=Counti; xOrigin:=xOrigini; yOrigin:=yOrigini;          zOrigin:=zOrigini;       end module;       f;    end proc;    if nargs<>3 then error "Add requires 3 arguments." fi;    Pname:=args;    # find base names in Patterns    bases:=[seq(StringTools:-SubString(convert(Stacks[i],`string`),       1..StringTools:-FirstFromLeft("_",convert(Stacks[i],       `string`))-1), i=1..nops(Stacks))];    if member(convert(Pname,`string`),bases)=false then       error "the first argument is not a base name of the existing patterns"    fi;    j:=0;    for i from 1 to nops(bases) do        if bases[i]=convert(Pname,`string`) then j:=j+1 fi;    end do;    items:=j+1;    firstItem:=convert(cat(convert(Pname,`string`),"_",1),`name`);    nextItem:=convert(cat(convert(Pname,`string`),"_",items),`name`);    if type(args,`list`) then Start:=args    else  error "the second argument must be a list for starting coordinate ([x,y,z])."    fi;    if type(args,`list`) then Finish:=args    else  error "the third argument must be a list for ending coordinate ([x,y,z])."    fi;    if StartmaxTrial then             TrialSelect:=j;             maxTrial:=TrialCount;          fi;           end do;        # create the new collection of boxes within the volume        if TrialSelect>0 then          xCount:=trunc(xExtra/Trials[TrialSelect]);          yCount:=trunc(yExtra/Trials[TrialSelect]);          zCount:=trunc(zExtra/Trials[TrialSelect]);          Count:=xCount*yCount*zCount;          i:=i+1;          newStack:=makeStack(nextItem, Trials[TrialSelect],            Trials[TrialSelect], Trials[TrialSelect],            firstItem:-xVol, firstItem:-yVol,            firstItem:-zVol, xCount, yCount, zCount,            Count, Start, Start, Start);          Stacks:=Stacks minus {newStack};          Stacks:=Stacks union {newStack};          printf("Stack Name: %s \n", nextItem);          printf("Stack Count = %d; %d x %d x %d \n", Count,                 xCount, yCount, zCount);        else          printf("no boxes fit in the space \n");          items:=items-1;        fi;    else        error "Start [x,y,z] must be larger than Ending [x,y,z]"    fi;    StacksL:=[seq(convert(cat(convert(Pname,`string`),"_",i),`name`)              ,i=1..items)];    BoxSum:=add(StacksL[i]:-Count,i=1..nops(StacksL));    RETURN([StacksL,BoxSum]);  end proc;    end module;      (2.2.1)

Application of Model

Data / Dimensions

The length, width and height of the box and the fill volume are required.  The orientation of the fill volume remains fixed for the calculations.  The boxes are assumed to lay flat on one of the sides.  They are packed within the volume in orderly structures.

 > BoxLength1:=1: BoxLength2:=2: BoxLength3:=3: VolLength1:=11: VolLength2:=13: VolLength3:=14:

Packing Calculations

Upper Bound on Boxes within the Volume

The upper bound on the amount of boxes that will fit into the volume is calculated by a simple ratio of their volumes.

 > Volume:=VolLength1*VolLength2*VolLength3; BoxVolume:=BoxLength1*BoxLength2*BoxLength3; MaximumBoxes:=trunc(Volume/BoxVolume);   (3.2.1.1)

Trial Packing Patterns

The packing patterns are calculated 6 times since there are six potential orientations of the box for the initial packing structure.  Most of the boxes are placed in the initial orientation.  The program then tries to fit more boxes with the extra x-axis space.  Next, it tries to fit more boxes within the extra y-axis space.  Finally, it tries to fit more boxes into the extra z-axis space.

The Initialize routine of the Pattern module has 10 arguments:

arg = name for the series of pattern fits to the volume

arg = box length along the x-axis dimension

arg = box length along the y-axis dimension

arg = box length along the z-axis dimension

arg = volume x dimension

arg = volume y dimension

arg = volume z dimension

arg = x, y or z to set which extra space to 1st try fitting extra boxes

arg = x, y or z to set which extra space to 2nd try fitting extra boxes
arg = x, y or z to set which extra space to 3rd try fitting extra boxes

The resulting box loading patterns and the total number of boxes loaded are stored within the Result variable.

 > Result:=Pattern:-Initialize(P1,BoxLength1,BoxLength2,   BoxLength3,VolLength1,VolLength2,VolLength3,x,y,z); Result:=Pattern:-Initialize(P2,BoxLength2,BoxLength1,   BoxLength3,VolLength1,VolLength2,VolLength3,x,y,z); Result:=Pattern:-Initialize(P3,BoxLength1,BoxLength3,   BoxLength2,VolLength1,VolLength2,VolLength3,x,y,z); Result:=Pattern:-Initialize(P4,BoxLength3,BoxLength2,   BoxLength1,VolLength1,VolLength2,VolLength3,x,y,z); Result:=Pattern:-Initialize(P5,BoxLength2,BoxLength3,   BoxLength1,VolLength1,VolLength2,VolLength3,x,y,z); Result:=Pattern:-Initialize(P6,BoxLength3,BoxLength1,   BoxLength2,VolLength1,VolLength2,VolLength3,x,y,z);

 Stack Name: P1_1 Stack Count = 264; 11 x 6 x 4 Maximum Point of Stack: x=11, y=12, z=12 filling the extra y-space

 Stack Name: P1_2 Stack Count = 21; 3 x 1 x 7 Stack Name: P1_3 Stack Count = 4; 1 x 1 x 4 filling the extra z-space Stack Name: P1_4 Stack Count = 44; 11 x 4 x 1 Stack Name: P2_1 Stack Count = 260; 5 x 13 x 4 Maximum Point of Stack: x=10, y=13, z=12 filling the extra x-space Stack Name: P2_2 Stack Count = 28; 1 x 4 x 7 filling the extra z-space Stack Name: P2_3 Stack Count = 40; 5 x 4 x 2 Stack Name: P3_1 Stack Count = 308; 11 x 4 x 7 Maximum Point of Stack: x=11, y=12, z=14 filling the extra y-space Stack Name: P3_2 Stack Count = 21; 3 x 1 x 7 Stack Name: P3_3 Stack Count = 4; 1 x 1 x 4 Stack Name: P4_1 Stack Count = 252; 3 x 6 x 14 Maximum Point of Stack: x=9, y=12, z=14 filling the extra x-space Stack Name: P4_2 Stack Count = 56; 1 x 4 x 14 Stack Name: P4_3 Stack Count = 4; 1 x 1 x 4 filling the extra y-space Stack Name: P4_4 Stack Count = 21; 3 x 1 x 7 Stack Name: P5_1 Stack Count = 280; 5 x 4 x 14 Maximum Point of Stack: x=10, y=12, z=14 filling the extra x-space Stack Name: P5_2 Stack Count = 28; 1 x 4 x 7 filling the extra y-space Stack Name: P5_3 Stack Count = 21; 3 x 1 x 7 Stack Name: P5_4 Stack Count = 4; 1 x 1 x 4 Stack Name: P6_1 Stack Count = 273; 3 x 13 x 7 Maximum Point of Stack: x=9, y=13, z=14 filling the extra x-space Stack Name: P6_2 Stack Count = 56; 2 x 4 x 7 Stack Name: P6_3 Stack Count = 4; 1 x 1 x 4 (3.2.2.1)

Plot a Packing Pattern

The Plot routine of the Pattern module plots the loading patterns that define a given way of filling the volume.  The list of loading patterns for a given volume filling  was returned as the first element in the solution from Pattern:-Initialize.  Enter your desired volume filling  number as the variable i.  It can be 1 through 6.

 > i:=1: cat("Solution ",i); cat(Result[i]," boxes"); Pattern:-Plot(Result[i]);   The first volume filling has 4 different patterns of box placement.  You may view a single box pattern as follows:

 > i:=1:  # volume filling number j:=3:  # box pattern number within the filling Pattern:-Plot([Result[i][j]]); Adding More Boxes to a Pattern

The volume filling routine may not find all of the feasible locations to place boxes.  You may add more box patterns manually through the Add routine.  The Coordinates routine help in determining data needed in the Add routine.  Here is an example.

Result 2 did not fill all of the available space as shown in the plot below.  More boxes may be placed into the volume.

 > i:=2: Pattern:-Plot(Result[i]); The Coordinates routine provides data on the individual box patterns within a Result from above.  It gives the name, starting coordinate [x,y,z] and ending coordinate [x,y,z] for each of the individual patterns.  The starting coordinate is where the first box is placed.  The next boxes are placed at increasing values of [x,y,z].  The ending coordinate is the point in the individual fill volume that is diagonal and furthest from the starting coordinate.

 > for item in Result[i] do   Pattern:-Coordinates(item)  end do;   (3.4.1)

The filling pattern from Result 2 has free volume from [0,12,12] to [11,13,14].  It also has a small cavity from [10,12,0] to [11,13,14] that is not big enough to have more boxes.  A new filling pattern is now added for the free volume.  The Add routine is applied.  It has three arguments:

arg, the base name of the volume filling  (P1, P2, P3, P4, P5 and P6 were used above.  It is one of these values.)
arg, starting coordinate as [x1,y1,z1]  (the first box is placed here with more boxes added in increasing [x,y,z]

directions)

arg, ending coordinate as [x2,y2,z2]  (the ending coordinate defines the volume of the fill box;  therefore, x2>x1,

y2>y1, and z2>z1)

 filling the space Stack Name: P2_4 Stack Count = 3; 3 x 1 x 1 (3.4.2)

Here is a plot of the new set of filling patterns:

 > Pattern:-Plot(NewResult2); >

Legal Notice: The copyright for this application is owned by the author. Neither Maplesoft nor the author are responsible for any errors contained within and are not liable for any damages resulting from the use of this material. This application is intended for non-commercial, non-profit use only. Contact the author for permission if you wish to use this application in for-profit activities. 