#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); }