bpackscenes.C
#include <stream.h>
#include <strings.h>
#include "../polka.H"
#include "bpack.H"
#define BIN_WD 0.6
#define BIN_HT 0.5
MyAnimator bpack;
int
MyAnimator::Controller()
{
if (!strcmp(AlgoEvtName,"Init"))
b.Init(AnimInts[0]);
else if (!strcmp(AlgoEvtName,"NewWeight"))
b.NewWeight(AnimInts[0],AnimDoubles[0]);
else if (!strcmp(AlgoEvtName,"Failure"))
b.MoveTo(AnimInts[0],AnimInts[1]);
else if (!strcmp(AlgoEvtName,"Success")) {
b.MoveTo(AnimInts[0],AnimInts[1]);
b.InPlace(AnimInts[0],AnimInts[1]);
}
else
b.CheckInput();
return(1);
}
/* draw the container and set up scaling values for the weights */
int
Blocks::Init(int bins)
{
Loc1Desc line;
int len,d;
Create("First-fit bin packing");
/* draw the bin holding area */
Rectangle *r = new Rectangle(this,1,0.3,0.2,BIN_WD,BIN_HT,"black",0.0);
r->Originate(0);
wid = BIN_WD / bins;
appear = new Loc(0.05,0.2); /* save place for new elt to appear */
line.num = bins+1; // we want them left-adjusted, so need to add one
line.fx = 0.3; line.fy = 0.2;
line.tx = 0.3+BIN_WD; line.ty = 0.2;
line.Make(spots);
/* array of bin locations (where next weight should go) */
Action a("DELAY",5);
len = r->Program(0,&a);
time = Animate(time,len);
return(1);
}
/* have a new weight (with height scaled to value) appear */
int
Blocks::NewWeight(int idnum, double val)
{
double ht,x,y,cx,cy;
char str[5];
Loc *center;
int len;
ht = val * BIN_HT; /* scale how big the rect should be */
x = appear->XCoord();
y = appear->YCoord();
weights[idnum] = new Rectangle(this,1,x,y,wid,ht,"red",0.5);
weights[idnum]->Originate(time);
center = weights[idnum]->Where(PART_C);
cx = center->XCoord();
cy = center->YCoord();
sprintf(str,"%d",idnum);
labels[idnum] = new Text(this,1,cx,cy,"black",NULL,str,1);
labels[idnum]->Originate(time);
Action a("DELAY",1);
len = weights[idnum]->Program(time,&a);
time = Animate(time,len);
return(1);
}
/* move the weight to the corresponding bin position */
int
Blocks::MoveTo(int n, int binnum)
{
int len;
Loc *frompt = weights[n]->Where(PART_SW);
Loc *topt = spots[binnum];
Action a("MOVE",frompt,topt,CLOCKWISE);
len = weights[n]->Program(time,&a);
len = labels[n]->Program(time,&a);
time = Animate(time,len);
delete(frompt);
return(1);
}
/* make the weight move to the given bin, then highlight it to show it */
/* found its place */
int
Blocks::InPlace(int n, int binnum)
{
double x0,y0,x1,y1;
double fval = 1.0;
int len;
Loc *nw = weights[n]->Where(PART_NW); /* put a black outline
around weight */
x0 = nw->XCoord();
y0 = nw->YCoord();
LocPtr se = weights[n]->Where(PART_SE);
x1 = se->XCoord();
y1 = se->YCoord();
Rectangle *r = new Rectangle(this,1,x0,y1,x1-x0,y0-y1,"black",0.0);
r->Originate(time);
Action a("FILL",1,&fval,&fval);
len = weights[n]->Program(time,&a);
time = Animate(time,len);
/* reset this bin's entry position to the top of the weight */
delete(spots[binnum]);
spots[binnum] = nw;
delete(se);
return(1);
}