[Lemon-commits] [lemon_svn] alpar: r1444 - in hugo/trunk/src/work: . alpar
Lemon SVN
svn at lemon.cs.elte.hu
Mon Nov 6 20:45:29 CET 2006
Author: alpar
Date: Tue Jan 4 23:16:46 2005
New Revision: 1444
Modified:
hugo/trunk/src/work/Doxyfile
hugo/trunk/src/work/alpar/graph_to_eps.cc
Log:
Several new named parameters and documentation added to graphToEps().
Modified: hugo/trunk/src/work/Doxyfile
==============================================================================
--- hugo/trunk/src/work/Doxyfile (original)
+++ hugo/trunk/src/work/Doxyfile Tue Jan 4 23:16:46 2005
@@ -407,6 +407,7 @@
jacint/graph_gen.h \
marci/max_bipartite_matching.h \
marci/bipartite_graph_wrapper.h \
+ alpar/graph_to_eps.cc \
deba \
Modified: hugo/trunk/src/work/alpar/graph_to_eps.cc
==============================================================================
--- hugo/trunk/src/work/alpar/graph_to_eps.cc (original)
+++ hugo/trunk/src/work/alpar/graph_to_eps.cc Tue Jan 4 23:16:46 2005
@@ -1,32 +1,41 @@
+#include<math.h>
#include<lemon/xy.h>
#include<lemon/maps.h>
#include<lemon/list_graph.h>
-///\file
+
+///\file \ingroup misc
///Simple graph drawer
namespace lemon {
- ///\e
+///Data structure representing RGB colors.
+
+///Data structure representing RGB colors.
+///\ingroup misc
class Color
{
double _r,_g,_b;
public:
- ///\e
+ ///Default constructor
Color() {}
- ///\e
+ ///Constructor
Color(double r,double g,double b) :_r(r),_g(g),_b(b) {};
- ///\e
+ ///Returns the red component
double getR() {return _r;}
- ///\e
+ ///Returns the green component
double getG() {return _g;}
- ///\e
+ ///Returns the blue component
double getB() {return _b;}
- ///\e
+ ///Set the color components
void set(double r,double g,double b) { _r=r;_g=g;_b=b; };
};
- ///\e
+///Default traits class of \ref GraphToEps
+
+///Default traits class of \ref GraphToEps
+///
+///\c G is the type of the underlying graph.
template<class G>
struct DefaultGraphToEpsTraits
{
@@ -40,21 +49,42 @@
const Graph &g;
- ConstMap<typename Graph::Node,xy<double> > coords;
- ConstMap<typename Graph::Node,double > nodeSizes;
+ ConstMap<typename Graph::Node,xy<double> > _coords;
+ ConstMap<typename Graph::Node,double > _nodeSizes;
- ConstMap<typename Graph::Node,Color > nodeColors;
- ConstMap<typename Graph::Edge,Color > edgeColors;
- double nodeSizeScalar;
- double xBorder, yBorder;
-
- DefaultGraphToEpsTraits(G &_g) :
- g(_g), coords(xy<double>(1,1)), nodeSizes(1.0),
- nodeColors(Color(1,1,1)), edgeColors(Color(0,0,0)),
- nodeSizeScalar(1.0), xBorder(10), yBorder(10) {}
+ ConstMap<typename Graph::Node,Color > _nodeColors;
+ ConstMap<typename Graph::Edge,Color > _edgeColors;
+
+ ConstMap<typename Graph::Edge,double > _edgeWidths;
+
+ double _edgeWidthScale;
+
+ double _nodeScale;
+ double _xBorder, _yBorder;
+ double _scale;
+ double _nodeBorderQuotient;
+
+ bool _drawArrows;
+ double _arrowLength, _arrowWidth;
+
+ ///Constructor
+
+ ///Constructor
+ ///\param _g is a reference to the underlying graph
+ DefaultGraphToEpsTraits(const G &_g) :
+ g(_g), _coords(xy<double>(1,1)), _nodeSizes(1.0),
+ _nodeColors(Color(1,1,1)), _edgeColors(Color(0,0,0)),
+ _edgeWidths(1), _edgeWidthScale(0.3),
+ _nodeScale(1.0), _xBorder(10), _yBorder(10), _scale(1.0),
+ _nodeBorderQuotient(.1),
+ _drawArrows(false), _arrowLength(1), _arrowWidth(0.3) {}
};
- ///\e
+///Helper class to implement the named parameters of \ref graphToEps()
+
+///Helper class to implement the named parameters of \ref graphToEps()
+///\todo Is 'helper class' a good name for this?
+///
template<class T> class GraphToEps : public T
{
typedef typename T::Graph Graph;
@@ -70,49 +100,115 @@
public:
GraphToEps(const T &t) : T(t), dontPrint(false) {};
- template<class X> struct SetCoordsTraits : public T {
- const X &coords;
- SetCoordsTraits(const T &t,const X &x) : T(t), coords(x) {}
+ template<class X> struct CoordsTraits : public T {
+ const X &_coords;
+ CoordsTraits(const T &t,const X &x) : T(t), _coords(x) {}
};
- ///\e
- template<class X> GraphToEps<SetCoordsTraits<X> > setCoords(const X &x) {
+ ///Sets the map of the node coordinates
+
+ ///Sets the map of the node coordinates.
+ ///\param x must be a node map with xy<double> or xy<int> values.
+ template<class X> GraphToEps<CoordsTraits<X> > coords(const X &x) {
dontPrint=true;
- return GraphToEps<SetCoordsTraits<X> >(SetCoordsTraits<X>(*this,x));
+ return GraphToEps<CoordsTraits<X> >(CoordsTraits<X>(*this,x));
}
- template<class X> struct SetNodeSizesTraits : public T {
- const X &nodeSizes;
- SetNodeSizesTraits(const T &t,const X &x) : T(t), nodeSizes(x) {}
+ template<class X> struct NodeSizesTraits : public T {
+ const X &_nodeSizes;
+ NodeSizesTraits(const T &t,const X &x) : T(t), _nodeSizes(x) {}
};
- ///\e
- template<class X> GraphToEps<SetNodeSizesTraits<X> > setNodeSizes(const X &x)
+ ///Sets the map of the node sizes
+
+ ///Sets the map of the node sizes
+ ///\param x must be a node map with \c double (or convertible) values.
+ template<class X> GraphToEps<NodeSizesTraits<X> > nodeSizes(const X &x)
{
dontPrint=true;
- return GraphToEps<SetNodeSizesTraits<X> >(SetNodeSizesTraits<X>(*this,x));
+ return GraphToEps<NodeSizesTraits<X> >(NodeSizesTraits<X>(*this,x));
}
- template<class X> struct SetNodeColorsTraits : public T {
- const X &nodeColors;
- SetNodeColorsTraits(const T &t,const X &x) : T(t), nodeColors(x) {}
+ template<class X> struct EdgeWidthsTraits : public T {
+ const X &_edgeWidths;
+ EdgeWidthsTraits(const T &t,const X &x) : T(t), _edgeWidths(x) {}
};
- ///\e
- template<class X> GraphToEps<SetNodeColorsTraits<X> >
- setNodeColors(const X &x)
+ ///Sets the map of the edge widths
+
+ ///Sets the map of the edge widths
+ ///\param x must be a edge map with \c double (or convertible) values.
+ template<class X> GraphToEps<EdgeWidthsTraits<X> > edgeWidths(const X &x)
{
dontPrint=true;
- return GraphToEps<SetNodeColorsTraits<X> >(SetNodeColorsTraits<X>(*this,x));
+ return GraphToEps<EdgeWidthsTraits<X> >(EdgeWidthsTraits<X>(*this,x));
}
- template<class X> struct SetEdgeColorsTraits : public T {
- const X &edgeColors;
- SetEdgeColorsTraits(const T &t,const X &x) : T(t), edgeColors(x) {}
+
+ template<class X> struct NodeColorsTraits : public T {
+ const X &_nodeColors;
+ NodeColorsTraits(const T &t,const X &x) : T(t), _nodeColors(x) {}
};
- ///\e
- template<class X> GraphToEps<SetEdgeColorsTraits<X> >
- setEdgeColors(const X &x)
+ ///Sets the map of the node colors
+
+ ///Sets the map of the node colors
+ ///\param x must be a node map with \ref Color values.
+ template<class X> GraphToEps<NodeColorsTraits<X> >
+ nodeColors(const X &x)
+ {
+ dontPrint=true;
+ return GraphToEps<NodeColorsTraits<X> >(NodeColorsTraits<X>(*this,x));
+ }
+ template<class X> struct EdgeColorsTraits : public T {
+ const X &_edgeColors;
+ EdgeColorsTraits(const T &t,const X &x) : T(t), _edgeColors(x) {}
+ };
+ ///Sets the map of the edge colors
+
+ ///Sets the map of the edge colors
+ ///\param x must be a edge map with \ref Color values.
+ template<class X> GraphToEps<EdgeColorsTraits<X> >
+ edgeColors(const X &x)
{
dontPrint=true;
- return GraphToEps<SetEdgeColorsTraits<X> >(SetEdgeColorsTraits<X>(*this,x));
+ return GraphToEps<EdgeColorsTraits<X> >(EdgeColorsTraits<X>(*this,x));
}
- ///\e
- GraphToEps<T> &scaleNodeSize(double d) {nodeSizeScalar=d;return *this;}
+ ///Sets a global scale factor for node sizes
+
+ ///Sets a global scale factor for node sizes
+ ///
+ GraphToEps<T> &nodeScale(double d) {_nodeScale=d;return *this;}
+ ///Sets a global scale factor for edge widths
+
+ ///Sets a global scale factor for edge widths
+ ///
+ GraphToEps<T> &edgeWidthScale(double d) {_edgeWidthScale=d;return *this;}
+ ///Sets a global scale factor for the whole picture
+
+ ///Sets a global scale factor for the whole picture
+ ///
+ GraphToEps<T> &scale(double d) {_scale=d;return *this;}
+ ///Sets the width of the border around the picture
+
+ ///Sets the width of the border around the picture
+ ///
+ GraphToEps<T> &border(double b) {_xBorder=_yBorder=b;return *this;}
+ ///Sets the width of the border around the picture
+
+ ///Sets the width of the border around the picture
+ ///
+ GraphToEps<T> &border(double x, double y) {
+ _xBorder=x;_yBorder=y;return *this;
+ }
+ ///Sets whether to draw arrows
+
+ ///Sets whether to draw arrows
+ ///
+ GraphToEps<T> &drawArrows(bool b=true) {_drawArrows=b;return *this;}
+ ///Sets the length of the arrowheads
+
+ ///Sets the length of the arrowheads
+ ///
+ GraphToEps<T> &arrowLength(double d) {_arrowLength*=d;return *this;}
+ ///Sets the width of the arrowheads
+
+ ///Sets the width of the arrowheads
+ ///
+ GraphToEps<T> &arrowWidth(double d) {_arrowWidth*=d;return *this;}
~GraphToEps()
{
@@ -121,44 +217,98 @@
cout << "%!PS-Adobe-2.0 EPSF-2.0\n";
//\todo: Chech whether the graph is empty.
BoundingBox<double> bb;
- for(NodeIt n(g);
- n!=INVALID;
- ++n) {
- xy<double> p(nodeSizes[n]*nodeSizeScalar,nodeSizes[n]*nodeSizeScalar);
- bb+=coords[n]+p;
- bb+=coords[n]-p;
+ for(NodeIt n(g);n!=INVALID;++n) {
+ double ns=_nodeSizes[n]*_nodeScale;
+ xy<double> p(ns,ns);
+ bb+=p+_coords[n];
+ bb+=-p+_coords[n];
}
cout << "%%BoundingBox: "
- << bb.left()-xBorder << ' ' << bb.bottom()-yBorder << ' '
- << bb.right()+xBorder << ' ' << bb.top()+yBorder << '\n';
- //x1 y1 x2 y2 cr cg cb
- cout << "/l { setrgbcolor newpath moveto lineto stroke } bind def\n";
+ << bb.left()* _scale-_xBorder << ' '
+ << bb.bottom()*_scale-_yBorder << ' '
+ << bb.right()* _scale+_xBorder << ' '
+ << bb.top()* _scale+_yBorder << '\n';
+ //x1 y1 x2 y2 cr cg cb w
+ cout << "/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def\n";
cout << "/c { newpath dup 3 index add 2 index moveto 0 360 arc } bind def\n";
// x y r cr cg cb
cout << "/n { setrgbcolor 2 index 2 index 2 index c fill\n"
- << " 0 0 0 setrgbcolor dup 10 div setlinewidth c stroke\n"
+ << " 0 0 0 setrgbcolor dup "
+ << _nodeBorderQuotient << " mul setlinewidth "
+ << 1+_nodeBorderQuotient/2 << " div c stroke\n"
<< " } bind def\n";
-
+ cout << "/arrl " << _arrowLength << " def\n";
+ cout << "/arrw " << _arrowWidth << " def\n";
+ // l dx_norm dy_norm
+ cout << "/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def\n";
+ //len w dx_norm dy_norm x1 y1 cr cg cb
+ cout << "/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def\n"
+ << " /w exch def /len exch def\n"
+ // << " 0.1 setlinewidth x1 y1 moveto dx len mul dy len mul rlineto stroke"
+ << " newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto\n"
+ << " len w sub arrl sub dx dy lrl\n"
+ << " arrw dy dx neg lrl\n"
+ << " dx arrl w add mul dy w 2 div arrw add mul sub\n"
+ << " dy arrl w add mul dx w 2 div arrw add mul add rlineto\n"
+ << " dx arrl w add mul neg dy w 2 div arrw add mul sub\n"
+ << " dy arrl w add mul neg dx w 2 div arrw add mul add rlineto\n"
+ << " arrw dy dx neg lrl\n"
+ << " len w sub arrl sub neg dx dy lrl\n"
+ << " closepath fill } bind def\n";
+ cout << "\ngsave\n";
+ if(_scale!=1.0) cout << _scale << " dup scale\n";
cout << "%Edges:\ngsave\n";
for(NodeIt n(g);n!=INVALID;++n)
for(OutEdgeIt e(g,n);e!=INVALID;++e)
- cout << coords[g.source(e)].x << ' ' << coords[g.source(e)].y << ' '
- << coords[g.target(e)].x << ' ' << coords[g.target(e)].y << ' '
- << edgeColors[e].getR() << ' '
- << edgeColors[e].getG() << ' '
- << edgeColors[e].getB() << " l\n";
+ if(_drawArrows) {
+ xy<double> d(_coords[g.target(e)]-_coords[g.source(e)]);
+ double l=sqrt(d.normSquare());
+ d/=l;
+ xy<double> x1(d*_nodeScale*_nodeSizes[g.source(e)]+
+ _coords[g.source(e)]);
+ cout << l-(_nodeSizes[g.source(e)]+
+ _nodeSizes[g.target(e)])*_nodeScale << ' '
+ << _edgeWidths[e]*_edgeWidthScale << ' '
+ << d.x << ' ' << d.y << ' '
+ << x1.x << ' ' << x1.y << ' '
+ << _edgeColors[e].getR() << ' '
+ << _edgeColors[e].getG() << ' '
+ << _edgeColors[e].getB() << " arr\n";
+ }
+ else cout << _coords[g.source(e)].x << ' '
+ << _coords[g.source(e)].y << ' '
+ << _coords[g.target(e)].x << ' '
+ << _coords[g.target(e)].y << ' '
+ << _edgeColors[e].getR() << ' '
+ << _edgeColors[e].getG() << ' '
+ << _edgeColors[e].getB() << ' '
+ << _edgeWidths[e]*_edgeWidthScale << " l\n";
cout << "grestore\n%Nodes:\ngsave\n";
for(NodeIt n(g);n!=INVALID;++n)
- cout << coords[n].x << ' ' << coords[n].y << ' '
- << nodeSizes[n]*nodeSizeScalar << ' '
- << nodeColors[n].getR() << ' '
- << nodeColors[n].getG() << ' '
- << nodeColors[n].getB() << " n\n";
- cout << "grestore\n";
+ cout << _coords[n].x << ' ' << _coords[n].y << ' '
+ << _nodeSizes[n]*_nodeScale << ' '
+ << _nodeColors[n].getR() << ' '
+ << _nodeColors[n].getG() << ' '
+ << _nodeColors[n].getB() << " n\n";
+ cout << "grestore\ngrestore\n";
}
};
+///Generates an EPS file from a graph
+
+///\ingroup misc
+///Generates an EPS file from a graph.
+///
+///This function has a lot of \ref named-templ-param "named parameters",
+///they are declared as the members of class \ref GraphToEps. The following
+///example shows how to use these parameters.
+///\code
+/// graphToEps(g).scale(10).coords(coords)
+/// .nodeScale(2).nodeSizes(sizes)
+/// .edgeWidthScale(.4);
+///\endcode
+///\sa GraphToEps
template<class G>
GraphToEps<DefaultGraphToEpsTraits<G> > graphToEps(G &g)
{
@@ -194,7 +344,7 @@
typedef ListGraph::Node Node;
typedef ListGraph::NodeIt NodeIt;
typedef ListGraph::Edge Edge;
- typedef xy<double> Xy;
+ typedef xy<int> Xy;
Node n1=g.addNode();
Node n2=g.addNode();
@@ -206,6 +356,7 @@
ListGraph::NodeMap<double> sizes(g);
ListGraph::NodeMap<int> colors(g);
ListGraph::EdgeMap<int> ecolors(g);
+ ListGraph::EdgeMap<int> widths(g);
coords[n1]=Xy(50,50); sizes[n1]=1; colors[n1]=1;
coords[n2]=Xy(50,70); sizes[n2]=2; colors[n2]=2;
@@ -215,16 +366,19 @@
Edge e;
- e=g.addEdge(n1,n2); ecolors[e]=0;
- e=g.addEdge(n2,n3); ecolors[e]=0;
- e=g.addEdge(n3,n5); ecolors[e]=0;
- e=g.addEdge(n5,n4); ecolors[e]=0;
- e=g.addEdge(n4,n1); ecolors[e]=0;
- e=g.addEdge(n2,n4); ecolors[e]=1;
- e=g.addEdge(n3,n4); ecolors[e]=2;
-
- graphToEps(g).setCoords(coords).
- scaleNodeSize(2).setNodeSizes(sizes).
- setNodeColors(composeMap(colorSet,colors)).
- setEdgeColors(composeMap(colorSet,ecolors));
+ e=g.addEdge(n1,n2); ecolors[e]=0; widths[e]=1;
+ e=g.addEdge(n2,n3); ecolors[e]=0; widths[e]=1;
+ e=g.addEdge(n3,n5); ecolors[e]=0; widths[e]=3;
+ e=g.addEdge(n5,n4); ecolors[e]=0; widths[e]=1;
+ e=g.addEdge(n4,n1); ecolors[e]=0; widths[e]=1;
+ e=g.addEdge(n2,n4); ecolors[e]=1; widths[e]=2;
+ e=g.addEdge(n3,n4); ecolors[e]=2; widths[e]=1;
+
+ graphToEps(g).scale(10).coords(coords).
+ nodeScale(2).nodeSizes(sizes).
+ nodeColors(composeMap(colorSet,colors)).
+ edgeColors(composeMap(colorSet,ecolors)).
+ edgeWidthScale(.4).edgeWidths(widths).
+ drawArrows().arrowWidth(1).arrowLength(1)
+ ;
}
More information about the Lemon-commits
mailing list