- bezier.h went to lemon/bits/
authoralpar
Mon, 14 Aug 2006 15:15:57 +0000
changeset 21780d7c0f96a5ee
parent 2177 416a7030b7e3
child 2179 a3bb30be417c
- bezier.h went to lemon/bits/
- new graphToEps() option: absolute/relative node size/link width scaling.
demo/graph_to_eps_demo.cc
lemon/bezier.h
lemon/bits/bezier.h
lemon/graph_to_eps.h
     1.1 --- a/demo/graph_to_eps_demo.cc	Fri Aug 11 14:55:33 2006 +0000
     1.2 +++ b/demo/graph_to_eps_demo.cc	Mon Aug 14 15:15:57 2006 +0000
     1.3 @@ -42,6 +42,7 @@
     1.4  int main()
     1.5  {
     1.6    Palette palette;
     1.7 +  Palette paletteW(true);
     1.8  
     1.9    ListGraph g;
    1.10    typedef ListGraph::Node Node;
    1.11 @@ -80,12 +81,21 @@
    1.12    
    1.13    IdMap<ListGraph,Node> id(g);
    1.14  
    1.15 +  cout << "Create 'graph_to_eps_demo_out_pure.eps'" << endl;
    1.16 +  graphToEps(g,"graph_to_eps_demo_out_pure.eps").
    1.17 +    //scale(10).
    1.18 +    coords(coords).
    1.19 +    title("Sample .eps figure").
    1.20 +    copyright("(C) 2006 LEMON Project").
    1.21 +    run();
    1.22 +
    1.23    cout << "Create 'graph_to_eps_demo_out.eps'" << endl;
    1.24    graphToEps(g,"graph_to_eps_demo_out.eps").
    1.25      //scale(10).
    1.26      coords(coords).
    1.27      title("Sample .eps figure").
    1.28      copyright("(C) 2006 LEMON Project").
    1.29 +    absoluteNodeSizes().absoluteEdgeWidths().
    1.30      nodeScale(2).nodeSizes(sizes).
    1.31      nodeShapes(shapes).
    1.32      nodeColors(composeMap(palette,colors)).
    1.33 @@ -100,6 +110,7 @@
    1.34      //scale(10).
    1.35      title("Sample .eps figure (with arrowheads)").
    1.36      copyright("(C) 2006 LEMON Project").
    1.37 +    absoluteNodeSizes().absoluteEdgeWidths().
    1.38      nodeColors(composeMap(palette,colors)).
    1.39      coords(coords).
    1.40      nodeScale(2).nodeSizes(sizes).
    1.41 @@ -126,6 +137,7 @@
    1.42      //scale(10).
    1.43      title("Sample .eps figure (parallel edges)").
    1.44      copyright("(C) 2006 LEMON Project").
    1.45 +    absoluteNodeSizes().absoluteEdgeWidths().
    1.46      nodeShapes(shapes).
    1.47      coords(coords).
    1.48      nodeScale(2).nodeSizes(sizes).
    1.49 @@ -141,6 +153,7 @@
    1.50      //scale(10).
    1.51      title("Sample .eps figure (parallel edges and arrowheads)").
    1.52      copyright("(C) 2006 LEMON Project").
    1.53 +    absoluteNodeSizes().absoluteEdgeWidths().
    1.54      nodeScale(2).nodeSizes(sizes).
    1.55      coords(coords).
    1.56      nodeShapes(shapes).
    1.57 @@ -156,6 +169,7 @@
    1.58    graphToEps(g,"graph_to_eps_demo_out_a4.eps").scaleToA4().
    1.59      title("Sample .eps figure (fits to A4)").
    1.60      copyright("(C) 2006 LEMON Project").
    1.61 +    absoluteNodeSizes().absoluteEdgeWidths().
    1.62      nodeScale(2).nodeSizes(sizes).
    1.63      coords(coords).
    1.64      nodeShapes(shapes).
    1.65 @@ -172,7 +186,7 @@
    1.66    ListGraph::NodeMap<Xy> hcoords(h);
    1.67    
    1.68    int cols=int(sqrt(double(palette.size())));
    1.69 -  for(int i=0;i<int(palette.size());i++) {
    1.70 +  for(int i=0;i<int(paletteW.size());i++) {
    1.71      Node n=h.addNode();
    1.72      hcoords[n]=Xy(i%cols,i/cols);
    1.73      hcolors[n]=i;
    1.74 @@ -184,12 +198,11 @@
    1.75      title("Sample .eps figure (Palette demo)").
    1.76      copyright("(C) 2006 LEMON Project").
    1.77      coords(hcoords).
    1.78 -    nodeScale(.45).
    1.79 +    absoluteNodeSizes().absoluteEdgeWidths().
    1.80 +    nodeScale(45).
    1.81      distantColorNodeTexts().
    1.82      //    distantBWNodeTexts().
    1.83      nodeTexts(hcolors).nodeTextSize(.6).
    1.84 -    nodeColors(composeMap(palette,hcolors)).
    1.85 +    nodeColors(composeMap(paletteW,hcolors)).
    1.86      run();
    1.87 -
    1.88 -
    1.89  }
     2.1 --- a/lemon/bezier.h	Fri Aug 11 14:55:33 2006 +0000
     2.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.3 @@ -1,172 +0,0 @@
     2.4 -/* -*- C++ -*-
     2.5 - *
     2.6 - * This file is a part of LEMON, a generic C++ optimization library
     2.7 - *
     2.8 - * Copyright (C) 2003-2006
     2.9 - * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
    2.10 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
    2.11 - *
    2.12 - * Permission to use, modify and distribute this software is granted
    2.13 - * provided that this copyright notice appears in all copies. For
    2.14 - * precise terms see the accompanying LICENSE file.
    2.15 - *
    2.16 - * This software is provided "AS IS" with no warranty of any kind,
    2.17 - * express or implied, and with no claim as to its suitability for any
    2.18 - * purpose.
    2.19 - *
    2.20 - */
    2.21 -
    2.22 -#ifndef LEMON_BEZIER_H
    2.23 -#define LEMON_BEZIER_H
    2.24 -
    2.25 -///\ingroup misc
    2.26 -///\file
    2.27 -///\brief Classes to compute with Bezier curves.
    2.28 -///
    2.29 -///Up to now this file is used internally by \ref graph_to_eps.h
    2.30 -///
    2.31 -///\author Alpar Juttner
    2.32 -
    2.33 -#include<lemon/xy.h>
    2.34 -
    2.35 -namespace lemon {
    2.36 -
    2.37 -class BezierBase {
    2.38 -public:
    2.39 -  typedef xy<double> xy;
    2.40 -protected:
    2.41 -  static xy conv(xy x,xy y,double t) {return (1-t)*x+t*y;}
    2.42 -};
    2.43 -
    2.44 -class Bezier1 : public BezierBase
    2.45 -{
    2.46 -public:
    2.47 -  xy p1,p2;
    2.48 -
    2.49 -  Bezier1() {}
    2.50 -  Bezier1(xy _p1, xy _p2) :p1(_p1), p2(_p2) {}
    2.51 -  
    2.52 -  xy operator()(double t) const
    2.53 -  {
    2.54 -    //    return conv(conv(p1,p2,t),conv(p2,p3,t),t);
    2.55 -    return conv(p1,p2,t);
    2.56 -  }
    2.57 -  Bezier1 before(double t) const
    2.58 -  {
    2.59 -    return Bezier1(p1,conv(p1,p2,t));
    2.60 -  }
    2.61 -  
    2.62 -  Bezier1 after(double t) const
    2.63 -  {
    2.64 -    return Bezier1(conv(p1,p2,t),p2);
    2.65 -  }
    2.66 -
    2.67 -  Bezier1 revert() const { return Bezier1(p2,p1);}
    2.68 -  Bezier1 operator()(double a,double b) const { return before(b).after(a/b); }
    2.69 -  xy grad() const { return p2-p1; }
    2.70 -  xy norm() const { return rot90(p2-p1); }
    2.71 -  xy grad(double) const { return grad(); }
    2.72 -  xy norm(double t) const { return rot90(grad(t)); }
    2.73 -};
    2.74 -
    2.75 -class Bezier2 : public BezierBase
    2.76 -{
    2.77 -public:
    2.78 -  xy p1,p2,p3;
    2.79 -
    2.80 -  Bezier2() {}
    2.81 -  Bezier2(xy _p1, xy _p2, xy _p3) :p1(_p1), p2(_p2), p3(_p3) {}
    2.82 -  Bezier2(const Bezier1 &b) : p1(b.p1), p2(conv(b.p1,b.p2,.5)), p3(b.p2) {}
    2.83 -  xy operator()(double t) const
    2.84 -  {
    2.85 -    //    return conv(conv(p1,p2,t),conv(p2,p3,t),t);
    2.86 -    return ((1-t)*(1-t))*p1+(2*(1-t)*t)*p2+(t*t)*p3;
    2.87 -  }
    2.88 -  Bezier2 before(double t) const
    2.89 -  {
    2.90 -    xy q(conv(p1,p2,t));
    2.91 -    xy r(conv(p2,p3,t));
    2.92 -    return Bezier2(p1,q,conv(q,r,t));
    2.93 -  }
    2.94 -  
    2.95 -  Bezier2 after(double t) const
    2.96 -  {
    2.97 -    xy q(conv(p1,p2,t));
    2.98 -    xy r(conv(p2,p3,t));
    2.99 -    return Bezier2(conv(q,r,t),r,p3);
   2.100 -  }
   2.101 -  Bezier2 revert() const { return Bezier2(p3,p2,p1);}
   2.102 -  Bezier2 operator()(double a,double b) const { return before(b).after(a/b); }
   2.103 -  Bezier1 grad() const { return Bezier1(2.0*(p2-p1),2.0*(p3-p2)); }
   2.104 -  Bezier1 norm() const { return Bezier1(2.0*rot90(p2-p1),2.0*rot90(p3-p2)); }
   2.105 -  xy grad(double t) const { return grad()(t); }
   2.106 -  xy norm(double t) const { return rot90(grad(t)); }
   2.107 -};
   2.108 -
   2.109 -class Bezier3 : public BezierBase
   2.110 -{
   2.111 -public:
   2.112 -  xy p1,p2,p3,p4;
   2.113 -
   2.114 -  Bezier3() {}
   2.115 -  Bezier3(xy _p1, xy _p2, xy _p3, xy _p4) :p1(_p1), p2(_p2), p3(_p3), p4(_p4) {}
   2.116 -  Bezier3(const Bezier1 &b) : p1(b.p1), p2(conv(b.p1,b.p2,1.0/3.0)), 
   2.117 -			      p3(conv(b.p1,b.p2,2.0/3.0)), p4(b.p2) {}
   2.118 -  Bezier3(const Bezier2 &b) : p1(b.p1), p2(conv(b.p1,b.p2,2.0/3.0)),
   2.119 -			      p3(conv(b.p2,b.p3,1.0/3.0)), p4(b.p3) {}
   2.120 -  
   2.121 -  xy operator()(double t) const 
   2.122 -    {
   2.123 -      //    return Bezier2(conv(p1,p2,t),conv(p2,p3,t),conv(p3,p4,t))(t);
   2.124 -      return ((1-t)*(1-t)*(1-t))*p1+(3*t*(1-t)*(1-t))*p2+
   2.125 -	(3*t*t*(1-t))*p3+(t*t*t)*p4;
   2.126 -    }
   2.127 -  Bezier3 before(double t) const
   2.128 -    {
   2.129 -      xy p(conv(p1,p2,t));
   2.130 -      xy q(conv(p2,p3,t));
   2.131 -      xy r(conv(p3,p4,t));
   2.132 -      xy a(conv(p,q,t));
   2.133 -      xy b(conv(q,r,t));
   2.134 -      xy c(conv(a,b,t));
   2.135 -      return Bezier3(p1,p,a,c);
   2.136 -    }
   2.137 -  
   2.138 -  Bezier3 after(double t) const
   2.139 -    {
   2.140 -      xy p(conv(p1,p2,t));
   2.141 -      xy q(conv(p2,p3,t));
   2.142 -      xy r(conv(p3,p4,t));
   2.143 -      xy a(conv(p,q,t));
   2.144 -      xy b(conv(q,r,t));
   2.145 -      xy c(conv(a,b,t));
   2.146 -      return Bezier3(c,b,r,p4);
   2.147 -    }
   2.148 -  Bezier3 revert() const { return Bezier3(p4,p3,p2,p1);}
   2.149 -  Bezier3 operator()(double a,double b) const { return before(b).after(a/b); }
   2.150 -  Bezier2 grad() const { return Bezier2(3.0*(p2-p1),3.0*(p3-p2),3.0*(p4-p3)); }
   2.151 -  Bezier2 norm() const { return Bezier2(3.0*rot90(p2-p1),
   2.152 -				  3.0*rot90(p3-p2),
   2.153 -				  3.0*rot90(p4-p3)); }
   2.154 -  xy grad(double t) const { return grad()(t); }
   2.155 -  xy norm(double t) const { return rot90(grad(t)); }
   2.156 -
   2.157 -  template<class R,class F,class S,class D>
   2.158 -  R recSplit(F &_f,const S &_s,D _d) const 
   2.159 -  {
   2.160 -    const xy a=(p1+p2)/2;
   2.161 -    const xy b=(p2+p3)/2;
   2.162 -    const xy c=(p3+p4)/2;
   2.163 -    const xy d=(a+b)/2;
   2.164 -    const xy e=(b+c)/2;
   2.165 -    const xy f=(d+e)/2;
   2.166 -    R f1=_f(Bezier3(p1,a,d,e),_d);
   2.167 -    R f2=_f(Bezier3(e,d,c,p4),_d);
   2.168 -    return _s(f1,f2);
   2.169 -  }
   2.170 -  
   2.171 -};
   2.172 -
   2.173 -} //END OF NAMESPACE LEMON
   2.174 -
   2.175 -#endif // LEMON_BEZIER_H
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/lemon/bits/bezier.h	Mon Aug 14 15:15:57 2006 +0000
     3.3 @@ -0,0 +1,172 @@
     3.4 +/* -*- C++ -*-
     3.5 + *
     3.6 + * This file is a part of LEMON, a generic C++ optimization library
     3.7 + *
     3.8 + * Copyright (C) 2003-2006
     3.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
    3.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
    3.11 + *
    3.12 + * Permission to use, modify and distribute this software is granted
    3.13 + * provided that this copyright notice appears in all copies. For
    3.14 + * precise terms see the accompanying LICENSE file.
    3.15 + *
    3.16 + * This software is provided "AS IS" with no warranty of any kind,
    3.17 + * express or implied, and with no claim as to its suitability for any
    3.18 + * purpose.
    3.19 + *
    3.20 + */
    3.21 +
    3.22 +#ifndef LEMON_BEZIER_H
    3.23 +#define LEMON_BEZIER_H
    3.24 +
    3.25 +///\ingroup misc
    3.26 +///\file
    3.27 +///\brief Classes to compute with Bezier curves.
    3.28 +///
    3.29 +///Up to now this file is used internally by \ref graph_to_eps.h
    3.30 +///
    3.31 +///\author Alpar Juttner
    3.32 +
    3.33 +#include<lemon/xy.h>
    3.34 +
    3.35 +namespace lemon {
    3.36 +
    3.37 +class BezierBase {
    3.38 +public:
    3.39 +  typedef xy<double> xy;
    3.40 +protected:
    3.41 +  static xy conv(xy x,xy y,double t) {return (1-t)*x+t*y;}
    3.42 +};
    3.43 +
    3.44 +class Bezier1 : public BezierBase
    3.45 +{
    3.46 +public:
    3.47 +  xy p1,p2;
    3.48 +
    3.49 +  Bezier1() {}
    3.50 +  Bezier1(xy _p1, xy _p2) :p1(_p1), p2(_p2) {}
    3.51 +  
    3.52 +  xy operator()(double t) const
    3.53 +  {
    3.54 +    //    return conv(conv(p1,p2,t),conv(p2,p3,t),t);
    3.55 +    return conv(p1,p2,t);
    3.56 +  }
    3.57 +  Bezier1 before(double t) const
    3.58 +  {
    3.59 +    return Bezier1(p1,conv(p1,p2,t));
    3.60 +  }
    3.61 +  
    3.62 +  Bezier1 after(double t) const
    3.63 +  {
    3.64 +    return Bezier1(conv(p1,p2,t),p2);
    3.65 +  }
    3.66 +
    3.67 +  Bezier1 revert() const { return Bezier1(p2,p1);}
    3.68 +  Bezier1 operator()(double a,double b) const { return before(b).after(a/b); }
    3.69 +  xy grad() const { return p2-p1; }
    3.70 +  xy norm() const { return rot90(p2-p1); }
    3.71 +  xy grad(double) const { return grad(); }
    3.72 +  xy norm(double t) const { return rot90(grad(t)); }
    3.73 +};
    3.74 +
    3.75 +class Bezier2 : public BezierBase
    3.76 +{
    3.77 +public:
    3.78 +  xy p1,p2,p3;
    3.79 +
    3.80 +  Bezier2() {}
    3.81 +  Bezier2(xy _p1, xy _p2, xy _p3) :p1(_p1), p2(_p2), p3(_p3) {}
    3.82 +  Bezier2(const Bezier1 &b) : p1(b.p1), p2(conv(b.p1,b.p2,.5)), p3(b.p2) {}
    3.83 +  xy operator()(double t) const
    3.84 +  {
    3.85 +    //    return conv(conv(p1,p2,t),conv(p2,p3,t),t);
    3.86 +    return ((1-t)*(1-t))*p1+(2*(1-t)*t)*p2+(t*t)*p3;
    3.87 +  }
    3.88 +  Bezier2 before(double t) const
    3.89 +  {
    3.90 +    xy q(conv(p1,p2,t));
    3.91 +    xy r(conv(p2,p3,t));
    3.92 +    return Bezier2(p1,q,conv(q,r,t));
    3.93 +  }
    3.94 +  
    3.95 +  Bezier2 after(double t) const
    3.96 +  {
    3.97 +    xy q(conv(p1,p2,t));
    3.98 +    xy r(conv(p2,p3,t));
    3.99 +    return Bezier2(conv(q,r,t),r,p3);
   3.100 +  }
   3.101 +  Bezier2 revert() const { return Bezier2(p3,p2,p1);}
   3.102 +  Bezier2 operator()(double a,double b) const { return before(b).after(a/b); }
   3.103 +  Bezier1 grad() const { return Bezier1(2.0*(p2-p1),2.0*(p3-p2)); }
   3.104 +  Bezier1 norm() const { return Bezier1(2.0*rot90(p2-p1),2.0*rot90(p3-p2)); }
   3.105 +  xy grad(double t) const { return grad()(t); }
   3.106 +  xy norm(double t) const { return rot90(grad(t)); }
   3.107 +};
   3.108 +
   3.109 +class Bezier3 : public BezierBase
   3.110 +{
   3.111 +public:
   3.112 +  xy p1,p2,p3,p4;
   3.113 +
   3.114 +  Bezier3() {}
   3.115 +  Bezier3(xy _p1, xy _p2, xy _p3, xy _p4) :p1(_p1), p2(_p2), p3(_p3), p4(_p4) {}
   3.116 +  Bezier3(const Bezier1 &b) : p1(b.p1), p2(conv(b.p1,b.p2,1.0/3.0)), 
   3.117 +			      p3(conv(b.p1,b.p2,2.0/3.0)), p4(b.p2) {}
   3.118 +  Bezier3(const Bezier2 &b) : p1(b.p1), p2(conv(b.p1,b.p2,2.0/3.0)),
   3.119 +			      p3(conv(b.p2,b.p3,1.0/3.0)), p4(b.p3) {}
   3.120 +  
   3.121 +  xy operator()(double t) const 
   3.122 +    {
   3.123 +      //    return Bezier2(conv(p1,p2,t),conv(p2,p3,t),conv(p3,p4,t))(t);
   3.124 +      return ((1-t)*(1-t)*(1-t))*p1+(3*t*(1-t)*(1-t))*p2+
   3.125 +	(3*t*t*(1-t))*p3+(t*t*t)*p4;
   3.126 +    }
   3.127 +  Bezier3 before(double t) const
   3.128 +    {
   3.129 +      xy p(conv(p1,p2,t));
   3.130 +      xy q(conv(p2,p3,t));
   3.131 +      xy r(conv(p3,p4,t));
   3.132 +      xy a(conv(p,q,t));
   3.133 +      xy b(conv(q,r,t));
   3.134 +      xy c(conv(a,b,t));
   3.135 +      return Bezier3(p1,p,a,c);
   3.136 +    }
   3.137 +  
   3.138 +  Bezier3 after(double t) const
   3.139 +    {
   3.140 +      xy p(conv(p1,p2,t));
   3.141 +      xy q(conv(p2,p3,t));
   3.142 +      xy r(conv(p3,p4,t));
   3.143 +      xy a(conv(p,q,t));
   3.144 +      xy b(conv(q,r,t));
   3.145 +      xy c(conv(a,b,t));
   3.146 +      return Bezier3(c,b,r,p4);
   3.147 +    }
   3.148 +  Bezier3 revert() const { return Bezier3(p4,p3,p2,p1);}
   3.149 +  Bezier3 operator()(double a,double b) const { return before(b).after(a/b); }
   3.150 +  Bezier2 grad() const { return Bezier2(3.0*(p2-p1),3.0*(p3-p2),3.0*(p4-p3)); }
   3.151 +  Bezier2 norm() const { return Bezier2(3.0*rot90(p2-p1),
   3.152 +				  3.0*rot90(p3-p2),
   3.153 +				  3.0*rot90(p4-p3)); }
   3.154 +  xy grad(double t) const { return grad()(t); }
   3.155 +  xy norm(double t) const { return rot90(grad(t)); }
   3.156 +
   3.157 +  template<class R,class F,class S,class D>
   3.158 +  R recSplit(F &_f,const S &_s,D _d) const 
   3.159 +  {
   3.160 +    const xy a=(p1+p2)/2;
   3.161 +    const xy b=(p2+p3)/2;
   3.162 +    const xy c=(p3+p4)/2;
   3.163 +    const xy d=(a+b)/2;
   3.164 +    const xy e=(b+c)/2;
   3.165 +    const xy f=(d+e)/2;
   3.166 +    R f1=_f(Bezier3(p1,a,d,e),_d);
   3.167 +    R f2=_f(Bezier3(e,d,c,p4),_d);
   3.168 +    return _s(f1,f2);
   3.169 +  }
   3.170 +  
   3.171 +};
   3.172 +
   3.173 +} //END OF NAMESPACE LEMON
   3.174 +
   3.175 +#endif // LEMON_BEZIER_H
     4.1 --- a/lemon/graph_to_eps.h	Fri Aug 11 14:55:33 2006 +0000
     4.2 +++ b/lemon/graph_to_eps.h	Mon Aug 14 15:15:57 2006 +0000
     4.3 @@ -38,7 +38,7 @@
     4.4  #include<lemon/xy.h>
     4.5  #include<lemon/maps.h>
     4.6  #include<lemon/color.h>
     4.7 -#include<lemon/bezier.h>
     4.8 +#include<lemon/bits/bezier.h>
     4.9  
    4.10  
    4.11  ///\ingroup eps_io
    4.12 @@ -130,6 +130,9 @@
    4.13    bool _autoNodeScale;
    4.14    bool _autoEdgeWidthScale;
    4.15  
    4.16 +  bool _absoluteNodeSizes;
    4.17 +  bool _absoluteEdgeWidths;
    4.18 +
    4.19    bool _negY;
    4.20    ///Constructor
    4.21  
    4.22 @@ -143,9 +146,9 @@
    4.23    DefaultGraphToEpsTraits(const G &_g,std::ostream& _os=std::cout,
    4.24  			  bool _pros=false) :
    4.25      g(_g), os(_os),
    4.26 -    _coords(xy<double>(1,1)), _nodeSizes(1.0), _nodeShapes(0),
    4.27 +    _coords(xy<double>(1,1)), _nodeSizes(.01), _nodeShapes(0),
    4.28      _nodeColors(WHITE), _edgeColors(BLACK),
    4.29 -    _edgeWidths(1), _edgeWidthScale(0.3),
    4.30 +    _edgeWidths(1.0), _edgeWidthScale(0.003),
    4.31      _nodeScale(1.0), _xBorder(10), _yBorder(10), _scale(1.0),
    4.32      _nodeBorderQuotient(.1),
    4.33      _drawArrows(false), _arrowLength(1), _arrowWidth(0.3),
    4.34 @@ -158,6 +161,8 @@
    4.35      _nodeTextColorType(SAME_COL), _nodeTextColors(BLACK),
    4.36      _autoNodeScale(false),
    4.37      _autoEdgeWidthScale(false),
    4.38 +    _absoluteNodeSizes(false),
    4.39 +    _absoluteEdgeWidths(false),
    4.40      _negY(false)
    4.41    {}
    4.42  };
    4.43 @@ -229,6 +234,10 @@
    4.44    using T::_autoNodeScale;
    4.45    using T::_autoEdgeWidthScale;
    4.46  
    4.47 +  using T::_absoluteNodeSizes;
    4.48 +  using T::_absoluteEdgeWidths;
    4.49 +
    4.50 +
    4.51    using T::_negY;
    4.52  
    4.53    // dradnats ++C eht yb deriuqer si ti eveileb t'naC
    4.54 @@ -478,6 +487,8 @@
    4.55    /// If both nodeSizes() and autoNodeScale() are used, then the
    4.56    /// node sizes will be scaled in such a way that the greatest size will be
    4.57    /// equal to \c d.
    4.58 +  /// \sa nodeSizes()
    4.59 +  /// \sa autoNodeScale()
    4.60    GraphToEps<T> &nodeScale(double d) {_nodeScale=d;return *this;}
    4.61    ///Turns on/off the automatic node width scaling.
    4.62  
    4.63 @@ -489,6 +500,16 @@
    4.64      _autoNodeScale=b;return *this;
    4.65    }
    4.66  
    4.67 +  ///Turns on/off the absolutematic node width scaling.
    4.68 +
    4.69 +  ///Turns on/off the absolutematic node width scaling.
    4.70 +  ///
    4.71 +  ///\sa nodeScale()
    4.72 +  ///
    4.73 +  GraphToEps<T> &absoluteNodeSizes(bool b=true) {
    4.74 +    _absoluteNodeSizes=b;return *this;
    4.75 +  }
    4.76 +
    4.77    ///Negates the Y coordinates.
    4.78  
    4.79    ///Negates the Y coordinates.
    4.80 @@ -520,6 +541,15 @@
    4.81    GraphToEps<T> &autoEdgeWidthScale(bool b=true) {
    4.82      _autoEdgeWidthScale=b;return *this;
    4.83    }
    4.84 +  ///Turns on/off the absolutematic edge width scaling.
    4.85 +
    4.86 +  ///Turns on/off the absolutematic edge width scaling.
    4.87 +  ///
    4.88 +  ///\sa edgeWidthScale()
    4.89 +  ///
    4.90 +  GraphToEps<T> &absoluteEdgeWidths(bool b=true) {
    4.91 +    _absoluteEdgeWidths=b;return *this;
    4.92 +  }
    4.93    ///Sets a global scale factor for the whole picture
    4.94  
    4.95    ///Sets a global scale factor for the whole picture
    4.96 @@ -664,6 +694,8 @@
    4.97    ///this function calles the algorithm itself, i.e. in this case
    4.98    ///it draws the graph.
    4.99    void run() {
   4.100 +    ///\todo better 'epsilon' would be nice here.
   4.101 +    const double EPSILON=1e-9;
   4.102      if(dontPrint) return;
   4.103      
   4.104      _NegY<typename T::CoordsMapType> mycoords(_coords,_negY);
   4.105 @@ -687,7 +719,7 @@
   4.106        for(EdgeIt e(g);e!=INVALID;++e)
   4.107  	max_w=std::max(double(_edgeWidths[e]),max_w);
   4.108        ///\todo better 'epsilon' would be nice here.
   4.109 -      if(max_w>1e-9) {
   4.110 +      if(max_w>EPSILON) {
   4.111  	_edgeWidthScale/=max_w;
   4.112        }
   4.113      }
   4.114 @@ -697,14 +729,25 @@
   4.115        for(NodeIt n(g);n!=INVALID;++n)
   4.116  	max_s=std::max(double(_nodeSizes[n]),max_s);
   4.117        ///\todo better 'epsilon' would be nice here.
   4.118 -      if(max_s>1e-9) {
   4.119 +      if(max_s>EPSILON) {
   4.120  	_nodeScale/=max_s;
   4.121        }
   4.122      }
   4.123  
   4.124 -
   4.125 +    double diag_len = 1;
   4.126 +    if(!(_absoluteNodeSizes&&_absoluteEdgeWidths)) {
   4.127 +      BoundingBox<double> bb;
   4.128 +      for(NodeIt n(g);n!=INVALID;++n) bb.add(mycoords[n]);
   4.129 +      if (bb.empty()) {
   4.130 +	bb = BoundingBox<double>(xy<double>(0,0));
   4.131 +      }
   4.132 +      diag_len = std::sqrt((bb.bottomLeft()-bb.topRight()).normSquare());
   4.133 +      if(diag_len<EPSILON) diag_len = 1;
   4.134 +      if(!_absoluteNodeSizes) _nodeScale*=diag_len;
   4.135 +      if(!_absoluteEdgeWidths) _edgeWidthScale*=diag_len;
   4.136 +    }
   4.137 +    
   4.138      BoundingBox<double> bb;
   4.139 -    ///\bug: Chech whether the graph is empty.
   4.140      for(NodeIt n(g);n!=INVALID;++n) {
   4.141        double ns=_nodeSizes[n]*_nodeScale;
   4.142        xy<double> p(ns,ns);
   4.143 @@ -864,7 +907,7 @@
   4.144  	  xy<double> dvec(mycoords[g.target(*i)]-mycoords[g.source(*i)]);
   4.145  	  double l=std::sqrt(dvec.normSquare()); 
   4.146  	  ///\todo better 'epsilon' would be nice here.
   4.147 -	  xy<double> d(dvec/std::max(l,1e-9));
   4.148 +	  xy<double> d(dvec/std::max(l,EPSILON));
   4.149   	  xy<double> m;
   4.150  // 	  m=xy<double>(mycoords[g.target(*i)]+mycoords[g.source(*i)])/2.0;
   4.151