# HG changeset patch # User alpar # Date 1106049747 0 # Node ID caa13d29152820c0d2b504b322f7f13073d6d1d7 # Parent 5b7ca75297b52f204643352813d33a7f3594a945 In graphToEps(), nodes may have different shapes (circles or squares). diff -r 5b7ca75297b5 -r caa13d291528 src/demo/graph_to_eps_demo.cc --- a/src/demo/graph_to_eps_demo.cc Sun Jan 16 22:34:51 2005 +0000 +++ b/src/demo/graph_to_eps_demo.cc Tue Jan 18 12:02:27 2005 +0000 @@ -67,14 +67,15 @@ ListGraph::NodeMap<Xy> coords(g); ListGraph::NodeMap<double> sizes(g); ListGraph::NodeMap<int> colors(g); + ListGraph::NodeMap<int> shapes(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; - coords[n3]=Xy(70,70); sizes[n3]=1; colors[n3]=3; - coords[n4]=Xy(70,50); sizes[n4]=2; colors[n4]=4; - coords[n5]=Xy(85,60); sizes[n5]=3; colors[n5]=5; + coords[n1]=Xy(50,50); sizes[n1]=1; colors[n1]=1; shapes[n1]=0; + coords[n2]=Xy(50,70); sizes[n2]=2; colors[n2]=2; shapes[n2]=0; + coords[n3]=Xy(70,70); sizes[n3]=1; colors[n3]=3; shapes[n3]=0; + coords[n4]=Xy(70,50); sizes[n4]=2; colors[n4]=4; shapes[n4]=1; + coords[n5]=Xy(85,60); sizes[n5]=3; colors[n5]=5; shapes[n5]=0; Edge e; @@ -90,6 +91,7 @@ graphToEps(g,"graph_to_eps_demo_out.eps").scale(10).coords(coords). nodeScale(2).nodeSizes(sizes). + nodeShapes(shapes). nodeColors(composeMap(colorSet,colors)). edgeColors(composeMap(colorSet,ecolors)). edgeWidthScale(.4).edgeWidths(widths). @@ -97,6 +99,7 @@ graphToEps(g,"graph_to_eps_demo_out_arr.eps").scale(10).coords(coords). nodeScale(2).nodeSizes(sizes). + nodeShapes(shapes). nodeColors(composeMap(colorSet,colors)). edgeColors(composeMap(colorSet,ecolors)). edgeWidthScale(.4).edgeWidths(widths). @@ -116,6 +119,7 @@ graphToEps(g,"graph_to_eps_demo_out_par.eps").scale(10).coords(coords). nodeScale(2).nodeSizes(sizes). + nodeShapes(shapes). nodeColors(composeMap(colorSet,colors)). edgeColors(composeMap(colorSet,ecolors)). edgeWidthScale(.4).edgeWidths(widths). @@ -124,10 +128,12 @@ graphToEps(g,"graph_to_eps_demo_out_par_arr.eps").scale(10).coords(coords). nodeScale(2).nodeSizes(sizes). + nodeShapes(shapes). nodeColors(composeMap(colorSet,colors)). edgeColors(composeMap(colorSet,ecolors)). edgeWidthScale(.3).edgeWidths(widths). nodeTexts(id).nodeTextSize(3). enableParallel().parEdgeDist(1). + // hideNodes(). drawArrows().arrowWidth(1).arrowLength(1); } diff -r 5b7ca75297b5 -r caa13d291528 src/lemon/graph_to_eps.h --- a/src/lemon/graph_to_eps.h Sun Jan 16 22:34:51 2005 +0000 +++ b/src/lemon/graph_to_eps.h Tue Jan 18 12:02:27 2005 +0000 @@ -80,6 +80,7 @@ ConstMap<typename Graph::Node,xy<double> > _coords; ConstMap<typename Graph::Node,double > _nodeSizes; + ConstMap<typename Graph::Node,int > _nodeShapes; ConstMap<typename Graph::Node,Color > _nodeColors; ConstMap<typename Graph::Edge,Color > _edgeColors; @@ -123,7 +124,7 @@ DefaultGraphToEpsTraits(const G &_g,std::ostream& _os=std::cout, bool _pros=false) : g(_g), os(_os), - _coords(xy<double>(1,1)), _nodeSizes(1.0), + _coords(xy<double>(1,1)), _nodeSizes(1.0), _nodeShapes(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), @@ -154,6 +155,8 @@ bool dontPrint; + enum NodeShapes { CIRCLE=0, SQUARE=1 }; + class edgeLess { const Graph &g; public: @@ -214,6 +217,20 @@ dontPrint=true; return GraphToEps<NodeSizesTraits<X> >(NodeSizesTraits<X>(*this,x)); } + template<class X> struct NodeShapesTraits : public T { + const X &_nodeShapes; + NodeShapesTraits(const T &t,const X &x) : T(t), _nodeShapes(x) {} + }; + ///Sets the map of the node shapes + + ///Sets the map of the node shapes + ///\param x must be a node map with \c int (or convertible) values. + ///\todo Incomplete doc. + template<class X> GraphToEps<NodeShapesTraits<X> > nodeShapes(const X &x) + { + dontPrint=true; + return GraphToEps<NodeShapesTraits<X> >(NodeShapesTraits<X>(*this,x)); + } template<class X> struct NodeTextsTraits : public T { const X &_nodeTexts; NodeTextsTraits(const T &t,const X &x) : T(t), _nodeTexts(x) {} @@ -386,7 +403,20 @@ ///Sets whether the the graph is directed. ///Use it to show the undirected edges as a pair of directed ones. GraphToEps<T> &bidir(bool b=true) {_undir=!b;return *this;} - + +protected: + bool isInsideNode(xy<double> p, double r,int t) + { + switch(t) { + case CIRCLE: + return p.normSquare()<=r*r; + case SQUARE: + return p.x<=r&&p.x>=-r&&p.y<=r&&p.y>=-r; + } + return false; + } + +public: ~GraphToEps() { if(dontPrint) return; @@ -409,13 +439,25 @@ os << "/lb { setlinewidth setrgbcolor newpath moveto\n" << " 4 2 roll 1 index 1 index curveto stroke } bind def\n"; os << "/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def\n"; + //x y r os << "/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def\n"; + //x y r + os << "/sq { newpath 2 index 1 index add 2 index 2 index add moveto\n" + << " 2 index 1 index sub 2 index 2 index add lineto\n" + << " 2 index 1 index sub 2 index 2 index sub lineto\n" + << " 2 index 1 index add 2 index 2 index sub lineto\n" + << " closepath pop pop pop} bind def\n"; // x y r cr cg cb - os << "/n { setrgbcolor 2 index 2 index 2 index c fill\n" + os << "/nc { setrgbcolor 2 index 2 index 2 index c fill\n" << " 0 0 0 setrgbcolor dup " << _nodeBorderQuotient << " mul setlinewidth " << 1+_nodeBorderQuotient/2 << " div c stroke\n" << " } bind def\n"; + os << "/nsq { setrgbcolor 2 index 2 index 2 index sq fill\n" + << " 0 0 0 setrgbcolor dup " + << _nodeBorderQuotient << " mul setlinewidth " + << 1+_nodeBorderQuotient/2 << " div sq stroke\n" + << " } bind def\n"; os << "/arrl " << _arrowLength << " def\n"; os << "/arrw " << _arrowWidth << " def\n"; // l dx_norm dy_norm @@ -474,32 +516,33 @@ sw+=_edgeWidths[*e]*_edgeWidthScale/2.0; xy<double> mm=m+rot(d)*sw/.75; if(_drawArrows) { + int node_shape; const int INERPOL_PREC=20; xy<double> s=_coords[g.source(*e)]; xy<double> t=_coords[g.target(*e)]; double rn=_nodeSizes[g.target(*e)]*_nodeScale; - rn*=rn; + node_shape=_nodeShapes[g.target(*e)]; Bezier3 bez(s,mm,mm,t); double t1=0,t2=1; for(int i=0;i<INERPOL_PREC;++i) - if((bez((t1+t2)/2)-t).normSquare()>rn) t1=(t1+t2)/2; - else t2=(t1+t2)/2; + if(isInsideNode(bez((t1+t2)/2)-t,rn,node_shape)) t2=(t1+t2)/2; + else t1=(t1+t2)/2; xy<double> apoint=bez((t1+t2)/2); - rn = _nodeSizes[g.target(*e)]*_nodeScale+_arrowLength+ - _edgeWidths[*e]*_edgeWidthScale; + rn = _arrowLength+_edgeWidths[*e]*_edgeWidthScale; rn*=rn; - t1=0;t2=1; + t2=(t1+t2)/2;t1=0; for(int i=0;i<INERPOL_PREC;++i) - if((bez((t1+t2)/2)-t).normSquare()>rn) t1=(t1+t2)/2; + if((bez((t1+t2)/2)-apoint).normSquare()>rn) t1=(t1+t2)/2; else t2=(t1+t2)/2; xy<double> linend=bez((t1+t2)/2); bez=bez.before((t1+t2)/2); - rn=_nodeSizes[g.source(*e)]*_nodeScale; rn*=rn; - t1=0;t2=1; - for(int i=0;i<INERPOL_PREC;++i) - if((bez((t1+t2)/2)-s).normSquare()>rn) t2=(t1+t2)/2; - else t1=(t1+t2)/2; - bez=bez.after((t1+t2)/2); +// rn=_nodeSizes[g.source(*e)]*_nodeScale; +// node_shape=_nodeShapes[g.source(*e)]; +// t1=0;t2=1; +// for(int i=0;i<INERPOL_PREC;++i) +// if(isInsideNode(bez((t1+t2)/2)-t,rn,node_shape)) t1=(t1+t2)/2; +// else t2=(t1+t2)/2; +// bez=bez.after((t1+t2)/2); os << _edgeWidths[*e]*_edgeWidthScale << " setlinewidth " << _edgeColors[*e].getR() << ' ' << _edgeColors[*e].getG() << ' ' @@ -559,12 +602,20 @@ } if(_showNodes) { os << "%Nodes:\ngsave\n"; - for(NodeIt n(g);n!=INVALID;++n) + for(NodeIt n(g);n!=INVALID;++n) { os << _coords[n].x << ' ' << _coords[n].y << ' ' << _nodeSizes[n]*_nodeScale << ' ' << _nodeColors[n].getR() << ' ' << _nodeColors[n].getG() << ' ' - << _nodeColors[n].getB() << " n\n"; + << _nodeColors[n].getB() << ' '; + switch(_nodeShapes[n]) { + case CIRCLE: + os<< "nc";break; + case SQUARE: + os<< "nsq";break; + } + os<<'\n'; + } os << "grestore\n"; } if(_showNodeText) {