1.1 --- a/src/lemon/graph_to_eps.h Sun Jan 16 22:34:51 2005 +0000
1.2 +++ b/src/lemon/graph_to_eps.h Tue Jan 18 12:02:27 2005 +0000
1.3 @@ -80,6 +80,7 @@
1.4
1.5 ConstMap<typename Graph::Node,xy<double> > _coords;
1.6 ConstMap<typename Graph::Node,double > _nodeSizes;
1.7 + ConstMap<typename Graph::Node,int > _nodeShapes;
1.8
1.9 ConstMap<typename Graph::Node,Color > _nodeColors;
1.10 ConstMap<typename Graph::Edge,Color > _edgeColors;
1.11 @@ -123,7 +124,7 @@
1.12 DefaultGraphToEpsTraits(const G &_g,std::ostream& _os=std::cout,
1.13 bool _pros=false) :
1.14 g(_g), os(_os),
1.15 - _coords(xy<double>(1,1)), _nodeSizes(1.0),
1.16 + _coords(xy<double>(1,1)), _nodeSizes(1.0), _nodeShapes(0),
1.17 _nodeColors(Color(1,1,1)), _edgeColors(Color(0,0,0)),
1.18 _edgeWidths(1), _edgeWidthScale(0.3),
1.19 _nodeScale(1.0), _xBorder(10), _yBorder(10), _scale(1.0),
1.20 @@ -154,6 +155,8 @@
1.21
1.22 bool dontPrint;
1.23
1.24 + enum NodeShapes { CIRCLE=0, SQUARE=1 };
1.25 +
1.26 class edgeLess {
1.27 const Graph &g;
1.28 public:
1.29 @@ -214,6 +217,20 @@
1.30 dontPrint=true;
1.31 return GraphToEps<NodeSizesTraits<X> >(NodeSizesTraits<X>(*this,x));
1.32 }
1.33 + template<class X> struct NodeShapesTraits : public T {
1.34 + const X &_nodeShapes;
1.35 + NodeShapesTraits(const T &t,const X &x) : T(t), _nodeShapes(x) {}
1.36 + };
1.37 + ///Sets the map of the node shapes
1.38 +
1.39 + ///Sets the map of the node shapes
1.40 + ///\param x must be a node map with \c int (or convertible) values.
1.41 + ///\todo Incomplete doc.
1.42 + template<class X> GraphToEps<NodeShapesTraits<X> > nodeShapes(const X &x)
1.43 + {
1.44 + dontPrint=true;
1.45 + return GraphToEps<NodeShapesTraits<X> >(NodeShapesTraits<X>(*this,x));
1.46 + }
1.47 template<class X> struct NodeTextsTraits : public T {
1.48 const X &_nodeTexts;
1.49 NodeTextsTraits(const T &t,const X &x) : T(t), _nodeTexts(x) {}
1.50 @@ -386,7 +403,20 @@
1.51 ///Sets whether the the graph is directed.
1.52 ///Use it to show the undirected edges as a pair of directed ones.
1.53 GraphToEps<T> &bidir(bool b=true) {_undir=!b;return *this;}
1.54 -
1.55 +
1.56 +protected:
1.57 + bool isInsideNode(xy<double> p, double r,int t)
1.58 + {
1.59 + switch(t) {
1.60 + case CIRCLE:
1.61 + return p.normSquare()<=r*r;
1.62 + case SQUARE:
1.63 + return p.x<=r&&p.x>=-r&&p.y<=r&&p.y>=-r;
1.64 + }
1.65 + return false;
1.66 + }
1.67 +
1.68 +public:
1.69 ~GraphToEps()
1.70 {
1.71 if(dontPrint) return;
1.72 @@ -409,13 +439,25 @@
1.73 os << "/lb { setlinewidth setrgbcolor newpath moveto\n"
1.74 << " 4 2 roll 1 index 1 index curveto stroke } bind def\n";
1.75 os << "/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def\n";
1.76 + //x y r
1.77 os << "/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def\n";
1.78 + //x y r
1.79 + os << "/sq { newpath 2 index 1 index add 2 index 2 index add moveto\n"
1.80 + << " 2 index 1 index sub 2 index 2 index add lineto\n"
1.81 + << " 2 index 1 index sub 2 index 2 index sub lineto\n"
1.82 + << " 2 index 1 index add 2 index 2 index sub lineto\n"
1.83 + << " closepath pop pop pop} bind def\n";
1.84 // x y r cr cg cb
1.85 - os << "/n { setrgbcolor 2 index 2 index 2 index c fill\n"
1.86 + os << "/nc { setrgbcolor 2 index 2 index 2 index c fill\n"
1.87 << " 0 0 0 setrgbcolor dup "
1.88 << _nodeBorderQuotient << " mul setlinewidth "
1.89 << 1+_nodeBorderQuotient/2 << " div c stroke\n"
1.90 << " } bind def\n";
1.91 + os << "/nsq { setrgbcolor 2 index 2 index 2 index sq fill\n"
1.92 + << " 0 0 0 setrgbcolor dup "
1.93 + << _nodeBorderQuotient << " mul setlinewidth "
1.94 + << 1+_nodeBorderQuotient/2 << " div sq stroke\n"
1.95 + << " } bind def\n";
1.96 os << "/arrl " << _arrowLength << " def\n";
1.97 os << "/arrw " << _arrowWidth << " def\n";
1.98 // l dx_norm dy_norm
1.99 @@ -474,32 +516,33 @@
1.100 sw+=_edgeWidths[*e]*_edgeWidthScale/2.0;
1.101 xy<double> mm=m+rot(d)*sw/.75;
1.102 if(_drawArrows) {
1.103 + int node_shape;
1.104 const int INERPOL_PREC=20;
1.105 xy<double> s=_coords[g.source(*e)];
1.106 xy<double> t=_coords[g.target(*e)];
1.107 double rn=_nodeSizes[g.target(*e)]*_nodeScale;
1.108 - rn*=rn;
1.109 + node_shape=_nodeShapes[g.target(*e)];
1.110 Bezier3 bez(s,mm,mm,t);
1.111 double t1=0,t2=1;
1.112 for(int i=0;i<INERPOL_PREC;++i)
1.113 - if((bez((t1+t2)/2)-t).normSquare()>rn) t1=(t1+t2)/2;
1.114 - else t2=(t1+t2)/2;
1.115 + if(isInsideNode(bez((t1+t2)/2)-t,rn,node_shape)) t2=(t1+t2)/2;
1.116 + else t1=(t1+t2)/2;
1.117 xy<double> apoint=bez((t1+t2)/2);
1.118 - rn = _nodeSizes[g.target(*e)]*_nodeScale+_arrowLength+
1.119 - _edgeWidths[*e]*_edgeWidthScale;
1.120 + rn = _arrowLength+_edgeWidths[*e]*_edgeWidthScale;
1.121 rn*=rn;
1.122 - t1=0;t2=1;
1.123 + t2=(t1+t2)/2;t1=0;
1.124 for(int i=0;i<INERPOL_PREC;++i)
1.125 - if((bez((t1+t2)/2)-t).normSquare()>rn) t1=(t1+t2)/2;
1.126 + if((bez((t1+t2)/2)-apoint).normSquare()>rn) t1=(t1+t2)/2;
1.127 else t2=(t1+t2)/2;
1.128 xy<double> linend=bez((t1+t2)/2);
1.129 bez=bez.before((t1+t2)/2);
1.130 - rn=_nodeSizes[g.source(*e)]*_nodeScale; rn*=rn;
1.131 - t1=0;t2=1;
1.132 - for(int i=0;i<INERPOL_PREC;++i)
1.133 - if((bez((t1+t2)/2)-s).normSquare()>rn) t2=(t1+t2)/2;
1.134 - else t1=(t1+t2)/2;
1.135 - bez=bez.after((t1+t2)/2);
1.136 +// rn=_nodeSizes[g.source(*e)]*_nodeScale;
1.137 +// node_shape=_nodeShapes[g.source(*e)];
1.138 +// t1=0;t2=1;
1.139 +// for(int i=0;i<INERPOL_PREC;++i)
1.140 +// if(isInsideNode(bez((t1+t2)/2)-t,rn,node_shape)) t1=(t1+t2)/2;
1.141 +// else t2=(t1+t2)/2;
1.142 +// bez=bez.after((t1+t2)/2);
1.143 os << _edgeWidths[*e]*_edgeWidthScale << " setlinewidth "
1.144 << _edgeColors[*e].getR() << ' '
1.145 << _edgeColors[*e].getG() << ' '
1.146 @@ -559,12 +602,20 @@
1.147 }
1.148 if(_showNodes) {
1.149 os << "%Nodes:\ngsave\n";
1.150 - for(NodeIt n(g);n!=INVALID;++n)
1.151 + for(NodeIt n(g);n!=INVALID;++n) {
1.152 os << _coords[n].x << ' ' << _coords[n].y << ' '
1.153 << _nodeSizes[n]*_nodeScale << ' '
1.154 << _nodeColors[n].getR() << ' '
1.155 << _nodeColors[n].getG() << ' '
1.156 - << _nodeColors[n].getB() << " n\n";
1.157 + << _nodeColors[n].getB() << ' ';
1.158 + switch(_nodeShapes[n]) {
1.159 + case CIRCLE:
1.160 + os<< "nc";break;
1.161 + case SQUARE:
1.162 + os<< "nsq";break;
1.163 + }
1.164 + os<<'\n';
1.165 + }
1.166 os << "grestore\n";
1.167 }
1.168 if(_showNodeText) {