11
#include "shortest_paths.h"
12
#include "gradient_projection.h"
13
#include <libvpsc/generate-constraints.h>
14
#include "straightener.h"
17
typedef vector<unsigned> Cluster;
18
typedef vector<Cluster*> Clusters;
21
typedef pair<unsigned, unsigned> Edge;
23
// defines references to three variables for which the goal function
24
// will be altered to prefer points u-b-v are in a linear arrangement
25
// such that b is placed at u+t(v-u).
26
struct LinearConstraint {
27
LinearConstraint(unsigned u, unsigned v, unsigned b, double w,
28
double frac_ub, double frac_bv,
30
: u(u),v(v),b(b),w(w),frac_ub(frac_ub),frac_bv(frac_bv),
38
double uvx = X[v] - X[u],
42
t = uvx * vbx + uvy * vby;
43
t/= uvx * uvx + uvy * uvy;
44
// p is the projection point of b on line uv
45
//double px = scalarProj * uvx + X[u];
46
//double py = scalarProj * uvy + Y[u];
49
double numerator=X[b]-X[u];
50
double denominator=X[v]-X[u];
51
if(fabs(denominator)<0.001) {
52
// if line is close to vertical then use Y coords to compute T
54
denominator=Y[v]-Y[u];
56
if(fabs(denominator)<0.0001) {
59
t=numerator/denominator;
67
//printf("New LC: t=%f\n",t);
74
// 2nd partial derivatives of the goal function
75
// (X[b] - (1-t) X[u] - t X[v])^2
82
// Length of each segment as a fraction of the total edge length
87
typedef vector<LinearConstraint*> LinearConstraints;
89
class TestConvergence {
92
TestConvergence(const double& tolerance = 0.001, const unsigned maxiterations = 1000)
93
: old_stress(DBL_MAX),
95
maxiterations(maxiterations),
97
virtual ~TestConvergence() {}
99
virtual bool operator()(double new_stress, double* X, double* Y) {
100
//std::cout<<"iteration="<<iterations<<", new_stress="<<new_stress<<std::endl;
101
if (old_stress == DBL_MAX) {
102
old_stress = new_stress;
103
if(++iterations>=maxiterations) {;
110
fabs(new_stress - old_stress) / (new_stress + 1e-10) < tolerance
111
|| ++iterations > maxiterations;
112
old_stress = new_stress;
117
unsigned maxiterations;
120
static TestConvergence defaultTest(0.0001,100);
121
class ConstrainedMajorizationLayout {
123
ConstrainedMajorizationLayout(
124
vector<Rectangle*>& rs,
128
TestConvergence& done=defaultTest)
129
: constrainedLayout(false),
131
lapSize(n), lap2(new double*[lapSize]),
132
Q(lap2), Dij(new double*[lapSize]),
138
linearConstraints(NULL),
141
straightenEdges(NULL)
143
assert(rs.size()==n);
144
boundingBoxes = new Rectangle*[rs.size()];
145
copy(rs.begin(),rs.end(),boundingBoxes);
147
double** D=new double*[n];
148
for(unsigned i=0;i<n;i++) {
151
shortest_paths::johnsons(n,D,es,eweights);
152
edge_length = idealLength;
153
// Lij_{i!=j}=1/(Dij^2)
155
for(unsigned i = 0; i<n; i++) {
156
X[i]=rs[i]->getCentreX();
157
Y[i]=rs[i]->getCentreY();
159
lap2[i]=new double[n];
160
Dij[i]=new double[n];
161
for(unsigned j=0;j<n;j++) {
162
double w = edge_length * D[i][j];
165
degree+=lap2[i][j]=w>1e-30?1.f/(w*w):0;
173
void moveBoundingBoxes() {
174
for(unsigned i=0;i<lapSize;i++) {
175
boundingBoxes[i]->moveCentreX(X[i]);
176
boundingBoxes[i]->moveCentreY(Y[i]);
180
void setupConstraints(
181
AlignmentConstraints* acsx, AlignmentConstraints* acsy,
183
PageBoundaryConstraints* pbcx = NULL,
184
PageBoundaryConstraints* pbcy = NULL,
185
SimpleConstraints* scx = NULL,
186
SimpleConstraints* scy = NULL,
188
vector<straightener::Edge*>* straightenEdges = NULL);
190
void addLinearConstraints(LinearConstraints* linearConstraints);
192
void setupDummyVars();
194
~ConstrainedMajorizationLayout() {
196
delete [] boundingBoxes;
198
if(constrainedLayout) {
202
for(unsigned i=0;i<lapSize;i++) {
212
void straighten(vector<straightener::Edge*>&, Dim);
214
bool constrainedLayout;
216
double euclidean_distance(unsigned i, unsigned j) {
218
(X[i] - X[j]) * (X[i] - X[j]) +
219
(Y[i] - Y[j]) * (Y[i] - Y[j]));
221
double compute_stress(double **Dij);
222
void majlayout(double** Dij,GradientProjection* gp, double* coords);
223
void majlayout(double** Dij,GradientProjection* gp, double* coords,
225
unsigned n; // is lapSize + dummyVars
226
unsigned lapSize; // lapSize is the number of variables for actual nodes
227
double** lap2; // graph laplacian
228
double** Q; // quadratic terms matrix used in computations
231
TestConvergence& done;
232
Rectangle** boundingBoxes;
236
LinearConstraints *linearConstraints;
237
GradientProjection *gpX, *gpY;
238
vector<straightener::Edge*>* straightenEdges;
242
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4