graph_to_eps mission accomplished.
- lemon/graph_to_eps.h header created
- lemon/bezier.h: Tools to compute with bezier curves (unclean and undocumented
interface, used internally by graph_to_eps.h)
- demo/graph_to_eps_demo.cc: a simple demo for lemon/graph_to_eps.h
1.1 --- a/src/demo/Makefile.am Tue Jan 11 09:09:50 2005 +0000
1.2 +++ b/src/demo/Makefile.am Tue Jan 11 09:15:25 2005 +0000
1.3 @@ -2,8 +2,10 @@
1.4
1.5 EXTRA_DIST = sub_graph_wrapper_demo.dim
1.6
1.7 -noinst_PROGRAMS = dim_to_dot sub_graph_wrapper_demo
1.8 +noinst_PROGRAMS = dim_to_dot sub_graph_wrapper_demo graph_to_eps_demo
1.9
1.10 dim_to_dot_SOURCES = dim_to_dot.cc
1.11
1.12 sub_graph_wrapper_demo_SOURCES = sub_graph_wrapper_demo.cc tight_edge_filter_map.h
1.13 +
1.14 +graph_to_eps_demo_SOURCES = graph_to_eps_demo.cc
1.15 \ No newline at end of file
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/src/demo/graph_to_eps_demo.cc Tue Jan 11 09:15:25 2005 +0000
2.3 @@ -0,0 +1,133 @@
2.4 +/* -*- C++ -*-
2.5 + * src/lemon/demo/graph_to_eps.cc -
2.6 + * Part of LEMON, a generic C++ optimization library
2.7 + *
2.8 + * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
2.9 + * (Egervary Combinatorial Optimization Research Group, EGRES).
2.10 + *
2.11 + * Permission to use, modify and distribute this software is granted
2.12 + * provided that this copyright notice appears in all copies. For
2.13 + * precise terms see the accompanying LICENSE file.
2.14 + *
2.15 + * This software is provided "AS IS" with no warranty of any kind,
2.16 + * express or implied, and with no claim as to its suitability for any
2.17 + * purpose.
2.18 + *
2.19 + */
2.20 +
2.21 +#include<lemon/graph_to_eps.h>
2.22 +#include<lemon/maps.h>
2.23 +#include<lemon/list_graph.h>
2.24 +
2.25 +
2.26 +using namespace std;
2.27 +using namespace lemon;
2.28 +
2.29 +class ColorSet : public MapBase<int,Color>
2.30 +{
2.31 +public:
2.32 + Color operator[](int i) const
2.33 + {
2.34 + switch(i%8){
2.35 + case 0: return Color(0,0,0);
2.36 + case 1: return Color(1,0,0);
2.37 + case 2: return Color(0,1,0);
2.38 + case 3: return Color(0,0,1);
2.39 + case 4: return Color(1,1,0);
2.40 + case 5: return Color(1,0,1);
2.41 + case 6: return Color(0,1,1);
2.42 + case 7: return Color(1,1,1);
2.43 + }
2.44 + return Color(0,0,0);
2.45 + }
2.46 +} colorSet;
2.47 +
2.48 +class IdMap :public MapBase<ListGraph::Node,int>
2.49 +{
2.50 + const ListGraph &g;
2.51 +public:
2.52 + IdMap(const ListGraph &_g) :g(_g) {}
2.53 + Value operator[](Key n) const { return g.id(n); }
2.54 +};
2.55 +
2.56 +int main()
2.57 +{
2.58 + ListGraph g;
2.59 + typedef ListGraph::Node Node;
2.60 + typedef ListGraph::NodeIt NodeIt;
2.61 + typedef ListGraph::Edge Edge;
2.62 + typedef xy<int> Xy;
2.63 +
2.64 + Node n1=g.addNode();
2.65 + Node n2=g.addNode();
2.66 + Node n3=g.addNode();
2.67 + Node n4=g.addNode();
2.68 + Node n5=g.addNode();
2.69 +
2.70 + ListGraph::NodeMap<Xy> coords(g);
2.71 + ListGraph::NodeMap<double> sizes(g);
2.72 + ListGraph::NodeMap<int> colors(g);
2.73 + ListGraph::EdgeMap<int> ecolors(g);
2.74 + ListGraph::EdgeMap<int> widths(g);
2.75 +
2.76 + coords[n1]=Xy(50,50); sizes[n1]=1; colors[n1]=1;
2.77 + coords[n2]=Xy(50,70); sizes[n2]=2; colors[n2]=2;
2.78 + coords[n3]=Xy(70,70); sizes[n3]=1; colors[n3]=3;
2.79 + coords[n4]=Xy(70,50); sizes[n4]=2; colors[n4]=4;
2.80 + coords[n5]=Xy(85,60); sizes[n5]=3; colors[n5]=5;
2.81 +
2.82 + Edge e;
2.83 +
2.84 + e=g.addEdge(n1,n2); ecolors[e]=0; widths[e]=1;
2.85 + e=g.addEdge(n2,n3); ecolors[e]=0; widths[e]=1;
2.86 + e=g.addEdge(n3,n5); ecolors[e]=0; widths[e]=3;
2.87 + e=g.addEdge(n5,n4); ecolors[e]=0; widths[e]=1;
2.88 + e=g.addEdge(n4,n1); ecolors[e]=0; widths[e]=1;
2.89 + e=g.addEdge(n2,n4); ecolors[e]=1; widths[e]=2;
2.90 + e=g.addEdge(n3,n4); ecolors[e]=2; widths[e]=1;
2.91 +
2.92 + IdMap id(g);
2.93 +
2.94 + graphToEps(g,"graph_to_eps_demo_out.eps").scale(10).coords(coords).
2.95 + nodeScale(2).nodeSizes(sizes).
2.96 + nodeColors(composeMap(colorSet,colors)).
2.97 + edgeColors(composeMap(colorSet,ecolors)).
2.98 + edgeWidthScale(.4).edgeWidths(widths).
2.99 + nodeTexts(id).nodeTextSize(3);
2.100 +
2.101 + graphToEps(g,"graph_to_eps_demo_out_arr.eps").scale(10).coords(coords).
2.102 + nodeScale(2).nodeSizes(sizes).
2.103 + nodeColors(composeMap(colorSet,colors)).
2.104 + edgeColors(composeMap(colorSet,ecolors)).
2.105 + edgeWidthScale(.4).edgeWidths(widths).
2.106 + nodeTexts(id).nodeTextSize(3).
2.107 + drawArrows().arrowWidth(1).arrowLength(1);
2.108 +
2.109 + e=g.addEdge(n1,n4); ecolors[e]=2; widths[e]=1;
2.110 + e=g.addEdge(n4,n1); ecolors[e]=1; widths[e]=2;
2.111 +
2.112 + e=g.addEdge(n1,n2); ecolors[e]=1; widths[e]=1;
2.113 + e=g.addEdge(n1,n2); ecolors[e]=2; widths[e]=1;
2.114 + e=g.addEdge(n1,n2); ecolors[e]=3; widths[e]=1;
2.115 + e=g.addEdge(n1,n2); ecolors[e]=4; widths[e]=1;
2.116 + e=g.addEdge(n1,n2); ecolors[e]=5; widths[e]=1;
2.117 + e=g.addEdge(n1,n2); ecolors[e]=6; widths[e]=1;
2.118 + e=g.addEdge(n1,n2); ecolors[e]=7; widths[e]=1;
2.119 +
2.120 + graphToEps(g,"graph_to_eps_demo_out_par.eps").scale(10).coords(coords).
2.121 + nodeScale(2).nodeSizes(sizes).
2.122 + nodeColors(composeMap(colorSet,colors)).
2.123 + edgeColors(composeMap(colorSet,ecolors)).
2.124 + edgeWidthScale(.4).edgeWidths(widths).
2.125 + nodeTexts(id).nodeTextSize(3).
2.126 + enableParallel().parEdgeDist(1.5);
2.127 +
2.128 + graphToEps(g,"graph_to_eps_demo_out_par_arr.eps").scale(10).coords(coords).
2.129 + nodeScale(2).nodeSizes(sizes).
2.130 + nodeColors(composeMap(colorSet,colors)).
2.131 + edgeColors(composeMap(colorSet,ecolors)).
2.132 + edgeWidthScale(.3).edgeWidths(widths).
2.133 + nodeTexts(id).nodeTextSize(3).
2.134 + enableParallel().parEdgeDist(1).
2.135 + drawArrows().arrowWidth(1).arrowLength(1);
2.136 +}
3.1 --- a/src/lemon/Makefile.am Tue Jan 11 09:09:50 2005 +0000
3.2 +++ b/src/lemon/Makefile.am Tue Jan 11 09:15:25 2005 +0000
3.3 @@ -1,6 +1,7 @@
3.4 pkginclude_HEADERS = \
3.5 map_defines.h \
3.6 array_map.h \
3.7 + bezier.h \
3.8 bfs.h \
3.9 dfs.h \
3.10 bin_heap.h \
3.11 @@ -11,6 +12,7 @@
3.12 full_graph.h \
3.13 graph_wrapper.h \
3.14 graph_utils.h \
3.15 + graph_to_eps.h \
3.16 invalid.h \
3.17 kruskal.h \
3.18 list_graph.h \
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/src/lemon/bezier.h Tue Jan 11 09:15:25 2005 +0000
4.3 @@ -0,0 +1,139 @@
4.4 +/* -*- C++ -*-
4.5 + * src/lemon/bezier.h - Part of LEMON, a generic C++ optimization library
4.6 + *
4.7 + * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
4.8 + * (Egervary Combinatorial Optimization Research Group, EGRES).
4.9 + *
4.10 + * Permission to use, modify and distribute this software is granted
4.11 + * provided that this copyright notice appears in all copies. For
4.12 + * precise terms see the accompanying LICENSE file.
4.13 + *
4.14 + * This software is provided "AS IS" with no warranty of any kind,
4.15 + * express or implied, and with no claim as to its suitability for any
4.16 + * purpose.
4.17 + *
4.18 + */
4.19 +
4.20 +#ifndef LEMON_BEZIER_H
4.21 +#define LEMON_BEZIER_H
4.22 +
4.23 +///\ingroup misc
4.24 +///\file
4.25 +///\brief Classes to compute with Bezier curves.
4.26 +///
4.27 +///Up to now this file is internally used by \ref graph_to_eps.h
4.28 +///
4.29 +///\author Alpar Juttner
4.30 +
4.31 +#include<lemon/xy.h>
4.32 +
4.33 +namespace lemon {
4.34 +
4.35 +class BezierBase {
4.36 +public:
4.37 + typedef xy<double> xy;
4.38 +protected:
4.39 + static xy conv(xy x,xy y,double t) {return (1-t)*x+t*y;}
4.40 +};
4.41 +
4.42 +class Bezier1 : public BezierBase
4.43 +{
4.44 +public:
4.45 + xy p1,p2;
4.46 +
4.47 + Bezier1() {}
4.48 + Bezier1(xy _p1, xy _p2) :p1(_p1), p2(_p2) {}
4.49 +
4.50 + xy operator()(double t) const
4.51 + {
4.52 + // return conv(conv(p1,p2,t),conv(p2,p3,t),t);
4.53 + return conv(p1,p2,t);
4.54 + }
4.55 + Bezier1 before(double t) const
4.56 + {
4.57 + return Bezier1(p1,conv(p1,p2,t));
4.58 + }
4.59 +
4.60 + Bezier1 after(double t) const
4.61 + {
4.62 + return Bezier1(conv(p1,p2,t),p2);
4.63 + }
4.64 + Bezier1 operator()(double a,double b) { return before(b).after(a/b); }
4.65 +};
4.66 +
4.67 +class Bezier2 : public BezierBase
4.68 +{
4.69 +public:
4.70 + xy p1,p2,p3;
4.71 +
4.72 + Bezier2() {}
4.73 + Bezier2(xy _p1, xy _p2, xy _p3) :p1(_p1), p2(_p2), p3(_p3) {}
4.74 + Bezier2(const Bezier1 &b) : p1(b.p1), p2(conv(b.p1,b.p2,.5)), p3(b.p2) {}
4.75 + xy operator()(double t) const
4.76 + {
4.77 + // return conv(conv(p1,p2,t),conv(p2,p3,t),t);
4.78 + return ((1-t)*(1-t))*p1+(2*(1-t)*t)*p2+(t*t)*p3;
4.79 + }
4.80 + Bezier2 before(double t) const
4.81 + {
4.82 + xy q(conv(p1,p2,t));
4.83 + xy r(conv(p2,p3,t));
4.84 + return Bezier2(p1,q,conv(q,r,t));
4.85 + }
4.86 +
4.87 + Bezier2 after(double t) const
4.88 + {
4.89 + xy q(conv(p1,p2,t));
4.90 + xy r(conv(p2,p3,t));
4.91 + return Bezier2(conv(q,r,t),r,p3);
4.92 + }
4.93 + Bezier2 operator()(double a,double b) { return before(b).after(a/b); }
4.94 +
4.95 +};
4.96 +
4.97 +class Bezier3 : public BezierBase
4.98 +{
4.99 +public:
4.100 + xy p1,p2,p3,p4;
4.101 +
4.102 + Bezier3() {}
4.103 + Bezier3(xy _p1, xy _p2, xy _p3, xy _p4) :p1(_p1), p2(_p2), p3(_p3), p4(_p4) {}
4.104 + Bezier3(const Bezier1 &b) : p1(b.p1), p2(conv(b.p1,b.p2,1.0/3.0)),
4.105 + p3(conv(b.p1,b.p2,2.0/3.0)), p4(b.p2) {}
4.106 + Bezier3(const Bezier2 &b) : p1(b.p1), p2(conv(b.p1,b.p2,2.0/3.0)),
4.107 + p3(conv(b.p2,b.p3,1.0/3.0)), p4(b.p3) {}
4.108 +
4.109 + xy operator()(double t) const
4.110 + {
4.111 + // return Bezier2(conv(p1,p2,t),conv(p2,p3,t),conv(p3,p4,t))(t);
4.112 + return ((1-t)*(1-t)*(1-t))*p1+(3*t*(1-t)*(1-t))*p2+
4.113 + (3*t*t*(1-t))*p3+(t*t*t)*p4;
4.114 + }
4.115 + Bezier3 before(double t) const
4.116 + {
4.117 + xy p(conv(p1,p2,t));
4.118 + xy q(conv(p2,p3,t));
4.119 + xy r(conv(p3,p4,t));
4.120 + xy a(conv(p,q,t));
4.121 + xy b(conv(q,r,t));
4.122 + xy c(conv(a,b,t));
4.123 + return Bezier3(p1,p,a,c);
4.124 + }
4.125 +
4.126 + Bezier3 after(double t) const
4.127 + {
4.128 + xy p(conv(p1,p2,t));
4.129 + xy q(conv(p2,p3,t));
4.130 + xy r(conv(p3,p4,t));
4.131 + xy a(conv(p,q,t));
4.132 + xy b(conv(q,r,t));
4.133 + xy c(conv(a,b,t));
4.134 + return Bezier3(c,b,r,p4);
4.135 + }
4.136 + Bezier3 operator()(double a,double b) { return before(b).after(a/b); }
4.137 +
4.138 +};
4.139 +
4.140 +} //END OF NAMESPACE LEMON
4.141 +
4.142 +#endif // LEMON_BEZIER_H
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/src/lemon/graph_to_eps.h Tue Jan 11 09:15:25 2005 +0000
5.3 @@ -0,0 +1,597 @@
5.4 +/* -*- C++ -*-
5.5 + * src/lemon/graph_to_eps.h - Part of LEMON, a generic C++ optimization library
5.6 + *
5.7 + * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5.8 + * (Egervary Combinatorial Optimization Research Group, EGRES).
5.9 + *
5.10 + * Permission to use, modify and distribute this software is granted
5.11 + * provided that this copyright notice appears in all copies. For
5.12 + * precise terms see the accompanying LICENSE file.
5.13 + *
5.14 + * This software is provided "AS IS" with no warranty of any kind,
5.15 + * express or implied, and with no claim as to its suitability for any
5.16 + * purpose.
5.17 + *
5.18 + */
5.19 +
5.20 +#ifndef LEMON_GRAPH_TO_EPS_H
5.21 +#define LEMON_GRAPH_TO_EPS_H
5.22 +
5.23 +#include<iostream>
5.24 +#include<fstream>
5.25 +#include<sstream>
5.26 +#include<algorithm>
5.27 +#include<vector>
5.28 +
5.29 +#include<lemon/xy.h>
5.30 +#include<lemon/maps.h>
5.31 +#include<lemon/bezier.h>
5.32 +
5.33 +///\ingroup misc
5.34 +///\file
5.35 +///\brief Simple graph drawer
5.36 +///
5.37 +///\author Alpar Juttner
5.38 +
5.39 +namespace lemon {
5.40 +
5.41 +///Data structure representing RGB colors.
5.42 +
5.43 +///Data structure representing RGB colors.
5.44 +///\ingroup misc
5.45 +class Color
5.46 +{
5.47 + double _r,_g,_b;
5.48 +public:
5.49 + ///Default constructor
5.50 + Color() {}
5.51 + ///Constructor
5.52 + Color(double r,double g,double b) :_r(r),_g(g),_b(b) {};
5.53 + ///Returns the red component
5.54 + double getR() {return _r;}
5.55 + ///Returns the green component
5.56 + double getG() {return _g;}
5.57 + ///Returns the blue component
5.58 + double getB() {return _b;}
5.59 + ///Set the color components
5.60 + void set(double r,double g,double b) { _r=r;_g=g;_b=b; };
5.61 +};
5.62 +
5.63 +///Default traits class of \ref GraphToEps
5.64 +
5.65 +///Default traits class of \ref GraphToEps
5.66 +///
5.67 +///\c G is the type of the underlying graph.
5.68 +template<class G>
5.69 +struct DefaultGraphToEpsTraits
5.70 +{
5.71 + typedef G Graph;
5.72 + typedef typename Graph::Node Node;
5.73 + typedef typename Graph::NodeIt NodeIt;
5.74 + typedef typename Graph::Edge Edge;
5.75 + typedef typename Graph::EdgeIt EdgeIt;
5.76 + typedef typename Graph::InEdgeIt InEdgeIt;
5.77 + typedef typename Graph::OutEdgeIt OutEdgeIt;
5.78 +
5.79 +
5.80 + const Graph &g;
5.81 +
5.82 + std::ostream& os;
5.83 +
5.84 + ConstMap<typename Graph::Node,xy<double> > _coords;
5.85 + ConstMap<typename Graph::Node,double > _nodeSizes;
5.86 +
5.87 + ConstMap<typename Graph::Node,Color > _nodeColors;
5.88 + ConstMap<typename Graph::Edge,Color > _edgeColors;
5.89 +
5.90 + ConstMap<typename Graph::Edge,double > _edgeWidths;
5.91 +
5.92 + double _edgeWidthScale;
5.93 +
5.94 + double _nodeScale;
5.95 + double _xBorder, _yBorder;
5.96 + double _scale;
5.97 + double _nodeBorderQuotient;
5.98 +
5.99 + bool _drawArrows;
5.100 + double _arrowLength, _arrowWidth;
5.101 +
5.102 + bool _showNodes, _showEdges;
5.103 +
5.104 + bool _enableParallel;
5.105 + double _parEdgeDist;
5.106 +
5.107 + bool _showNodeText;
5.108 + ConstMap<typename Graph::Node,bool > _nodeTexts;
5.109 + double _nodeTextSize;
5.110 +
5.111 + bool _undir;
5.112 + bool _pleaseRemoveOsStream;
5.113 + ///Constructor
5.114 +
5.115 + ///Constructor
5.116 + ///\param _g is a reference to the graph to be printed
5.117 + ///\param _os is a reference to the output stream.
5.118 + ///\param _os is a reference to the output stream.
5.119 + ///\param _pros If it is \c true, then the \c ostream referenced by \c _os
5.120 + ///will be explicitly deallocated by the destructor.
5.121 + ///By default it is <tt>std::cout</tt>
5.122 + DefaultGraphToEpsTraits(const G &_g,std::ostream& _os=std::cout,
5.123 + bool _pros=false) :
5.124 + g(_g), os(_os),
5.125 + _coords(xy<double>(1,1)), _nodeSizes(1.0),
5.126 + _nodeColors(Color(1,1,1)), _edgeColors(Color(0,0,0)),
5.127 + _edgeWidths(1), _edgeWidthScale(0.3),
5.128 + _nodeScale(1.0), _xBorder(10), _yBorder(10), _scale(1.0),
5.129 + _nodeBorderQuotient(.1),
5.130 + _drawArrows(false), _arrowLength(1), _arrowWidth(0.3),
5.131 + _showNodes(true), _showEdges(true),
5.132 + _enableParallel(false), _parEdgeDist(1),
5.133 + _showNodeText(false), _nodeTexts(false), _nodeTextSize(1),
5.134 + _undir(false),
5.135 + _pleaseRemoveOsStream(_pros) {}
5.136 +};
5.137 +
5.138 +///Helper class to implement the named parameters of \ref graphToEps()
5.139 +
5.140 +///Helper class to implement the named parameters of \ref graphToEps()
5.141 +///\todo Is 'helper class' a good name for this?
5.142 +///
5.143 +template<class T> class GraphToEps : public T
5.144 +{
5.145 + typedef typename T::Graph Graph;
5.146 + typedef typename Graph::Node Node;
5.147 + typedef typename Graph::NodeIt NodeIt;
5.148 + typedef typename Graph::Edge Edge;
5.149 + typedef typename Graph::EdgeIt EdgeIt;
5.150 + typedef typename Graph::InEdgeIt InEdgeIt;
5.151 + typedef typename Graph::OutEdgeIt OutEdgeIt;
5.152 +
5.153 + bool dontPrint;
5.154 +
5.155 + class edgeLess {
5.156 + const Graph &g;
5.157 + public:
5.158 + edgeLess(const Graph &_g) : g(_g) {}
5.159 + bool operator()(Edge a,Edge b) const
5.160 + {
5.161 + Node ai=min(g.source(a),g.target(a));
5.162 + Node aa=max(g.source(a),g.target(a));
5.163 + Node bi=min(g.source(b),g.target(b));
5.164 + Node ba=max(g.source(b),g.target(b));
5.165 + return ai<bi ||
5.166 + (ai==bi && (aa < ba ||
5.167 + (aa==ba && ai==g.source(a) && bi==g.target(b))));
5.168 + }
5.169 + };
5.170 + bool isParallel(Edge e,Edge f) const
5.171 + {
5.172 + return (g.source(e)==g.source(f)&&g.target(e)==g.target(f))||
5.173 + (g.source(e)==g.target(f)&&g.target(e)==g.source(f));
5.174 + }
5.175 + static xy<double> rot(xy<double> v)
5.176 + {
5.177 + return xy<double>(v.y,-v.x);
5.178 + }
5.179 + template<class xy>
5.180 + static std::string psOut(const xy &p)
5.181 + {
5.182 + std::ostringstream os;
5.183 + os << p.x << ' ' << p.y;
5.184 + return os.str();
5.185 + }
5.186 +
5.187 +public:
5.188 + GraphToEps(const T &t) : T(t), dontPrint(false) {};
5.189 +
5.190 + template<class X> struct CoordsTraits : public T {
5.191 + const X &_coords;
5.192 + CoordsTraits(const T &t,const X &x) : T(t), _coords(x) {}
5.193 + };
5.194 + ///Sets the map of the node coordinates
5.195 +
5.196 + ///Sets the map of the node coordinates.
5.197 + ///\param x must be a node map with xy<double> or xy<int> values.
5.198 + template<class X> GraphToEps<CoordsTraits<X> > coords(const X &x) {
5.199 + dontPrint=true;
5.200 + return GraphToEps<CoordsTraits<X> >(CoordsTraits<X>(*this,x));
5.201 + }
5.202 + template<class X> struct NodeSizesTraits : public T {
5.203 + const X &_nodeSizes;
5.204 + NodeSizesTraits(const T &t,const X &x) : T(t), _nodeSizes(x) {}
5.205 + };
5.206 + ///Sets the map of the node sizes
5.207 +
5.208 + ///Sets the map of the node sizes
5.209 + ///\param x must be a node map with \c double (or convertible) values.
5.210 + template<class X> GraphToEps<NodeSizesTraits<X> > nodeSizes(const X &x)
5.211 + {
5.212 + dontPrint=true;
5.213 + return GraphToEps<NodeSizesTraits<X> >(NodeSizesTraits<X>(*this,x));
5.214 + }
5.215 + template<class X> struct NodeTextsTraits : public T {
5.216 + const X &_nodeTexts;
5.217 + NodeTextsTraits(const T &t,const X &x) : T(t), _nodeTexts(x) {}
5.218 + };
5.219 + ///Sets the text printed on the nodes
5.220 +
5.221 + ///Sets the text printed on the nodes
5.222 + ///\param x must be a node map with type that can be pushed to a standard
5.223 + ///ostream.
5.224 + template<class X> GraphToEps<NodeTextsTraits<X> > nodeTexts(const X &x)
5.225 + {
5.226 + dontPrint=true;
5.227 + _showNodeText=true;
5.228 + return GraphToEps<NodeTextsTraits<X> >(NodeTextsTraits<X>(*this,x));
5.229 + }
5.230 + template<class X> struct EdgeWidthsTraits : public T {
5.231 + const X &_edgeWidths;
5.232 + EdgeWidthsTraits(const T &t,const X &x) : T(t), _edgeWidths(x) {}
5.233 + };
5.234 + ///Sets the map of the edge widths
5.235 +
5.236 + ///Sets the map of the edge widths
5.237 + ///\param x must be a edge map with \c double (or convertible) values.
5.238 + template<class X> GraphToEps<EdgeWidthsTraits<X> > edgeWidths(const X &x)
5.239 + {
5.240 + dontPrint=true;
5.241 + return GraphToEps<EdgeWidthsTraits<X> >(EdgeWidthsTraits<X>(*this,x));
5.242 + }
5.243 +
5.244 + template<class X> struct NodeColorsTraits : public T {
5.245 + const X &_nodeColors;
5.246 + NodeColorsTraits(const T &t,const X &x) : T(t), _nodeColors(x) {}
5.247 + };
5.248 + ///Sets the map of the node colors
5.249 +
5.250 + ///Sets the map of the node colors
5.251 + ///\param x must be a node map with \ref Color values.
5.252 + template<class X> GraphToEps<NodeColorsTraits<X> >
5.253 + nodeColors(const X &x)
5.254 + {
5.255 + dontPrint=true;
5.256 + return GraphToEps<NodeColorsTraits<X> >(NodeColorsTraits<X>(*this,x));
5.257 + }
5.258 + template<class X> struct EdgeColorsTraits : public T {
5.259 + const X &_edgeColors;
5.260 + EdgeColorsTraits(const T &t,const X &x) : T(t), _edgeColors(x) {}
5.261 + };
5.262 + ///Sets the map of the edge colors
5.263 +
5.264 + ///Sets the map of the edge colors
5.265 + ///\param x must be a edge map with \ref Color values.
5.266 + template<class X> GraphToEps<EdgeColorsTraits<X> >
5.267 + edgeColors(const X &x)
5.268 + {
5.269 + dontPrint=true;
5.270 + return GraphToEps<EdgeColorsTraits<X> >(EdgeColorsTraits<X>(*this,x));
5.271 + }
5.272 + ///Sets a global scale factor for node sizes
5.273 +
5.274 + ///Sets a global scale factor for node sizes
5.275 + ///
5.276 + GraphToEps<T> &nodeScale(double d) {_nodeScale=d;return *this;}
5.277 + ///Sets a global scale factor for edge widths
5.278 +
5.279 + ///Sets a global scale factor for edge widths
5.280 + ///
5.281 + GraphToEps<T> &edgeWidthScale(double d) {_edgeWidthScale=d;return *this;}
5.282 + ///Sets a global scale factor for the whole picture
5.283 +
5.284 + ///Sets a global scale factor for the whole picture
5.285 + ///
5.286 + GraphToEps<T> &scale(double d) {_scale=d;return *this;}
5.287 + ///Sets the width of the border around the picture
5.288 +
5.289 + ///Sets the width of the border around the picture
5.290 + ///
5.291 + GraphToEps<T> &border(double b) {_xBorder=_yBorder=b;return *this;}
5.292 + ///Sets the width of the border around the picture
5.293 +
5.294 + ///Sets the width of the border around the picture
5.295 + ///
5.296 + GraphToEps<T> &border(double x, double y) {
5.297 + _xBorder=x;_yBorder=y;return *this;
5.298 + }
5.299 + ///Sets whether to draw arrows
5.300 +
5.301 + ///Sets whether to draw arrows
5.302 + ///
5.303 + GraphToEps<T> &drawArrows(bool b=true) {_drawArrows=b;return *this;}
5.304 + ///Sets the length of the arrowheads
5.305 +
5.306 + ///Sets the length of the arrowheads
5.307 + ///
5.308 + GraphToEps<T> &arrowLength(double d) {_arrowLength*=d;return *this;}
5.309 + ///Sets the width of the arrowheads
5.310 +
5.311 + ///Sets the width of the arrowheads
5.312 + ///
5.313 + GraphToEps<T> &arrowWidth(double d) {_arrowWidth*=d;return *this;}
5.314 +
5.315 + ///Enables parallel edges
5.316 +
5.317 + ///Enables parallel edges
5.318 + ///\todo Partially implemented
5.319 + GraphToEps<T> &enableParallel(bool b=true) {_enableParallel=b;return *this;}
5.320 +
5.321 + ///Sets the distance
5.322 +
5.323 + ///Sets the distance
5.324 + ///
5.325 + GraphToEps<T> &parEdgeDist(double d) {_parEdgeDist*=d;return *this;}
5.326 +
5.327 + ///Hides the edges
5.328 +
5.329 + ///Hides the edges
5.330 + ///
5.331 + GraphToEps<T> &hideEdges(bool b=true) {_showEdges=!b;return *this;}
5.332 + ///Hides the nodes
5.333 +
5.334 + ///Hides the nodes
5.335 + ///
5.336 + GraphToEps<T> &hideNodes(bool b=true) {_showNodes=!b;return *this;}
5.337 +
5.338 + ///Sets the size of the node texts
5.339 +
5.340 + ///Sets the size of the node texts
5.341 + ///
5.342 + GraphToEps<T> &nodeTextSize(double d) {_nodeTextSize=d;return *this;}
5.343 + ///Sets whether the the graph is undirected
5.344 +
5.345 + ///Sets whether the the graph is undirected
5.346 + ///
5.347 + GraphToEps<T> &undir(bool b=true) {_undir=b;return *this;}
5.348 + ///Sets whether the the graph is directed
5.349 +
5.350 + ///Sets whether the the graph is directed.
5.351 + ///Use it to show the undirected edges as a pair of directed ones.
5.352 + GraphToEps<T> &bidir(bool b=true) {_undir=!b;return *this;}
5.353 +
5.354 + ~GraphToEps()
5.355 + {
5.356 + if(dontPrint) return;
5.357 +
5.358 + os << "%!PS-Adobe-2.0 EPSF-2.0\n";
5.359 + //\todo: Chech whether the graph is empty.
5.360 + BoundingBox<double> bb;
5.361 + for(NodeIt n(g);n!=INVALID;++n) {
5.362 + double ns=_nodeSizes[n]*_nodeScale;
5.363 + xy<double> p(ns,ns);
5.364 + bb+=p+_coords[n];
5.365 + bb+=-p+_coords[n];
5.366 + }
5.367 + os << "%%BoundingBox: "
5.368 + << bb.left()* _scale-_xBorder << ' '
5.369 + << bb.bottom()*_scale-_yBorder << ' '
5.370 + << bb.right()* _scale+_xBorder << ' '
5.371 + << bb.top()* _scale+_yBorder << '\n';
5.372 + //x1 y1 x2 y2 x3 y3 cr cg cb w
5.373 + os << "/lb { setlinewidth setrgbcolor newpath moveto\n"
5.374 + << " 4 2 roll 1 index 1 index curveto stroke } bind def\n";
5.375 + os << "/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def\n";
5.376 + os << "/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def\n";
5.377 + // x y r cr cg cb
5.378 + os << "/n { setrgbcolor 2 index 2 index 2 index c fill\n"
5.379 + << " 0 0 0 setrgbcolor dup "
5.380 + << _nodeBorderQuotient << " mul setlinewidth "
5.381 + << 1+_nodeBorderQuotient/2 << " div c stroke\n"
5.382 + << " } bind def\n";
5.383 + os << "/arrl " << _arrowLength << " def\n";
5.384 + os << "/arrw " << _arrowWidth << " def\n";
5.385 + // l dx_norm dy_norm
5.386 + os << "/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def\n";
5.387 + //len w dx_norm dy_norm x1 y1 cr cg cb
5.388 + os << "/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def\n"
5.389 + << " /w exch def /len exch def\n"
5.390 + // << " 0.1 setlinewidth x1 y1 moveto dx len mul dy len mul rlineto stroke"
5.391 + << " newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto\n"
5.392 + << " len w sub arrl sub dx dy lrl\n"
5.393 + << " arrw dy dx neg lrl\n"
5.394 + << " dx arrl w add mul dy w 2 div arrw add mul sub\n"
5.395 + << " dy arrl w add mul dx w 2 div arrw add mul add rlineto\n"
5.396 + << " dx arrl w add mul neg dy w 2 div arrw add mul sub\n"
5.397 + << " dy arrl w add mul neg dx w 2 div arrw add mul add rlineto\n"
5.398 + << " arrw dy dx neg lrl\n"
5.399 + << " len w sub arrl sub neg dx dy lrl\n"
5.400 + << " closepath fill } bind def\n";
5.401 + os << "/cshow { 2 index 2 index moveto dup stringwidth pop\n"
5.402 + << " neg 2 div fosi .35 mul neg rmoveto show pop pop} def\n";
5.403 +
5.404 + os << "\ngsave\n";
5.405 + if(_scale!=1.0) os << _scale << " dup scale\n";
5.406 +
5.407 + os << "%Edges:\ngsave\n";
5.408 +
5.409 + if(_showEdges)
5.410 + if(_enableParallel) {
5.411 + std::vector<Edge> el;
5.412 + for(EdgeIt e(g);e!=INVALID;++e)
5.413 + if(!_undir||g.source(e)<g.target(e)) el.push_back(e);
5.414 + sort(el.begin(),el.end(),edgeLess(g));
5.415 +
5.416 + typename std::vector<Edge>::iterator j;
5.417 + for(typename std::vector<Edge>::iterator i=el.begin();i!=el.end();i=j) {
5.418 + for(j=i+1;j!=el.end()&&isParallel(*i,*j);++j) ;
5.419 +
5.420 + double sw=0;
5.421 + for(typename std::vector<Edge>::iterator e=i;e!=j;++e)
5.422 + sw+=_edgeWidths[*e]*_edgeWidthScale+_parEdgeDist;
5.423 + sw-=_parEdgeDist;
5.424 + sw/=-2.0;
5.425 + xy<double> d(_coords[g.target(*i)]-_coords[g.source(*i)]);
5.426 + double l=sqrt(d.normSquare());
5.427 + d/=l;
5.428 +
5.429 + for(typename std::vector<Edge>::iterator e=i;e!=j;++e) {
5.430 + sw+=_edgeWidths[*e]*_edgeWidthScale/2.0;
5.431 + xy<double> m(_coords[g.target(*e)]+_coords[g.source(*e)]);
5.432 + m=m/2.0+rot(d)*sw/.75;
5.433 + if(_drawArrows) {
5.434 + const int INERPOL_PREC=20;
5.435 + xy<double> s=_coords[g.source(*e)];
5.436 + xy<double> t=_coords[g.target(*e)];
5.437 + double rn=_nodeSizes[g.target(*e)]*_nodeScale;
5.438 + rn*=rn;
5.439 + Bezier3 bez(s,m,m,t);
5.440 + double t1=0,t2=1;
5.441 + for(int i=0;i<INERPOL_PREC;++i)
5.442 + if((bez((t1+t2)/2)-t).normSquare()>rn) t1=(t1+t2)/2;
5.443 + else t2=(t1+t2)/2;
5.444 + xy<double> apoint=bez((t1+t2)/2);
5.445 + rn = _nodeSizes[g.target(*e)]*_nodeScale+_arrowLength+
5.446 + _edgeWidths[*e]*_edgeWidthScale;
5.447 + rn*=rn;
5.448 + t1=0;t2=1;
5.449 + for(int i=0;i<INERPOL_PREC;++i)
5.450 + if((bez((t1+t2)/2)-t).normSquare()>rn) t1=(t1+t2)/2;
5.451 + else t2=(t1+t2)/2;
5.452 + xy<double> linend=bez((t1+t2)/2);
5.453 + bez=bez.before((t1+t2)/2);
5.454 + rn=_nodeSizes[g.source(*e)]*_nodeScale; rn*=rn;
5.455 + t1=0;t2=1;
5.456 + for(int i=0;i<INERPOL_PREC;++i)
5.457 + if((bez((t1+t2)/2)-s).normSquare()>rn) t2=(t1+t2)/2;
5.458 + else t1=(t1+t2)/2;
5.459 + bez=bez.after((t1+t2)/2);
5.460 + os << _edgeWidths[*e]*_edgeWidthScale << " setlinewidth "
5.461 + << _edgeColors[*e].getR() << ' '
5.462 + << _edgeColors[*e].getG() << ' '
5.463 + << _edgeColors[*e].getB() << " setrgbcolor newpath\n"
5.464 + << bez.p1.x << ' ' << bez.p1.y << " moveto\n"
5.465 + << bez.p2.x << ' ' << bez.p2.y << ' '
5.466 + << bez.p3.x << ' ' << bez.p3.y << ' '
5.467 + << bez.p4.x << ' ' << bez.p4.y << " curveto stroke\n";
5.468 + xy<double> dd(rot(linend-apoint));
5.469 + dd*=(_edgeWidths[*e]*_edgeWidthScale+_arrowWidth)/
5.470 + sqrt(dd.normSquare());
5.471 + os << "newpath " << psOut(apoint) << " moveto "
5.472 + << psOut(linend+dd) << " lineto "
5.473 + << psOut(linend-dd) << " lineto closepath fill\n";
5.474 + }
5.475 + else {
5.476 + os << _coords[g.source(*e)].x << ' '
5.477 + << _coords[g.source(*e)].y << ' '
5.478 + << m.x << ' ' << m.y << ' '
5.479 + << _coords[g.target(*e)].x << ' '
5.480 + << _coords[g.target(*e)].y << ' '
5.481 + << _edgeColors[*e].getR() << ' '
5.482 + << _edgeColors[*e].getG() << ' '
5.483 + << _edgeColors[*e].getB() << ' '
5.484 + << _edgeWidths[*e]*_edgeWidthScale << " lb\n";
5.485 + }
5.486 + sw+=_edgeWidths[*e]*_edgeWidthScale/2.0+_parEdgeDist;
5.487 + }
5.488 + }
5.489 + }
5.490 + else for(EdgeIt e(g);e!=INVALID;++e)
5.491 + if(!_undir||g.source(e)<g.target(e))
5.492 + if(_drawArrows) {
5.493 + xy<double> d(_coords[g.target(e)]-_coords[g.source(e)]);
5.494 + double l=sqrt(d.normSquare());
5.495 + d/=l;
5.496 + xy<double> x1(d*_nodeScale*_nodeSizes[g.source(e)]+
5.497 + _coords[g.source(e)]);
5.498 + os << l-(_nodeSizes[g.source(e)]+
5.499 + _nodeSizes[g.target(e)])*_nodeScale << ' '
5.500 + << _edgeWidths[e]*_edgeWidthScale << ' '
5.501 + << d.x << ' ' << d.y << ' '
5.502 + << x1.x << ' ' << x1.y << ' '
5.503 + << _edgeColors[e].getR() << ' '
5.504 + << _edgeColors[e].getG() << ' '
5.505 + << _edgeColors[e].getB() << " arr\n";
5.506 + }
5.507 + else os << _coords[g.source(e)].x << ' '
5.508 + << _coords[g.source(e)].y << ' '
5.509 + << _coords[g.target(e)].x << ' '
5.510 + << _coords[g.target(e)].y << ' '
5.511 + << _edgeColors[e].getR() << ' '
5.512 + << _edgeColors[e].getG() << ' '
5.513 + << _edgeColors[e].getB() << ' '
5.514 + << _edgeWidths[e]*_edgeWidthScale << " l\n";
5.515 + os << "grestore\n%Nodes:\ngsave\n";
5.516 + if(_showNodes)
5.517 + for(NodeIt n(g);n!=INVALID;++n)
5.518 + os << _coords[n].x << ' ' << _coords[n].y << ' '
5.519 + << _nodeSizes[n]*_nodeScale << ' '
5.520 + << _nodeColors[n].getR() << ' '
5.521 + << _nodeColors[n].getG() << ' '
5.522 + << _nodeColors[n].getB() << " n\n";
5.523 + if(_showNodeText) {
5.524 + os << "grestore\n%Node texts:\ngsave\n";
5.525 + os << "/fosi " << _nodeTextSize << " def\n";
5.526 + os << "(Helvetica) findfont fosi scalefont setfont\n";
5.527 + os << "0 0 0 setrgbcolor\n";
5.528 + for(NodeIt n(g);n!=INVALID;++n)
5.529 + os << _coords[n].x << ' ' << _coords[n].y
5.530 + << " (" << _nodeTexts[n] << ") cshow\n";
5.531 + }
5.532 + os << "grestore\ngrestore\n";
5.533 +
5.534 + //CleanUp:
5.535 + if(_pleaseRemoveOsStream) {delete &os;}
5.536 + }
5.537 +};
5.538 +
5.539 +
5.540 +///Generates an EPS file from a graph
5.541 +
5.542 +///\ingroup misc
5.543 +///Generates an EPS file from a graph.
5.544 +///\param g is a reference to the graph to be printed
5.545 +///\param os is a reference to the output stream.
5.546 +///By default it is <tt>std::cout</tt>
5.547 +///
5.548 +///This function also has a lot of \ref named-templ-param "named parameters",
5.549 +///they are declared as the members of class \ref GraphToEps. The following
5.550 +///example shows how to use these parameters.
5.551 +///\code
5.552 +/// graphToEps(g).scale(10).coords(coords)
5.553 +/// .nodeScale(2).nodeSizes(sizes)
5.554 +/// .edgeWidthScale(.4);
5.555 +///\endcode
5.556 +///\sa GraphToEps
5.557 +///\sa graphToEps(G &g, char *file_name)
5.558 +template<class G>
5.559 +GraphToEps<DefaultGraphToEpsTraits<G> >
5.560 +graphToEps(G &g, std::ostream& os=std::cout)
5.561 +{
5.562 + return
5.563 + GraphToEps<DefaultGraphToEpsTraits<G> >(DefaultGraphToEpsTraits<G>(g,os));
5.564 +}
5.565 +
5.566 +///Generates an EPS file from a graph
5.567 +
5.568 +//\ingroup misc
5.569 +///This function does the same as
5.570 +///\ref graphToEps(G &g,std::ostream& os)
5.571 +///but it writes its output into the file \c file_name
5.572 +///instead of a stream.
5.573 +///\sa graphToEps(G &g, std::ostream& os)
5.574 +template<class G>
5.575 +GraphToEps<DefaultGraphToEpsTraits<G> >
5.576 +graphToEps(G &g,char *file_name)
5.577 +{
5.578 + return GraphToEps<DefaultGraphToEpsTraits<G> >
5.579 + (DefaultGraphToEpsTraits<G>(g,*new std::ofstream(file_name),true));
5.580 +}
5.581 +
5.582 +//Generates an EPS file from a graph.
5.583 +//\param g is a reference to the graph to be printed
5.584 +//\param file_name is the output file_name.
5.585 +//
5.586 +//This function also has a lot of \ref named-templ-param "named parameters",
5.587 +//they are declared as the members of class \ref GraphToEps. The following
5.588 +//example shows how to use these parameters.
5.589 +//\code
5.590 +// graphToEps(g).scale(10).coords(coords)
5.591 +// .nodeScale(2).nodeSizes(sizes)
5.592 +// .edgeWidthScale(.4);
5.593 +//\endcode
5.594 +//\sa GraphToEps
5.595 +//\todo Avoid duplicated documentation
5.596 +//\bug Exception handling is missing? (Or we can just ignore it?)
5.597 +
5.598 +} //END OF NAMESPACE LEMON
5.599 +
5.600 +#endif // LEMON_GRAPH_TO_EPS_H
6.1 --- a/src/work/alpar/graph_to_eps.cc Tue Jan 11 09:09:50 2005 +0000
6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
6.3 @@ -1,647 +0,0 @@
6.4 -/* -*- C++ -*-
6.5 - * src/lemon/graph_to_eps.h - Part of LEMON, a generic C++ optimization library
6.6 - *
6.7 - * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
6.8 - * (Egervary Combinatorial Optimization Research Group, EGRES).
6.9 - *
6.10 - * Permission to use, modify and distribute this software is granted
6.11 - * provided that this copyright notice appears in all copies. For
6.12 - * precise terms see the accompanying LICENSE file.
6.13 - *
6.14 - * This software is provided "AS IS" with no warranty of any kind,
6.15 - * express or implied, and with no claim as to its suitability for any
6.16 - * purpose.
6.17 - *
6.18 - */
6.19 -
6.20 -#include <iostream>
6.21 -#include <fstream>
6.22 -#include <algorithm>
6.23 -#include<math.h>
6.24 -
6.25 -#include<lemon/xy.h>
6.26 -#include<lemon/maps.h>
6.27 -#include<lemon/list_graph.h>
6.28 -
6.29 -
6.30 -///\ingroup misc
6.31 -///\file
6.32 -///\brief Simple graph drawer
6.33 -
6.34 -namespace lemon {
6.35 -
6.36 -///Data structure representing RGB colors.
6.37 -
6.38 -///Data structure representing RGB colors.
6.39 -///\ingroup misc
6.40 -class Color
6.41 -{
6.42 - double _r,_g,_b;
6.43 -public:
6.44 - ///Default constructor
6.45 - Color() {}
6.46 - ///Constructor
6.47 - Color(double r,double g,double b) :_r(r),_g(g),_b(b) {};
6.48 - ///Returns the red component
6.49 - double getR() {return _r;}
6.50 - ///Returns the green component
6.51 - double getG() {return _g;}
6.52 - ///Returns the blue component
6.53 - double getB() {return _b;}
6.54 - ///Set the color components
6.55 - void set(double r,double g,double b) { _r=r;_g=g;_b=b; };
6.56 -};
6.57 -
6.58 -///Default traits class of \ref GraphToEps
6.59 -
6.60 -///Default traits class of \ref GraphToEps
6.61 -///
6.62 -///\c G is the type of the underlying graph.
6.63 -template<class G>
6.64 -struct DefaultGraphToEpsTraits
6.65 -{
6.66 - typedef G Graph;
6.67 - typedef typename Graph::Node Node;
6.68 - typedef typename Graph::NodeIt NodeIt;
6.69 - typedef typename Graph::Edge Edge;
6.70 - typedef typename Graph::EdgeIt EdgeIt;
6.71 - typedef typename Graph::InEdgeIt InEdgeIt;
6.72 - typedef typename Graph::OutEdgeIt OutEdgeIt;
6.73 -
6.74 -
6.75 - const Graph &g;
6.76 -
6.77 - std::ostream& os;
6.78 -
6.79 - ConstMap<typename Graph::Node,xy<double> > _coords;
6.80 - ConstMap<typename Graph::Node,double > _nodeSizes;
6.81 -
6.82 - ConstMap<typename Graph::Node,Color > _nodeColors;
6.83 - ConstMap<typename Graph::Edge,Color > _edgeColors;
6.84 -
6.85 - ConstMap<typename Graph::Edge,double > _edgeWidths;
6.86 -
6.87 - double _edgeWidthScale;
6.88 -
6.89 - double _nodeScale;
6.90 - double _xBorder, _yBorder;
6.91 - double _scale;
6.92 - double _nodeBorderQuotient;
6.93 -
6.94 - bool _drawArrows;
6.95 - double _arrowLength, _arrowWidth;
6.96 -
6.97 - bool _showNodes, _showEdges;
6.98 -
6.99 - bool _enableParallel;
6.100 - double _parEdgeDist;
6.101 -
6.102 - bool _showNodeText;
6.103 - ConstMap<typename Graph::Node,bool > _nodeTexts;
6.104 - double _nodeTextSize;
6.105 -
6.106 - bool _pleaseRemoveOsStream;
6.107 - ///Constructor
6.108 -
6.109 - ///Constructor
6.110 - ///\param _g is a reference to the graph to be printed
6.111 - ///\param _os is a reference to the output stream.
6.112 - ///\param _os is a reference to the output stream.
6.113 - ///\param _pros If it is \c true, then the \c ostream referenced by \c _os
6.114 - ///will be explicitly deallocated by the destructor.
6.115 - ///By default it is <tt>std::cout</tt>
6.116 - DefaultGraphToEpsTraits(const G &_g,std::ostream& _os=std::cout,
6.117 - bool _pros=false) :
6.118 - g(_g), os(_os),
6.119 - _coords(xy<double>(1,1)), _nodeSizes(1.0),
6.120 - _nodeColors(Color(1,1,1)), _edgeColors(Color(0,0,0)),
6.121 - _edgeWidths(1), _edgeWidthScale(0.3),
6.122 - _nodeScale(1.0), _xBorder(10), _yBorder(10), _scale(1.0),
6.123 - _nodeBorderQuotient(.1),
6.124 - _drawArrows(false), _arrowLength(1), _arrowWidth(0.3),
6.125 - _showNodes(true), _showEdges(true),
6.126 - _enableParallel(false), _parEdgeDist(1),
6.127 - _showNodeText(false), _nodeTexts(false), _nodeTextSize(1),
6.128 - _pleaseRemoveOsStream(_pros) {}
6.129 -};
6.130 -
6.131 -///Helper class to implement the named parameters of \ref graphToEps()
6.132 -
6.133 -///Helper class to implement the named parameters of \ref graphToEps()
6.134 -///\todo Is 'helper class' a good name for this?
6.135 -///
6.136 -template<class T> class GraphToEps : public T
6.137 -{
6.138 - typedef typename T::Graph Graph;
6.139 - typedef typename Graph::Node Node;
6.140 - typedef typename Graph::NodeIt NodeIt;
6.141 - typedef typename Graph::Edge Edge;
6.142 - typedef typename Graph::EdgeIt EdgeIt;
6.143 - typedef typename Graph::InEdgeIt InEdgeIt;
6.144 - typedef typename Graph::OutEdgeIt OutEdgeIt;
6.145 -
6.146 - bool dontPrint;
6.147 -
6.148 - class edgeLess {
6.149 - const Graph &g;
6.150 - public:
6.151 - edgeLess(const Graph &_g) : g(_g) {}
6.152 - bool operator()(Edge a,Edge b) const
6.153 - {
6.154 - Node ai=min(g.source(a),g.target(a));
6.155 - Node aa=max(g.source(a),g.target(a));
6.156 - Node bi=min(g.source(b),g.target(b));
6.157 - Node ba=max(g.source(b),g.target(b));
6.158 - return ai<bi ||
6.159 - (ai==bi && (aa < ba ||
6.160 - (aa==ba && ai==g.source(a) && bi==g.target(b))));
6.161 - }
6.162 - };
6.163 - bool isParallel(Edge e,Edge f) const
6.164 - {
6.165 - return (g.source(e)==g.source(f)&&g.target(e)==g.target(f))||
6.166 - (g.source(e)==g.target(f)&&g.target(e)==g.source(f));
6.167 - }
6.168 - static xy<double> rot(xy<double> v)
6.169 - {
6.170 - return xy<double>(v.y,-v.x);
6.171 - }
6.172 -
6.173 -public:
6.174 - GraphToEps(const T &t) : T(t), dontPrint(false) {};
6.175 -
6.176 - template<class X> struct CoordsTraits : public T {
6.177 - const X &_coords;
6.178 - CoordsTraits(const T &t,const X &x) : T(t), _coords(x) {}
6.179 - };
6.180 - ///Sets the map of the node coordinates
6.181 -
6.182 - ///Sets the map of the node coordinates.
6.183 - ///\param x must be a node map with xy<double> or xy<int> values.
6.184 - template<class X> GraphToEps<CoordsTraits<X> > coords(const X &x) {
6.185 - dontPrint=true;
6.186 - return GraphToEps<CoordsTraits<X> >(CoordsTraits<X>(*this,x));
6.187 - }
6.188 - template<class X> struct NodeSizesTraits : public T {
6.189 - const X &_nodeSizes;
6.190 - NodeSizesTraits(const T &t,const X &x) : T(t), _nodeSizes(x) {}
6.191 - };
6.192 - ///Sets the map of the node sizes
6.193 -
6.194 - ///Sets the map of the node sizes
6.195 - ///\param x must be a node map with \c double (or convertible) values.
6.196 - template<class X> GraphToEps<NodeSizesTraits<X> > nodeSizes(const X &x)
6.197 - {
6.198 - dontPrint=true;
6.199 - return GraphToEps<NodeSizesTraits<X> >(NodeSizesTraits<X>(*this,x));
6.200 - }
6.201 - template<class X> struct NodeTextsTraits : public T {
6.202 - const X &_nodeTexts;
6.203 - NodeTextsTraits(const T &t,const X &x) : T(t), _nodeTexts(x) {}
6.204 - };
6.205 - ///Sets the text printed on the nodes
6.206 -
6.207 - ///Sets the text printed on the nodes
6.208 - ///\param x must be a node map with type that can be pushed to a standard
6.209 - ///ostream.
6.210 - template<class X> GraphToEps<NodeTextsTraits<X> > nodeTexts(const X &x)
6.211 - {
6.212 - dontPrint=true;
6.213 - _showNodeText=true;
6.214 - return GraphToEps<NodeTextsTraits<X> >(NodeTextsTraits<X>(*this,x));
6.215 - }
6.216 - template<class X> struct EdgeWidthsTraits : public T {
6.217 - const X &_edgeWidths;
6.218 - EdgeWidthsTraits(const T &t,const X &x) : T(t), _edgeWidths(x) {}
6.219 - };
6.220 - ///Sets the map of the edge widths
6.221 -
6.222 - ///Sets the map of the edge widths
6.223 - ///\param x must be a edge map with \c double (or convertible) values.
6.224 - template<class X> GraphToEps<EdgeWidthsTraits<X> > edgeWidths(const X &x)
6.225 - {
6.226 - dontPrint=true;
6.227 - return GraphToEps<EdgeWidthsTraits<X> >(EdgeWidthsTraits<X>(*this,x));
6.228 - }
6.229 -
6.230 - template<class X> struct NodeColorsTraits : public T {
6.231 - const X &_nodeColors;
6.232 - NodeColorsTraits(const T &t,const X &x) : T(t), _nodeColors(x) {}
6.233 - };
6.234 - ///Sets the map of the node colors
6.235 -
6.236 - ///Sets the map of the node colors
6.237 - ///\param x must be a node map with \ref Color values.
6.238 - template<class X> GraphToEps<NodeColorsTraits<X> >
6.239 - nodeColors(const X &x)
6.240 - {
6.241 - dontPrint=true;
6.242 - return GraphToEps<NodeColorsTraits<X> >(NodeColorsTraits<X>(*this,x));
6.243 - }
6.244 - template<class X> struct EdgeColorsTraits : public T {
6.245 - const X &_edgeColors;
6.246 - EdgeColorsTraits(const T &t,const X &x) : T(t), _edgeColors(x) {}
6.247 - };
6.248 - ///Sets the map of the edge colors
6.249 -
6.250 - ///Sets the map of the edge colors
6.251 - ///\param x must be a edge map with \ref Color values.
6.252 - template<class X> GraphToEps<EdgeColorsTraits<X> >
6.253 - edgeColors(const X &x)
6.254 - {
6.255 - dontPrint=true;
6.256 - return GraphToEps<EdgeColorsTraits<X> >(EdgeColorsTraits<X>(*this,x));
6.257 - }
6.258 - ///Sets a global scale factor for node sizes
6.259 -
6.260 - ///Sets a global scale factor for node sizes
6.261 - ///
6.262 - GraphToEps<T> &nodeScale(double d) {_nodeScale=d;return *this;}
6.263 - ///Sets a global scale factor for edge widths
6.264 -
6.265 - ///Sets a global scale factor for edge widths
6.266 - ///
6.267 - GraphToEps<T> &edgeWidthScale(double d) {_edgeWidthScale=d;return *this;}
6.268 - ///Sets a global scale factor for the whole picture
6.269 -
6.270 - ///Sets a global scale factor for the whole picture
6.271 - ///
6.272 - GraphToEps<T> &scale(double d) {_scale=d;return *this;}
6.273 - ///Sets the width of the border around the picture
6.274 -
6.275 - ///Sets the width of the border around the picture
6.276 - ///
6.277 - GraphToEps<T> &border(double b) {_xBorder=_yBorder=b;return *this;}
6.278 - ///Sets the width of the border around the picture
6.279 -
6.280 - ///Sets the width of the border around the picture
6.281 - ///
6.282 - GraphToEps<T> &border(double x, double y) {
6.283 - _xBorder=x;_yBorder=y;return *this;
6.284 - }
6.285 - ///Sets whether to draw arrows
6.286 -
6.287 - ///Sets whether to draw arrows
6.288 - ///
6.289 - GraphToEps<T> &drawArrows(bool b=true) {_drawArrows=b;return *this;}
6.290 - ///Sets the length of the arrowheads
6.291 -
6.292 - ///Sets the length of the arrowheads
6.293 - ///
6.294 - GraphToEps<T> &arrowLength(double d) {_arrowLength*=d;return *this;}
6.295 - ///Sets the width of the arrowheads
6.296 -
6.297 - ///Sets the width of the arrowheads
6.298 - ///
6.299 - GraphToEps<T> &arrowWidth(double d) {_arrowWidth*=d;return *this;}
6.300 -
6.301 - ///Enables parallel edges
6.302 -
6.303 - ///Enables parallel edges
6.304 - ///\todo Partially implemented
6.305 - GraphToEps<T> &enableParallel(bool b=true) {_enableParallel=b;return *this;}
6.306 -
6.307 - ///Sets the distance
6.308 -
6.309 - ///Sets the distance
6.310 - ///
6.311 - GraphToEps<T> &parEdgeDist(double d) {_parEdgeDist*=d;return *this;}
6.312 -
6.313 - ///Hides the edges
6.314 -
6.315 - ///Hides the edges
6.316 - ///
6.317 - GraphToEps<T> &hideEdges(bool b=true) {_showEdges=!b;return *this;}
6.318 - ///Hides the nodes
6.319 -
6.320 - ///Hides the nodes
6.321 - ///
6.322 - GraphToEps<T> &hideNodes(bool b=true) {_showNodes=!b;return *this;}
6.323 -
6.324 - ///Sets the size of the node texts
6.325 -
6.326 - ///Sets the size of the node texts
6.327 - ///
6.328 - GraphToEps<T> &nodeTextSize(double d) {_nodeTextSize=d;return *this;}
6.329 -
6.330 -
6.331 - ~GraphToEps()
6.332 - {
6.333 - if(dontPrint) return;
6.334 -
6.335 - os << "%!PS-Adobe-2.0 EPSF-2.0\n";
6.336 - //\todo: Chech whether the graph is empty.
6.337 - BoundingBox<double> bb;
6.338 - for(NodeIt n(g);n!=INVALID;++n) {
6.339 - double ns=_nodeSizes[n]*_nodeScale;
6.340 - xy<double> p(ns,ns);
6.341 - bb+=p+_coords[n];
6.342 - bb+=-p+_coords[n];
6.343 - }
6.344 - os << "%%BoundingBox: "
6.345 - << bb.left()* _scale-_xBorder << ' '
6.346 - << bb.bottom()*_scale-_yBorder << ' '
6.347 - << bb.right()* _scale+_xBorder << ' '
6.348 - << bb.top()* _scale+_yBorder << '\n';
6.349 - //x1 y1 x2 y2 x3 y3 cr cg cb w
6.350 - os << "/lb { setlinewidth setrgbcolor newpath moveto\n"
6.351 - << " 4 2 roll 1 index 1 index curveto stroke } bind def\n";
6.352 - os << "/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def\n";
6.353 - os << "/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def\n";
6.354 - // x y r cr cg cb
6.355 - os << "/n { setrgbcolor 2 index 2 index 2 index c fill\n"
6.356 - << " 0 0 0 setrgbcolor dup "
6.357 - << _nodeBorderQuotient << " mul setlinewidth "
6.358 - << 1+_nodeBorderQuotient/2 << " div c stroke\n"
6.359 - << " } bind def\n";
6.360 - os << "/arrl " << _arrowLength << " def\n";
6.361 - os << "/arrw " << _arrowWidth << " def\n";
6.362 - // l dx_norm dy_norm
6.363 - os << "/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def\n";
6.364 - //len w dx_norm dy_norm x1 y1 cr cg cb
6.365 - os << "/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def\n"
6.366 - << " /w exch def /len exch def\n"
6.367 - // << " 0.1 setlinewidth x1 y1 moveto dx len mul dy len mul rlineto stroke"
6.368 - << " newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto\n"
6.369 - << " len w sub arrl sub dx dy lrl\n"
6.370 - << " arrw dy dx neg lrl\n"
6.371 - << " dx arrl w add mul dy w 2 div arrw add mul sub\n"
6.372 - << " dy arrl w add mul dx w 2 div arrw add mul add rlineto\n"
6.373 - << " dx arrl w add mul neg dy w 2 div arrw add mul sub\n"
6.374 - << " dy arrl w add mul neg dx w 2 div arrw add mul add rlineto\n"
6.375 - << " arrw dy dx neg lrl\n"
6.376 - << " len w sub arrl sub neg dx dy lrl\n"
6.377 - << " closepath fill } bind def\n";
6.378 - os << "/cshow { 2 index 2 index moveto\n"
6.379 - << " dup stringwidth pop neg 2 div fosi .35 mul neg rmoveto show pop pop} def\n";
6.380 -
6.381 - os << "\ngsave\n";
6.382 - if(_scale!=1.0) os << _scale << " dup scale\n";
6.383 -
6.384 - os << "%Edges:\ngsave\n";
6.385 -
6.386 - if(_showEdges)
6.387 - if(_enableParallel) {
6.388 - vector<Edge> el;
6.389 - for(EdgeIt e(g);e!=INVALID;++e) el.push_back(e);
6.390 - sort(el.begin(),el.end(),edgeLess(g));
6.391 -
6.392 - typename vector<Edge>::iterator j;
6.393 - for(typename vector<Edge>::iterator i=el.begin();i!=el.end();i=j) {
6.394 - for(j=i+1;j!=el.end()&&isParallel(*i,*j);++j) ;
6.395 -
6.396 - if(_drawArrows) {
6.397 - // xy<double> d(_coords[g.target(e)]-_coords[g.source(e)]);
6.398 - // double l=sqrt(d.normSquare());
6.399 - // d/=l;
6.400 - // xy<double> x1(d*_nodeScale*_nodeSizes[g.source(e)]+
6.401 - // _coords[g.source(e)]);
6.402 - // os << l-(_nodeSizes[g.source(e)]+
6.403 - // _nodeSizes[g.target(e)])*_nodeScale << ' '
6.404 - // << _edgeWidths[e]*_edgeWidthScale << ' '
6.405 - // << d.x << ' ' << d.y << ' '
6.406 - // << x1.x << ' ' << x1.y << ' '
6.407 - // << _edgeColors[e].getR() << ' '
6.408 - // << _edgeColors[e].getG() << ' '
6.409 - // << _edgeColors[e].getB() << " arr\n";
6.410 - }
6.411 - else {
6.412 - double sw=0;
6.413 - for(typename vector<Edge>::iterator e=i;e!=j;++e)
6.414 - sw+=_edgeWidths[*e]*_edgeWidthScale+_parEdgeDist;
6.415 - sw-=_parEdgeDist;
6.416 - sw/=-2.0;
6.417 - xy<double> d(_coords[g.target(*i)]-_coords[g.source(*i)]);
6.418 - double l=sqrt(d.normSquare());
6.419 - d/=l;
6.420 - for(typename vector<Edge>::iterator e=i;e!=j;++e) {
6.421 - sw+=_edgeWidths[*e]*_edgeWidthScale/2.0;
6.422 - xy<double> m(_coords[g.target(*e)]+_coords[g.source(*e)]);
6.423 - m=m/2.0+rot(d)*sw/.75;
6.424 - os << _coords[g.source(*e)].x << ' '
6.425 - << _coords[g.source(*e)].y << ' '
6.426 - << m.x << ' ' << m.y << ' '
6.427 - << _coords[g.target(*e)].x << ' '
6.428 - << _coords[g.target(*e)].y << ' '
6.429 - << _edgeColors[*e].getR() << ' '
6.430 - << _edgeColors[*e].getG() << ' '
6.431 - << _edgeColors[*e].getB() << ' '
6.432 - << _edgeWidths[*e]*_edgeWidthScale << " lb\n";
6.433 - sw+=_edgeWidths[*e]*_edgeWidthScale/2.0+_parEdgeDist;
6.434 - }
6.435 - }
6.436 - }
6.437 - }
6.438 - else for(NodeIt n(g);n!=INVALID;++n)
6.439 - for(OutEdgeIt e(g,n);e!=INVALID;++e)
6.440 - if(_drawArrows) {
6.441 - xy<double> d(_coords[g.target(e)]-_coords[g.source(e)]);
6.442 - double l=sqrt(d.normSquare());
6.443 - d/=l;
6.444 - xy<double> x1(d*_nodeScale*_nodeSizes[g.source(e)]+
6.445 - _coords[g.source(e)]);
6.446 - os << l-(_nodeSizes[g.source(e)]+
6.447 - _nodeSizes[g.target(e)])*_nodeScale << ' '
6.448 - << _edgeWidths[e]*_edgeWidthScale << ' '
6.449 - << d.x << ' ' << d.y << ' '
6.450 - << x1.x << ' ' << x1.y << ' '
6.451 - << _edgeColors[e].getR() << ' '
6.452 - << _edgeColors[e].getG() << ' '
6.453 - << _edgeColors[e].getB() << " arr\n";
6.454 - }
6.455 - else os << _coords[g.source(e)].x << ' '
6.456 - << _coords[g.source(e)].y << ' '
6.457 - << _coords[g.target(e)].x << ' '
6.458 - << _coords[g.target(e)].y << ' '
6.459 - << _edgeColors[e].getR() << ' '
6.460 - << _edgeColors[e].getG() << ' '
6.461 - << _edgeColors[e].getB() << ' '
6.462 - << _edgeWidths[e]*_edgeWidthScale << " l\n";
6.463 - os << "grestore\n%Nodes:\ngsave\n";
6.464 - if(_showNodes)
6.465 - for(NodeIt n(g);n!=INVALID;++n)
6.466 - os << _coords[n].x << ' ' << _coords[n].y << ' '
6.467 - << _nodeSizes[n]*_nodeScale << ' '
6.468 - << _nodeColors[n].getR() << ' '
6.469 - << _nodeColors[n].getG() << ' '
6.470 - << _nodeColors[n].getB() << " n\n";
6.471 - if(_showNodeText) {
6.472 - os << "grestore\n%Node texts:\ngsave\n";
6.473 - os << "/fosi " << _nodeTextSize << " def\n";
6.474 - os << "(Helvetica) findfont fosi scalefont setfont\n";
6.475 - os << "0 0 0 setrgbcolor\n";
6.476 - for(NodeIt n(g);n!=INVALID;++n)
6.477 - os << _coords[n].x << ' ' << _coords[n].y
6.478 - << " (" << _nodeTexts[n] << ") cshow\n";
6.479 - }
6.480 - os << "grestore\ngrestore\n";
6.481 -
6.482 - //CleanUp:
6.483 - if(_pleaseRemoveOsStream) {delete &os;}
6.484 - }
6.485 -};
6.486 -
6.487 -
6.488 -///Generates an EPS file from a graph
6.489 -
6.490 -///\ingroup misc
6.491 -///Generates an EPS file from a graph.
6.492 -///\param g is a reference to the graph to be printed
6.493 -///\param os is a reference to the output stream.
6.494 -///By default it is <tt>std::cout</tt>
6.495 -///
6.496 -///This function also has a lot of \ref named-templ-param "named parameters",
6.497 -///they are declared as the members of class \ref GraphToEps. The following
6.498 -///example shows how to use these parameters.
6.499 -///\code
6.500 -/// graphToEps(g).scale(10).coords(coords)
6.501 -/// .nodeScale(2).nodeSizes(sizes)
6.502 -/// .edgeWidthScale(.4);
6.503 -///\endcode
6.504 -///\sa GraphToEps
6.505 -///\sa graphToEps(G &g, char *file_name)
6.506 -template<class G>
6.507 -GraphToEps<DefaultGraphToEpsTraits<G> >
6.508 -graphToEps(G &g, std::ostream& os=std::cout)
6.509 -{
6.510 - return
6.511 - GraphToEps<DefaultGraphToEpsTraits<G> >(DefaultGraphToEpsTraits<G>(g,os));
6.512 -}
6.513 -
6.514 -///Generates an EPS file from a graph
6.515 -
6.516 -//\ingroup misc
6.517 -///This function does the same as
6.518 -///\ref graphToEps(G &g,std::ostream& os)
6.519 -///but it writes its output into the file \c file_name
6.520 -///instead of a stream.
6.521 -///\sa graphToEps(G &g, std::ostream& os)
6.522 -template<class G>
6.523 -GraphToEps<DefaultGraphToEpsTraits<G> >
6.524 -graphToEps(G &g,char *file_name)
6.525 -{
6.526 - return GraphToEps<DefaultGraphToEpsTraits<G> >
6.527 - (DefaultGraphToEpsTraits<G>(g,*new ofstream(file_name),true));
6.528 -}
6.529 -
6.530 -//Generates an EPS file from a graph.
6.531 -//\param g is a reference to the graph to be printed
6.532 -//\param file_name is the output file_name.
6.533 -//
6.534 -//This function also has a lot of \ref named-templ-param "named parameters",
6.535 -//they are declared as the members of class \ref GraphToEps. The following
6.536 -//example shows how to use these parameters.
6.537 -//\code
6.538 -// graphToEps(g).scale(10).coords(coords)
6.539 -// .nodeScale(2).nodeSizes(sizes)
6.540 -// .edgeWidthScale(.4);
6.541 -//\endcode
6.542 -//\sa GraphToEps
6.543 -//\todo Avoid duplicated documentation
6.544 -//\bug Exception handling is missing? (Or we can just ignore it?)
6.545 -
6.546 -}
6.547 -
6.548 -using namespace lemon;
6.549 -
6.550 -class ColorSet : public MapBase<int,Color>
6.551 -{
6.552 -public:
6.553 - Color operator[](int i) const
6.554 - {
6.555 - switch(i%8){
6.556 - case 0: return Color(0,0,0);
6.557 - case 1: return Color(1,0,0);
6.558 - case 2: return Color(0,1,0);
6.559 - case 3: return Color(0,0,1);
6.560 - case 4: return Color(1,1,0);
6.561 - case 5: return Color(1,0,1);
6.562 - case 6: return Color(0,1,1);
6.563 - case 7: return Color(1,1,1);
6.564 - }
6.565 - return Color(0,0,0);
6.566 - }
6.567 -} colorSet;
6.568 -
6.569 -class IdMap :public MapBase<ListGraph::Node,int>
6.570 -{
6.571 - const ListGraph &g;
6.572 -public:
6.573 - IdMap(const ListGraph &_g) :g(_g) {}
6.574 - Value operator[](Key n) const { return g.id(n); }
6.575 -};
6.576 -
6.577 -
6.578 -
6.579 -int main()
6.580 -{
6.581 - ListGraph g;
6.582 - typedef ListGraph::Node Node;
6.583 - typedef ListGraph::NodeIt NodeIt;
6.584 - typedef ListGraph::Edge Edge;
6.585 - typedef xy<int> Xy;
6.586 -
6.587 - Node n1=g.addNode();
6.588 - Node n2=g.addNode();
6.589 - Node n3=g.addNode();
6.590 - Node n4=g.addNode();
6.591 - Node n5=g.addNode();
6.592 -
6.593 - ListGraph::NodeMap<Xy> coords(g);
6.594 - ListGraph::NodeMap<double> sizes(g);
6.595 - ListGraph::NodeMap<int> colors(g);
6.596 - ListGraph::EdgeMap<int> ecolors(g);
6.597 - ListGraph::EdgeMap<int> widths(g);
6.598 -
6.599 - coords[n1]=Xy(50,50); sizes[n1]=1; colors[n1]=1;
6.600 - coords[n2]=Xy(50,70); sizes[n2]=2; colors[n2]=2;
6.601 - coords[n3]=Xy(70,70); sizes[n3]=1; colors[n3]=3;
6.602 - coords[n4]=Xy(70,50); sizes[n4]=2; colors[n4]=4;
6.603 - coords[n5]=Xy(85,60); sizes[n5]=3; colors[n5]=5;
6.604 -
6.605 - Edge e;
6.606 -
6.607 - e=g.addEdge(n1,n2); ecolors[e]=0; widths[e]=1;
6.608 - e=g.addEdge(n2,n3); ecolors[e]=0; widths[e]=1;
6.609 - e=g.addEdge(n3,n5); ecolors[e]=0; widths[e]=3;
6.610 - e=g.addEdge(n5,n4); ecolors[e]=0; widths[e]=1;
6.611 - e=g.addEdge(n4,n1); ecolors[e]=0; widths[e]=1;
6.612 - e=g.addEdge(n2,n4); ecolors[e]=1; widths[e]=2;
6.613 - e=g.addEdge(n3,n4); ecolors[e]=2; widths[e]=1;
6.614 -
6.615 - IdMap id(g);
6.616 -
6.617 - graphToEps(g,"proba.eps").scale(10).coords(coords).
6.618 - nodeScale(2).nodeSizes(sizes).
6.619 - nodeColors(composeMap(colorSet,colors)).
6.620 - edgeColors(composeMap(colorSet,ecolors)).
6.621 - edgeWidthScale(.4).edgeWidths(widths).
6.622 - nodeTexts(id).nodeTextSize(3);
6.623 -
6.624 - graphToEps(g,"proba_arr.eps").scale(10).coords(coords).
6.625 - nodeScale(2).nodeSizes(sizes).
6.626 - nodeColors(composeMap(colorSet,colors)).
6.627 - edgeColors(composeMap(colorSet,ecolors)).
6.628 - edgeWidthScale(.4).edgeWidths(widths).
6.629 - nodeTexts(id).nodeTextSize(3).
6.630 - drawArrows().arrowWidth(1).arrowLength(1);
6.631 -
6.632 - e=g.addEdge(n1,n4); ecolors[e]=2; widths[e]=1;
6.633 - e=g.addEdge(n4,n1); ecolors[e]=1; widths[e]=2;
6.634 -
6.635 - e=g.addEdge(n1,n2); ecolors[e]=1; widths[e]=1;
6.636 - e=g.addEdge(n1,n2); ecolors[e]=2; widths[e]=1;
6.637 - e=g.addEdge(n1,n2); ecolors[e]=3; widths[e]=1;
6.638 - e=g.addEdge(n1,n2); ecolors[e]=4; widths[e]=1;
6.639 - e=g.addEdge(n1,n2); ecolors[e]=5; widths[e]=1;
6.640 - e=g.addEdge(n1,n2); ecolors[e]=6; widths[e]=1;
6.641 - e=g.addEdge(n1,n2); ecolors[e]=7; widths[e]=1;
6.642 -
6.643 - graphToEps(g,"proba_par.eps").scale(10).coords(coords).
6.644 - nodeScale(2).nodeSizes(sizes).
6.645 - nodeColors(composeMap(colorSet,colors)).
6.646 - edgeColors(composeMap(colorSet,ecolors)).
6.647 - edgeWidthScale(.4).edgeWidths(widths).
6.648 - nodeTexts(id).nodeTextSize(3).
6.649 - enableParallel().parEdgeDist(1.5);
6.650 -}