The compiler can still optimize this out, but this way we ensure it always stays
compilable and consistent with the surrounding code.
using std::endl;
using std::vector;
+#ifndef RECTANGLE_OVERLAP_LOGGING
+ #define RECTANGLE_OVERLAP_LOGGING 0
+#endif
+
typedef vector<Constraint*>::iterator Cit;
void Block::addVariable(Variable *v) {
}
}
void Block::merge(Block* b, Constraint* c) {
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<" merging on: "<<*c<<",c->left->offset="<<c->left->offset<<",c->right->offset="<<c->right->offset<<endl;
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<" merging on: "<<*c<<",c->left->offset="<<c->left->offset<<",c->right->offset="<<c->right->offset<<endl;
+ }
double dist = c->right->offset - c->left->offset - c->gap;
Block *l=c->left->block;
Block *r=c->right->block;
} else {
l->merge(r,c,-dist);
}
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<" merged block="<<(b->deleted?*this:*b)<<endl;
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<" merged block="<<(b->deleted?*this:*b)<<endl;
+ }
}
/**
* Merges b into this block across c. Can be either a
* @param distance separation required to satisfy c
*/
void Block::merge(Block *b, Constraint *c, double dist) {
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<" merging: "<<*b<<"dist="<<dist<<endl;
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<" merging: "<<*b<<"dist="<<dist<<endl;
+ }
c->active=true;
wposn+=b->wposn-dist*b->weight;
weight+=b->weight;
}
void Block::mergeIn(Block *b) {
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<" merging constraint heaps... "<<endl;
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<" merging constraint heaps... "<<endl;
+ }
// We check the top of the heaps to remove possible internal constraints
findMinInConstraint();
b->findMinInConstraint();
in->merge(b->in);
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<" merged heap: "<<*in<<endl;
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<" merged heap: "<<*in<<endl;
+ }
}
void Block::mergeOut(Block *b) {
findMinOutConstraint();
Block *lb=v->left->block;
Block *rb=v->right->block;
// rb may not be this if called between merge and mergeIn
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<" checking constraint ... "<<*v;
- f<<" timestamps: left="<<lb->timeStamp<<" right="<<rb->timeStamp<<" constraint="<<v->timeStamp<<endl;
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<" checking constraint ... "<<*v;
+ f<<" timestamps: left="<<lb->timeStamp<<" right="<<rb->timeStamp<<" constraint="<<v->timeStamp<<endl;
+ }
if(lb == rb) {
// constraint has been merged into the same block
-#ifdef RECTANGLE_OVERLAP_LOGGING
- if(v->slack()<0) {
+ if(RECTANGLE_OVERLAP_LOGGING && v->slack()<0) {
+ ofstream f(LOGFILE,ios::app);
f<<" violated internal constraint found! "<<*v<<endl;
f<<" lb="<<*lb<<endl;
f<<" rb="<<*rb<<endl;
}
-#endif
in->deleteMin();
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<" ... skipping internal constraint"<<endl;
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<" ... skipping internal constraint"<<endl;
+ }
} else if(v->timeStamp < lb->timeStamp) {
// block at other end of constraint has been moved since this
in->deleteMin();
outOfDate.push_back(v);
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<" reinserting out of date (reinsert later)"<<endl;
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<" reinserting out of date (reinsert later)"<<endl;
+ }
} else {
break;
}
}
void Block::deleteMinInConstraint() {
in->deleteMin();
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<"deleteMinInConstraint... "<<endl;
- f<<" result: "<<*in<<endl;
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<"deleteMinInConstraint... "<<endl;
+ f<<" result: "<<*in<<endl;
+ }
}
void Block::deleteMinOutConstraint() {
out->deleteMin();
* Returns the split constraint
*/
Constraint* Block::splitBetween(Variable* vl, Variable* vr, Block* &lb, Block* &rb) {
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<" need to split between: "<<*vl<<" and "<<*vr<<endl;
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<" need to split between: "<<*vl<<" and "<<*vr<<endl;
+ }
Constraint *c=findMinLMBetween(vl, vr);
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<" going to split on: "<<*c<<endl;
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<" going to split on: "<<*c<<endl;
+ }
split(lb,rb,c);
deleted = true;
return c;
using std::list;
using std::copy;
+#ifndef RECTANGLE_OVERLAP_LOGGING
+ #define RECTANGLE_OVERLAP_LOGGING 0
+#endif
+
long blockTimeCtr;
Blocks::Blocks(const int n, Variable *vs[]) : vs(vs),nvs(n) {
dfsVisit(c->right, order);
}
}
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<" order="<<*v<<endl;
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<" order="<<*v<<endl;
+ }
order->push_front(v);
}
/**
* neighbouring (left) block until no more violated constraints are found
*/
void Blocks::mergeLeft(Block *r) {
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<"mergeLeft called on "<<*r<<endl;
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<"mergeLeft called on "<<*r<<endl;
+ }
r->timeStamp=++blockTimeCtr;
r->setUpInConstraints();
Constraint *c=r->findMinInConstraint();
while (c != NULL && c->slack()<0) {
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<"mergeLeft on constraint: "<<*c<<endl;
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<"mergeLeft on constraint: "<<*c<<endl;
+ }
r->deleteMinInConstraint();
Block *l = c->left->block;
if (l->in==NULL) l->setUpInConstraints();
removeBlock(l);
c=r->findMinInConstraint();
}
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<"merged "<<*r<<endl;
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<"merged "<<*r<<endl;
+ }
}
/**
* Symmetrical to mergeLeft
*/
void Blocks::mergeRight(Block *l) {
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<"mergeRight called on "<<*l<<endl;
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<"mergeRight called on "<<*l<<endl;
+ }
l->setUpOutConstraints();
Constraint *c = l->findMinOutConstraint();
while (c != NULL && c->slack()<0) {
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<"mergeRight on constraint: "<<*c<<endl;
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<"mergeRight on constraint: "<<*c<<endl;
+ }
l->deleteMinOutConstraint();
Block *r = c->right->block;
r->setUpOutConstraints();
removeBlock(r);
c=l->findMinOutConstraint();
}
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<"merged "<<*l<<endl;
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<"merged "<<*l<<endl;
+ }
}
void Blocks::removeBlock(Block *doomed) {
doomed->deleted=true;
*/
void Blocks::split(Block *b, Block *&l, Block *&r, Constraint *c) {
b->split(l,r,c);
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<"Split left: "<<*l<<endl;
- f<<"Split right: "<<*r<<endl;
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<"Split left: "<<*l<<endl;
+ f<<"Split right: "<<*r<<endl;
+ }
r->posn = b->posn;
r->wposn = r->posn * r->weight;
mergeLeft(l);
#ifndef SEEN_REMOVEOVERLAP_BLOCKS_H
#define SEEN_REMOVEOVERLAP_BLOCKS_H
-#ifdef RECTANGLE_OVERLAP_LOGGING
#define LOGFILE "cRectangleOverlap.log"
-#endif
#include <set>
#include <list>
using std::ofstream;
using std::endl;
+#ifndef RECTANGLE_OVERLAP_LOGGING
+ #define RECTANGLE_OVERLAP_LOGGING 0
+#endif
+
#define EXTRA_GAP 0.0001
double Rectangle::xBorder=0;
oldX[i]=vs[i]->desiredPosition;
}
VPSC vpsc_x(n,vs,m,cs);
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<"Calling VPSC: Horizontal pass 1"<<endl;
- f.close();
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<"Calling VPSC: Horizontal pass 1"<<endl;
+ }
vpsc_x.solve();
for(int i=0;i<n;i++) {
rs[i]->moveCentreX(vs[i]->position());
Rectangle::setXBorder(Rectangle::xBorder-EXTRA_GAP);
m=generateYConstraints(n,rs,vs,cs);
VPSC vpsc_y(n,vs,m,cs);
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f.open(LOGFILE,ios::app);
- f<<"Calling VPSC: Vertical pass"<<endl;
- f.close();
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<"Calling VPSC: Vertical pass"<<endl;
+ }
vpsc_y.solve();
for(int i=0;i<n;i++) {
rs[i]->moveCentreY(vs[i]->position());
Rectangle::setYBorder(Rectangle::yBorder-EXTRA_GAP);
m=generateXConstraints(n,rs,vs,cs,false);
VPSC vpsc_x2(n,vs,m,cs);
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f.open(LOGFILE,ios::app);
- f<<"Calling VPSC: Horizontal pass 2"<<endl;
- f.close();
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<"Calling VPSC: Horizontal pass 2"<<endl;
+ }
vpsc_x2.solve();
for(int i=0;i<n;i++) {
rs[i]->moveCentreX(vs[i]->position());
using std::list;
using std::set;
+#ifndef RECTANGLE_OVERLAP_LOGGING
+ #define RECTANGLE_OVERLAP_LOGGING 0
+#endif
+
IncVPSC::IncVPSC(const unsigned n, Variable *vs[], const unsigned m, Constraint *cs[])
: VPSC(n,vs,m,cs) {
inactive.assign(cs,cs+m);
}
VPSC::VPSC(const unsigned n, Variable *vs[], const unsigned m, Constraint *cs[]) : cs(cs), m(m) {
bs=new Blocks(n, vs);
-#ifdef RECTANGLE_OVERLAP_LOGGING
- printBlocks();
- assert(!constraintGraphIsCyclic(n,vs));
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ printBlocks();
+ assert(!constraintGraphIsCyclic(n,vs));
+ }
}
VPSC::~VPSC() {
delete bs;
// useful in debugging
void VPSC::printBlocks() {
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- for(set<Block*>::iterator i=bs->begin();i!=bs->end();i++) {
- Block *b=*i;
- f<<" "<<*b<<endl;
- }
- for(unsigned i=0;i<m;i++) {
- f<<" "<<*cs[i]<<endl;
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ for(set<Block*>::iterator i=bs->begin();i!=bs->end();i++) {
+ Block *b=*i;
+ f<<" "<<*b<<endl;
+ }
+ for(unsigned i=0;i<m;i++) {
+ f<<" "<<*cs[i]<<endl;
+ }
}
-#endif
}
/**
* Produces a feasible - though not necessarily optimal - solution by
bs->cleanup();
for(unsigned i=0;i<m;i++) {
if(cs[i]->slack()<-0.0000001) {
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<"Error: Unsatisfied constraint: "<<*cs[i]<<endl;
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<"Error: Unsatisfied constraint: "<<*cs[i]<<endl;
+ }
//assert(cs[i]->slack()>-0.0000001);
throw "Unsatisfied constraint";
}
Block *b=*i;
Constraint *c=b->findMinLM();
if(c!=NULL && c->lm<0) {
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<"Split on constraint: "<<*c<<endl;
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<"Split on constraint: "<<*c<<endl;
+ }
// Split on c
Block *l=NULL, *r=NULL;
bs->split(b,l,r,c);
}
void IncVPSC::solve() {
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<"solve_inc()..."<<endl;
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<"solve_inc()..."<<endl;
+ }
double lastcost,cost = bs->cost();
do {
lastcost=cost;
satisfy();
splitBlocks();
cost = bs->cost();
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<" cost="<<cost<<endl;
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<" cost="<<cost<<endl;
+ }
} while(fabs(lastcost-cost)>0.0001);
}
/**
* constraint with the most negative lagrangian multiplier.
*/
void IncVPSC::satisfy() {
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<"satisfy_inc()..."<<endl;
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<"satisfy_inc()..."<<endl;
+ }
splitBlocks();
long splitCtr = 0;
Constraint* v = NULL;
bs->insert(lb);
}
}
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<" finished merges."<<endl;
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<" finished merges."<<endl;
+ }
bs->cleanup();
for(unsigned i=0;i<m;i++) {
v=cs[i];
throw s.str().c_str();
}
}
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<" finished cleanup."<<endl;
- printBlocks();
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<" finished cleanup."<<endl;
+ printBlocks();
+ }
}
void IncVPSC::moveBlocks() {
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<"moveBlocks()..."<<endl;
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<"moveBlocks()..."<<endl;
+ }
for(set<Block*>::const_iterator i(bs->begin());i!=bs->end();i++) {
Block *b = *i;
b->wposn = b->desiredWeightedPosition();
b->posn = b->wposn / b->weight;
}
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<" moved blocks."<<endl;
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<" moved blocks."<<endl;
+ }
}
void IncVPSC::splitBlocks() {
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
-#endif
moveBlocks();
splitCnt=0;
// Split each block if necessary on min LM
Block* b = *i;
Constraint* v=b->findMinLM();
if(v!=NULL && v->lm < -0.0000001) {
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<" found split point: "<<*v<<" lm="<<v->lm<<endl;
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<" found split point: "<<*v<<" lm="<<v->lm<<endl;
+ }
splitCnt++;
Block *b = v->left->block, *l=NULL, *r=NULL;
assert(v->left->block == v->right->block);
bs->insert(r);
b->deleted=true;
inactive.push_back(v);
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<" new blocks: "<<*l<<" and "<<*r<<endl;
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<" new blocks: "<<*l<<" and "<<*r<<endl;
+ }
}
}
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<" finished splits."<<endl;
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<" finished splits."<<endl;
+ }
bs->cleanup();
}
*/
double IncVPSC::mostViolated(ConstraintList &l, Constraint* &v) {
double minSlack = DBL_MAX;
-#ifdef RECTANGLE_OVERLAP_LOGGING
- ofstream f(LOGFILE,ios::app);
- f<<"Looking for most violated..."<<endl;
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<"Looking for most violated..."<<endl;
+ }
ConstraintList::iterator end = l.end();
ConstraintList::iterator deletePoint = end;
for(ConstraintList::iterator i=l.begin();i!=end;i++) {
*deletePoint = l[l.size()-1];
l.resize(l.size()-1);
}
-#ifdef RECTANGLE_OVERLAP_LOGGING
- f<<" most violated is: "<<*v<<endl;
-#endif
+ if (RECTANGLE_OVERLAP_LOGGING) {
+ ofstream f(LOGFILE,ios::app);
+ f<<" most violated is: "<<*v<<endl;
+ }
return minSlack;
}