summaryrefslogtreecommitdiffstats
path: root/src/libcola/straightener.h
diff options
context:
space:
mode:
authorMarc Jeanmougin <marc.jeanmougin@telecom-paristech.fr>2018-04-29 14:25:32 +0000
committerMarc Jeanmougin <marc.jeanmougin@telecom-paristech.fr>2018-04-29 14:25:32 +0000
commitab5f8ff5869021958f4ae8b838c3d707a2e85eaa (patch)
tree4907675828a5401d013b7587538cc8541edd2764 /src/libcola/straightener.h
parentmoved libcroco, libuemf, libdepixelize to 3rdparty folder (diff)
downloadinkscape-ab5f8ff5869021958f4ae8b838c3d707a2e85eaa.tar.gz
inkscape-ab5f8ff5869021958f4ae8b838c3d707a2e85eaa.zip
Put adaptagrams into its own folder
Diffstat (limited to 'src/libcola/straightener.h')
-rw-r--r--src/libcola/straightener.h389
1 files changed, 0 insertions, 389 deletions
diff --git a/src/libcola/straightener.h b/src/libcola/straightener.h
deleted file mode 100644
index 7112efcad..000000000
--- a/src/libcola/straightener.h
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- * vim: ts=4 sw=4 et tw=0 wm=0
- *
- * libcola - A library providing force-directed network layout using the
- * stress-majorization method subject to separation constraints.
- *
- * Copyright (C) 2006-2008 Monash University
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- * See the file LICENSE.LGPL distributed with the library.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
-*/
-
-#ifndef STRAIGHTENER_H
-#define STRAIGHTENER_H
-
-#include <set>
-#include <cfloat>
-#include <iostream>
-#include <iterator>
-
-#include "libvpsc/rectangle.h"
-#include "libcola/commondefs.h"
-
-namespace cola {
- class Cluster;
- class ConvexCluster;
- class SeparationConstraint;
-}
-namespace straightener {
-
-struct Route {
- Route(unsigned n) : n(n), xs(new double[n]), ys(new double[n]) {}
- ~Route() {
- delete [] xs;
- delete [] ys;
- }
- void print() {
- std::cout << "double xs[]={";
- std::copy(xs,xs+n-1,std::ostream_iterator<double>(std::cout,","));
- std::cout << xs[n-1] << "};" << std::endl << "double ys[]={";
- std::copy(ys,ys+n-1,std::ostream_iterator<double>(std::cout,","));
- std::cout << ys[n-1] << "};" << std::endl;
- }
- void boundingBox(double &xmin,double &ymin,double &xmax,double &ymax) {
- xmin=ymin=DBL_MAX;
- xmax=ymax=-DBL_MAX;
- for(unsigned i=0;i<n;i++) {
- xmin=std::min(xmin,xs[i]);
- xmax=std::max(xmax,xs[i]);
- ymin=std::min(ymin,ys[i]);
- ymax=std::max(ymax,ys[i]);
- }
- }
- double routeLength () const {
- double length=0;
- for(unsigned i=1;i<n;i++) {
- double dx=xs[i-1]-xs[i];
- double dy=ys[i-1]-ys[i];
- length+=sqrt(dx*dx+dy*dy);
- }
- return length;
- }
- void rerouteAround(vpsc::Rectangle *rect);
- unsigned n;
- double *xs;
- double *ys;
-};
-class Node;
-struct DebugPoint {
- double x,y;
-};
-struct DebugLine {
- DebugLine(double x0,double y0,double x1,double y1,unsigned colour)
- : x0(x0),y0(y0),x1(x1),y1(y1),colour(colour) {}
- double x0,y0,x1,y1;
- unsigned colour;
-};
-class ScanObject {
-public:
- const unsigned id;
- double getMin(vpsc::Dim d) const {
- return min[d];
- }
- double getMax(vpsc::Dim d) const {
- return max[d];
- }
- ScanObject(unsigned id) : id(id) {}
-protected:
- double min[2], max[2];
-};
-class Edge : public ScanObject {
-public:
- unsigned openInd; // position in openEdges
- unsigned startNode, endNode;
- double idealLength;
- std::vector<unsigned> dummyNodes;
- std::vector<unsigned> path;
- std::vector<unsigned> activePath;
- std::vector<DebugPoint> debugPoints;
- std::vector<DebugLine> debugLines;
- void print() {
- printf("Edge[%d]=(%d,%d)\n",id,startNode,endNode);
- route->print();
- }
- // if the edge route intersects with any of the rectangles in rects then reroute
- // those parts of the route around the rectangle boundaries
- void rerouteAround(std::vector<vpsc::Rectangle*> const &rects) {
- unsigned rid=0;
- for(std::vector<vpsc::Rectangle*>::const_iterator r=rects.begin();r!=rects.end();r++,rid++) {
- if(rid!=startNode && rid!=endNode) {
- route->rerouteAround(*r);
- }
- }
- updateBoundingBox();
- }
- // Edge with a non-trivial route
- Edge(unsigned id, unsigned start, unsigned end, Route* route)
- : ScanObject(id), startNode(start), endNode(end), route(route)
- {
- updateBoundingBox();
- }
- // Edge with a trivial route
- Edge(unsigned id, unsigned start, unsigned end,
- double x1, double y1, double x2, double y2)
- : ScanObject(id), startNode(start), endNode(end) {
- route = new Route(2);
- route->xs[0]=x1; route->ys[0]=y1;
- route->xs[1]=x2; route->ys[1]=y2;
- updateBoundingBox();
- }
- ~Edge() {
- delete route;
- }
- bool isEnd(unsigned n) const {
- if(startNode==n||endNode==n) return true;
- return false;
- }
- void nodePath(std::vector<Node*>& nodes, bool allActive);
- void createRouteFromPath(std::vector<Node *> const & nodes);
- void xpos(double y, std::vector<double>& xs) const {
- // search line segments for intersection points with y pos
- for(unsigned i=1;i<route->n;i++) {
- double ax=route->xs[i-1], bx=route->xs[i], ay=route->ys[i-1], by=route->ys[i];
- double r=(y-ay)/(by-ay);
- // as long as y is between ay and by then r>0
- if(r>=0&&r<=1) {
- xs.push_back(ax+(bx-ax)*r);
- }
- }
- }
- void ypos(double x, std::vector<double>& ys) const {
- // search line segments for intersection points with x pos
- for(unsigned i=1;i<route->n;i++) {
- double ax=route->xs[i-1], bx=route->xs[i], ay=route->ys[i-1], by=route->ys[i];
- double r=(x-ax)/(bx-ax);
- // as long as y is between ax and bx then r>0
- if(r>0&&r<=1) {
- ys.push_back(ay+(by-ay)*r);
- }
- }
- }
- Route const * getRoute() const {
- return route;
- }
- void setRoute(Route * r) {
- delete route;
- route=r;
- updateBoundingBox();
- }
-private:
- void updateBoundingBox() {
- route->boundingBox(min[0],min[1],max[0],max[1]);
- }
- Route* route;
-};
-class Straightener {
-public:
- Straightener(
- const double strength,
- const vpsc::Dim dim,
- std::vector<vpsc::Rectangle*> const & rs,
- cola::FixedList const & fixed,
- std::vector<Edge*> const & edges,
- vpsc::Variables const & vs,
- vpsc::Variables & lvs,
- vpsc::Constraints & lcs,
- std::valarray<double> & oldCoords,
- std::valarray<double> & oldG);
- ~Straightener();
- void updateNodePositions();
- void finalizeRoutes();
- void computeForces(cola::SparseMap &H);
- void computeForces2(cola::SparseMap &H);
- double computeStress(std::valarray<double> const &coords);
- double computeStress2(std::valarray<double> const &coords);
- std::valarray<double> dummyNodesX;
- std::valarray<double> dummyNodesY;
- std::valarray<double> g;
- std::valarray<double> coords;
- unsigned N;
-private:
- double strength;
- const vpsc::Dim dim;
- cola::FixedList const & fixed;
- std::vector<Edge*> const & edges;
- vpsc::Variables const & vs;
- vpsc::Variables & lvs;
- std::vector<Node*> nodes;
- double len(const unsigned u, const unsigned v,
- double& dx, double& dy,
- double& dx2, double& dy2);
- double gRule1(const unsigned a, const unsigned b);
- double gRule2(const unsigned a, const unsigned b, const unsigned c);
- double hRuleD1(const unsigned u, const unsigned v, const double sqrtf);
- double hRuleD2(const unsigned u, const unsigned v, const unsigned w, const double sqrtf);
- double hRule2(const unsigned u, const unsigned v, const unsigned w, const double sqrtf);
- double hRule3(const unsigned u, const unsigned v, const unsigned w, const double sqrtf);
- double hRule4(const unsigned a, const unsigned b, const unsigned c, const unsigned d);
- double hRule56(const unsigned u, const unsigned v,
- const unsigned a, const unsigned b, const unsigned c);
- double hRule7(const unsigned a, const unsigned b,
- const unsigned c, const unsigned d, const double sqrtf);
- double hRule8(const unsigned u, const unsigned v, const unsigned w,
- const unsigned a, const unsigned b, const unsigned c);
-};
-class Cluster {
-public:
- cola::ConvexCluster* colaCluster;
- Cluster(cola::ConvexCluster* c) : colaCluster(c) {}
- double scanpos;
- std::vector<Edge*> boundary;
- void updateActualBoundary();
-};
-class Node : public ScanObject {
-public:
- Cluster* cluster;
- // Nodes may optionally belong to a cluster.
- // Neg cluster_id means no cluster - i.e. top-level membership.
- double pos[2];
- double scanpos;
- double length[2];
- Edge* edge;
- bool dummy; // nodes on edge paths (but not ends) are dummy
- bool scan; // triggers scan events
- bool active; // node is active if it is not dummy or is dummy and involved in
- // a violated constraint
- bool open; // a node is opened (if scan is true) when the scanline first reaches
- // its boundary and closed when the scanline leaves it.
- Node(unsigned id, vpsc::Rectangle const * r) :
- ScanObject(id),cluster(NULL),
- edge(NULL),dummy(false),scan(true),active(true),open(false) {
- for(unsigned i=0;i<2;i++) {
- pos[i]=r->getCentreD(i);
- min[i]=r->getMinD(i);
- max[i]=r->getMaxD(i);
- length[i]=r->length(i);
- }
- }
- Node(unsigned id, const double x, const double y) :
- ScanObject(id),cluster(NULL),
- edge(NULL),dummy(false),scan(false),active(true),open(false) {
- pos[vpsc::HORIZONTAL]=x;
- pos[vpsc::VERTICAL]=y;
- for(unsigned i=0;i<2;i++) {
- length[i]=4;
- min[i]=pos[i]-length[i]/2.0;
- max[i]=pos[i]+length[i]/2.0;
- }
- }
- double euclidean_distance(Node const * v) const {
- double dx=pos[0]-v->pos[0];
- double dy=pos[1]-v->pos[1];
- return sqrt(dx*dx+dy*dy);
- }
-
-private:
- friend void sortNeighbours(const vpsc::Dim dim, Node * v, Node * l, Node * r,
- const double conjpos, std::vector<Edge*> const & openEdges,
- std::vector<Node *>& L, std::vector<Node *>& nodes);
- Node(const unsigned id, const double x, const double y, Edge* e) :
- ScanObject(id),cluster(NULL),
- edge(e),dummy(true),scan(false),active(false) {
- pos[vpsc::HORIZONTAL]=x;
- pos[vpsc::VERTICAL]=y;
- for(unsigned i=0;i<2;i++) {
- length[i]=4;
- min[i]=pos[i]-length[i]/2.0;
- max[i]=pos[i]+length[i]/2.0;
- }
- e->dummyNodes.push_back(id);
- }
-};
-struct CmpNodePos {
- bool operator() (const Node* u, const Node* v) const {
- double upos = u->scanpos;
- double vpos = v->scanpos;
- bool tiebreaker = u < v;
- if (u->cluster != v->cluster) {
- if(u->cluster!=NULL) {
- upos = u->cluster->scanpos;
- }
- if(v->cluster!=NULL) {
- vpos = v->cluster->scanpos;
- }
- tiebreaker = u->cluster < v->cluster;
- }
- if (upos < vpos) {
- return true;
- }
- if (vpos < upos) {
- return false;
- }
- return tiebreaker;
- }
-};
-typedef std::set<Node*,CmpNodePos> NodeSet;
-// defines references to three variables for which the goal function
-// will be altered to prefer points u-b-v are in a linear arrangement
-// such that b is placed at u+t(v-u).
-struct LinearConstraint {
- LinearConstraint(
- Node const & u,
- Node const & v,
- Node const & b,
- double w)
- : u(u.id),v(v.id),b(b.id),w(w)
- {
- // from cosine rule: ub.uv/|uv|=|ub|cos(theta)
- double uvx = v.pos[0] - u.pos[0],
- uvy = v.pos[1] - u.pos[1],
- ubx = b.pos[0] - u.pos[0],
- uby = b.pos[1] - u.pos[1],
- duv2 = uvx * uvx + uvy * uvy;
- if(duv2 < 0.0001) {
- t=0;
- } else {
- t = (uvx * ubx + uvy * uby)/duv2;
- }
- duu=(1-t)*(1-t);
- duv=t*(1-t);
- dub=t-1;
- dvv=t*t;
- dvb=-t;
- dbb=1;
- //printf("New LC: t=%f\n",t);
- }
- unsigned u;
- unsigned v;
- unsigned b;
- double w; // weight
- double t;
- // 2nd partial derivatives of the goal function
- // (X[b] - (1-t) X[u] - t X[v])^2
- double duu;
- double duv;
- double dub;
- double dvv;
- double dvb;
- double dbb;
-};
-void setEdgeLengths(double **D, std::vector<Edge*> & edges);
-double pathLength(Edge const * e, std::vector<Node*> const & nodes);
-double computeStressFromRoutes(double strength, std::vector<Edge*> & edges);
-typedef std::vector<LinearConstraint*> LinearConstraints;
-void generateConstraints(
- const vpsc::Dim dim,
- std::vector<Node*> & nodes,
- std::vector<Edge*> const & edges,
- std::vector<cola::SeparationConstraint*>& cs,
- bool xSkipping);
-void nodePath(Edge& e, std::vector<Node*>& nodes, std::vector<unsigned>& path);
-void generateClusterBoundaries(
- const vpsc::Dim dim,
- std::vector<Node*> & nodes,
- std::vector<Edge*> & edges,
- std::vector<vpsc::Rectangle*> const & rs,
- cola::Cluster const & clusterHierarchy,
- std::vector<straightener::Cluster*>& sclusters);
-
-} // namespace straightener
-#endif