/**
* @file
* Functions to automatically generate constraints for the
* rectangular node overlap removal problem.
*/
/*
*
* Authors:
* Tim Dwyer <tgdwyer@gmail.com>
*
* Copyright (C) 2005 Authors
*
* Released under GNU LGPL. Read the file 'COPYING' for more information.
*/
#include <set>
#include <cassert>
#include <cstdlib>
#include "generate-constraints.h"
#include "constraint.h"
namespace vpsc {
return os;
}
assert(x<=X);
assert(y<=Y);
}
struct Node;
struct Node {
Variable *v;
Rectangle *r;
double pos;
}
~Node() {
delete leftNeighbours;
delete rightNeighbours;
}
leftNeighbours->insert(u);
}
rightNeighbours->insert(u);
}
Node *v=*(i);
v->addRightNeighbour(this);
}
Node *v=*(i);
v->addLeftNeighbour(this);
}
}
};
return true;
}
return false;
}
}
return u < v;
/* I don't know how important it is to handle NaN correctly
* (e.g. we probably handle it badly in other code anyway, and
* in any case the best we can hope for is to reduce the
* badness of other nodes).
*
* Nevertheless, we try to do the right thing here and in
* event comparison. The issue is that (on platforms with
* ieee floating point comparison) NaN compares neither less
* than nor greater than any other number, yet sort wants a
* well-defined ordering. In particular, we want to ensure
* transitivity of equivalence, which normally wouldn't be
* guaranteed if the "middle" item in the transitivity
* involves a NaN. (NaN is neither less than nor greater than
* other numbers, so tends to be considered as equal to all
* other numbers: even unequal numbers.)
*/
}
Node *u=*(i);
if(u->r->overlapX(v->r)<=0) {
return leftv;
}
}
}
return leftv;
}
Node *u=*(i);
if(u->r->overlapX(v->r)<=0) {
return rightv;
}
}
}
return rightv;
}
struct Event {
Node *v;
double pos;
};
static int compare_events(const void *a, const void *b) {
// when comparing opening and closing from the same rect
// open must come first
return 1;
return 1;
return -1;
/* See comment in CmpNodePos. */
? -1
: 1 );
}
return 0;
}
/**
* Prepares constraints in order to apply VPSC horizontally. Assumes variables have already been created.
* useNeighbourLists determines whether or not a heuristic is used to deciding whether to resolve
* all overlap in the x pass, or leave some overlaps for the y pass.
*/
int generateXConstraints(const int n, Rectangle** rs, Variable** vars, Constraint** &cs, const bool useNeighbourLists) {
int i,m,ctr=0;
for(i=0;i<n;i++) {
}
for(i=0;i<2*n;i++) {
Node *v=e->v;
if(useNeighbourLists) {
v->setNeighbours(
);
} else {
v->firstAbove=u;
u->firstBelow=v;
}
v->firstBelow=u;
u->firstAbove=v;
}
}
} else {
// Close event
if(useNeighbourLists) {
i!=v->leftNeighbours->end();i++
) {
Node *u=*i;
u->rightNeighbours->erase(v);
}
i!=v->rightNeighbours->end();i++
) {
Node *u=*i;
u->leftNeighbours->erase(v);
}
} else {
if(l!=NULL) {
l->firstBelow = v->firstBelow;
}
if(r!=NULL) {
r->firstAbove = v->firstAbove;
}
}
delete v;
}
delete e;
}
delete [] events;
for(i=0;i<m;i++) cs[i]=constraints[i];
return m;
}
/**
* Prepares constraints in order to apply VPSC vertically to remove ALL overlap.
*/
int ctr=0,i,m;
for(i=0;i<n;i++) {
}
for(i=0;i<2*n;i++) {
Node *v=e->v;
Node *u=*i;
v->firstAbove=u;
u->firstBelow=v;
}
Node *u=*i;
v->firstBelow=u;
u->firstAbove=v;
}
} else {
// Close event
if(l!=NULL) {
l->firstBelow=v->firstBelow;
}
if(r!=NULL) {
r->firstAbove=v->firstAbove;
}
delete v;
}
delete e;
}
delete [] events;
for(i=0;i<m;i++) cs[i]=constraints[i];
return m;
}
}