In graphToEps(), nodes may have different shapes (circles or squares).
authoralpar
Tue, 18 Jan 2005 12:02:27 +0000
changeset 1086caa13d291528
parent 1085 5b7ca75297b5
child 1087 d496d1d5a5e7
In graphToEps(), nodes may have different shapes (circles or squares).
src/demo/graph_to_eps_demo.cc
src/lemon/graph_to_eps.h
     1.1 --- a/src/demo/graph_to_eps_demo.cc	Sun Jan 16 22:34:51 2005 +0000
     1.2 +++ b/src/demo/graph_to_eps_demo.cc	Tue Jan 18 12:02:27 2005 +0000
     1.3 @@ -67,14 +67,15 @@
     1.4    ListGraph::NodeMap<Xy> coords(g);
     1.5    ListGraph::NodeMap<double> sizes(g);
     1.6    ListGraph::NodeMap<int> colors(g);
     1.7 +  ListGraph::NodeMap<int> shapes(g);
     1.8    ListGraph::EdgeMap<int> ecolors(g);
     1.9    ListGraph::EdgeMap<int> widths(g);
    1.10    
    1.11 -  coords[n1]=Xy(50,50);  sizes[n1]=1; colors[n1]=1;
    1.12 -  coords[n2]=Xy(50,70);  sizes[n2]=2; colors[n2]=2;
    1.13 -  coords[n3]=Xy(70,70);  sizes[n3]=1; colors[n3]=3;
    1.14 -  coords[n4]=Xy(70,50);  sizes[n4]=2; colors[n4]=4;
    1.15 -  coords[n5]=Xy(85,60);  sizes[n5]=3; colors[n5]=5;
    1.16 +  coords[n1]=Xy(50,50);  sizes[n1]=1; colors[n1]=1; shapes[n1]=0;
    1.17 +  coords[n2]=Xy(50,70);  sizes[n2]=2; colors[n2]=2; shapes[n2]=0;
    1.18 +  coords[n3]=Xy(70,70);  sizes[n3]=1; colors[n3]=3; shapes[n3]=0;
    1.19 +  coords[n4]=Xy(70,50);  sizes[n4]=2; colors[n4]=4; shapes[n4]=1;
    1.20 +  coords[n5]=Xy(85,60);  sizes[n5]=3; colors[n5]=5; shapes[n5]=0;
    1.21    
    1.22    Edge e;
    1.23  
    1.24 @@ -90,6 +91,7 @@
    1.25  
    1.26    graphToEps(g,"graph_to_eps_demo_out.eps").scale(10).coords(coords).
    1.27      nodeScale(2).nodeSizes(sizes).
    1.28 +    nodeShapes(shapes).
    1.29      nodeColors(composeMap(colorSet,colors)).
    1.30      edgeColors(composeMap(colorSet,ecolors)).
    1.31      edgeWidthScale(.4).edgeWidths(widths).
    1.32 @@ -97,6 +99,7 @@
    1.33  
    1.34    graphToEps(g,"graph_to_eps_demo_out_arr.eps").scale(10).coords(coords).
    1.35      nodeScale(2).nodeSizes(sizes).
    1.36 +    nodeShapes(shapes).
    1.37      nodeColors(composeMap(colorSet,colors)).
    1.38      edgeColors(composeMap(colorSet,ecolors)).
    1.39      edgeWidthScale(.4).edgeWidths(widths).
    1.40 @@ -116,6 +119,7 @@
    1.41  
    1.42    graphToEps(g,"graph_to_eps_demo_out_par.eps").scale(10).coords(coords).
    1.43      nodeScale(2).nodeSizes(sizes).
    1.44 +    nodeShapes(shapes).
    1.45      nodeColors(composeMap(colorSet,colors)).
    1.46      edgeColors(composeMap(colorSet,ecolors)).
    1.47      edgeWidthScale(.4).edgeWidths(widths).
    1.48 @@ -124,10 +128,12 @@
    1.49  
    1.50    graphToEps(g,"graph_to_eps_demo_out_par_arr.eps").scale(10).coords(coords).
    1.51      nodeScale(2).nodeSizes(sizes).
    1.52 +    nodeShapes(shapes).
    1.53      nodeColors(composeMap(colorSet,colors)).
    1.54      edgeColors(composeMap(colorSet,ecolors)).
    1.55      edgeWidthScale(.3).edgeWidths(widths).
    1.56      nodeTexts(id).nodeTextSize(3).
    1.57      enableParallel().parEdgeDist(1).
    1.58 +    //    hideNodes().
    1.59      drawArrows().arrowWidth(1).arrowLength(1);
    1.60  }
     2.1 --- a/src/lemon/graph_to_eps.h	Sun Jan 16 22:34:51 2005 +0000
     2.2 +++ b/src/lemon/graph_to_eps.h	Tue Jan 18 12:02:27 2005 +0000
     2.3 @@ -80,6 +80,7 @@
     2.4    
     2.5    ConstMap<typename Graph::Node,xy<double> > _coords;
     2.6    ConstMap<typename Graph::Node,double > _nodeSizes;
     2.7 +  ConstMap<typename Graph::Node,int > _nodeShapes;
     2.8  
     2.9    ConstMap<typename Graph::Node,Color > _nodeColors;
    2.10    ConstMap<typename Graph::Edge,Color > _edgeColors;
    2.11 @@ -123,7 +124,7 @@
    2.12    DefaultGraphToEpsTraits(const G &_g,std::ostream& _os=std::cout,
    2.13  			  bool _pros=false) :
    2.14      g(_g), os(_os),
    2.15 -    _coords(xy<double>(1,1)), _nodeSizes(1.0),
    2.16 +    _coords(xy<double>(1,1)), _nodeSizes(1.0), _nodeShapes(0),
    2.17      _nodeColors(Color(1,1,1)), _edgeColors(Color(0,0,0)),
    2.18      _edgeWidths(1), _edgeWidthScale(0.3),
    2.19      _nodeScale(1.0), _xBorder(10), _yBorder(10), _scale(1.0),
    2.20 @@ -154,6 +155,8 @@
    2.21  
    2.22    bool dontPrint;
    2.23  
    2.24 +  enum NodeShapes { CIRCLE=0, SQUARE=1 };
    2.25 +		   
    2.26    class edgeLess {
    2.27      const Graph &g;
    2.28    public:
    2.29 @@ -214,6 +217,20 @@
    2.30      dontPrint=true;
    2.31      return GraphToEps<NodeSizesTraits<X> >(NodeSizesTraits<X>(*this,x));
    2.32    }
    2.33 +  template<class X> struct NodeShapesTraits : public T {
    2.34 +    const X &_nodeShapes;
    2.35 +    NodeShapesTraits(const T &t,const X &x) : T(t), _nodeShapes(x) {}
    2.36 +  };
    2.37 +  ///Sets the map of the node shapes
    2.38 +
    2.39 +  ///Sets the map of the node shapes
    2.40 +  ///\param x must be a node map with \c int (or convertible) values. 
    2.41 +  ///\todo Incomplete doc.
    2.42 +  template<class X> GraphToEps<NodeShapesTraits<X> > nodeShapes(const X &x)
    2.43 +  {
    2.44 +    dontPrint=true;
    2.45 +    return GraphToEps<NodeShapesTraits<X> >(NodeShapesTraits<X>(*this,x));
    2.46 +  }
    2.47    template<class X> struct NodeTextsTraits : public T {
    2.48      const X &_nodeTexts;
    2.49      NodeTextsTraits(const T &t,const X &x) : T(t), _nodeTexts(x) {}
    2.50 @@ -386,7 +403,20 @@
    2.51    ///Sets whether the the graph is directed.
    2.52    ///Use it to show the undirected edges as a pair of directed ones.
    2.53    GraphToEps<T> &bidir(bool b=true) {_undir=!b;return *this;}
    2.54 -  
    2.55 +
    2.56 +protected:
    2.57 +  bool isInsideNode(xy<double> p, double r,int t) 
    2.58 +  {
    2.59 +    switch(t) {
    2.60 +    case CIRCLE:
    2.61 +      return p.normSquare()<=r*r;
    2.62 +    case SQUARE:
    2.63 +      return p.x<=r&&p.x>=-r&&p.y<=r&&p.y>=-r;
    2.64 +    }
    2.65 +    return false;
    2.66 +  }
    2.67 +
    2.68 +public:
    2.69    ~GraphToEps() 
    2.70    {
    2.71      if(dontPrint) return;
    2.72 @@ -409,13 +439,25 @@
    2.73      os << "/lb { setlinewidth setrgbcolor newpath moveto\n"
    2.74         << "      4 2 roll 1 index 1 index curveto stroke } bind def\n";
    2.75      os << "/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def\n";
    2.76 +    //x y r
    2.77      os << "/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def\n";
    2.78 +    //x y r
    2.79 +    os << "/sq { newpath 2 index 1 index add 2 index 2 index add moveto\n"
    2.80 +       << "      2 index 1 index sub 2 index 2 index add lineto\n"
    2.81 +       << "      2 index 1 index sub 2 index 2 index sub lineto\n"
    2.82 +       << "      2 index 1 index add 2 index 2 index sub lineto\n"
    2.83 +       << "      closepath pop pop pop} bind def\n";
    2.84      // x y r cr cg cb
    2.85 -    os << "/n { setrgbcolor 2 index 2 index 2 index c fill\n"
    2.86 +    os << "/nc { setrgbcolor 2 index 2 index 2 index c fill\n"
    2.87         << "     0 0 0 setrgbcolor dup "
    2.88         << _nodeBorderQuotient << " mul setlinewidth "
    2.89         << 1+_nodeBorderQuotient/2 << " div c stroke\n"
    2.90         << "   } bind def\n";
    2.91 +    os << "/nsq { setrgbcolor 2 index 2 index 2 index sq fill\n"
    2.92 +       << "     0 0 0 setrgbcolor dup "
    2.93 +       << _nodeBorderQuotient << " mul setlinewidth "
    2.94 +       << 1+_nodeBorderQuotient/2 << " div sq stroke\n"
    2.95 +       << "   } bind def\n";
    2.96      os << "/arrl " << _arrowLength << " def\n";
    2.97      os << "/arrw " << _arrowWidth << " def\n";
    2.98      // l dx_norm dy_norm
    2.99 @@ -474,32 +516,33 @@
   2.100  	    sw+=_edgeWidths[*e]*_edgeWidthScale/2.0;
   2.101  	    xy<double> mm=m+rot(d)*sw/.75;
   2.102  	    if(_drawArrows) {
   2.103 +	      int node_shape;
   2.104  	      const int INERPOL_PREC=20;
   2.105  	      xy<double> s=_coords[g.source(*e)];
   2.106  	      xy<double> t=_coords[g.target(*e)];
   2.107  	      double rn=_nodeSizes[g.target(*e)]*_nodeScale;
   2.108 -	      rn*=rn;
   2.109 +	      node_shape=_nodeShapes[g.target(*e)];
   2.110  	      Bezier3 bez(s,mm,mm,t);
   2.111  	      double t1=0,t2=1;
   2.112  	      for(int i=0;i<INERPOL_PREC;++i)
   2.113 -		if((bez((t1+t2)/2)-t).normSquare()>rn) t1=(t1+t2)/2;
   2.114 -		else t2=(t1+t2)/2;
   2.115 +		if(isInsideNode(bez((t1+t2)/2)-t,rn,node_shape)) t2=(t1+t2)/2;
   2.116 +		else t1=(t1+t2)/2;
   2.117  	      xy<double> apoint=bez((t1+t2)/2);
   2.118 -	      rn = _nodeSizes[g.target(*e)]*_nodeScale+_arrowLength+
   2.119 -		_edgeWidths[*e]*_edgeWidthScale;
   2.120 +	      rn = _arrowLength+_edgeWidths[*e]*_edgeWidthScale;
   2.121  	      rn*=rn;
   2.122 -	      t1=0;t2=1;
   2.123 +	      t2=(t1+t2)/2;t1=0;
   2.124  	      for(int i=0;i<INERPOL_PREC;++i)
   2.125 -		if((bez((t1+t2)/2)-t).normSquare()>rn) t1=(t1+t2)/2;
   2.126 +		if((bez((t1+t2)/2)-apoint).normSquare()>rn) t1=(t1+t2)/2;
   2.127  		else t2=(t1+t2)/2;
   2.128  	      xy<double> linend=bez((t1+t2)/2);	      
   2.129  	      bez=bez.before((t1+t2)/2);
   2.130 -	      rn=_nodeSizes[g.source(*e)]*_nodeScale; rn*=rn;
   2.131 -	      t1=0;t2=1;
   2.132 -	      for(int i=0;i<INERPOL_PREC;++i)
   2.133 -		if((bez((t1+t2)/2)-s).normSquare()>rn) t2=(t1+t2)/2;
   2.134 -		else t1=(t1+t2)/2;
   2.135 -	      bez=bez.after((t1+t2)/2);
   2.136 +// 	      rn=_nodeSizes[g.source(*e)]*_nodeScale;
   2.137 +// 	      node_shape=_nodeShapes[g.source(*e)];
   2.138 +// 	      t1=0;t2=1;
   2.139 +// 	      for(int i=0;i<INERPOL_PREC;++i)
   2.140 +// 		if(isInsideNode(bez((t1+t2)/2)-t,rn,node_shape)) t1=(t1+t2)/2;
   2.141 +// 		else t2=(t1+t2)/2;
   2.142 +// 	      bez=bez.after((t1+t2)/2);
   2.143  	      os << _edgeWidths[*e]*_edgeWidthScale << " setlinewidth "
   2.144  		 << _edgeColors[*e].getR() << ' '
   2.145  		 << _edgeColors[*e].getG() << ' '
   2.146 @@ -559,12 +602,20 @@
   2.147      }
   2.148      if(_showNodes) {
   2.149        os << "%Nodes:\ngsave\n";
   2.150 -      for(NodeIt n(g);n!=INVALID;++n)
   2.151 +      for(NodeIt n(g);n!=INVALID;++n) {
   2.152  	os << _coords[n].x << ' ' << _coords[n].y << ' '
   2.153  	   << _nodeSizes[n]*_nodeScale << ' '
   2.154  	   << _nodeColors[n].getR() << ' '
   2.155  	   << _nodeColors[n].getG() << ' '
   2.156 -	   << _nodeColors[n].getB() << " n\n";
   2.157 +	   << _nodeColors[n].getB() << ' ';
   2.158 +	switch(_nodeShapes[n]) {
   2.159 +	case CIRCLE:
   2.160 +	  os<< "nc";break;
   2.161 +	case SQUARE:
   2.162 +	  os<< "nsq";break;
   2.163 +	}
   2.164 +	os<<'\n';
   2.165 +      }
   2.166        os << "grestore\n";
   2.167      }
   2.168      if(_showNodeText) {