- Parallel edges look a bit better
authoralpar
Sun, 16 Jan 2005 22:34:51 +0000
changeset 10855b7ca75297b5
parent 1084 320a0f083ca1
child 1086 caa13d291528
- Parallel edges look a bit better
- Possibility to insert verbatim PS blocks for each node
src/lemon/graph_to_eps.h
     1.1 --- a/src/lemon/graph_to_eps.h	Sun Jan 16 22:31:26 2005 +0000
     1.2 +++ b/src/lemon/graph_to_eps.h	Sun Jan 16 22:34:51 2005 +0000
     1.3 @@ -105,6 +105,10 @@
     1.4    ConstMap<typename Graph::Node,bool > _nodeTexts;  
     1.5    double _nodeTextSize;
     1.6  
     1.7 +  bool _showNodePsText;
     1.8 +  ConstMap<typename Graph::Node,bool > _nodePsTexts;  
     1.9 +  char *_nodePsTextsPreamble;
    1.10 +  
    1.11    bool _undir;
    1.12    bool _pleaseRemoveOsStream;
    1.13    ///Constructor
    1.14 @@ -128,6 +132,7 @@
    1.15      _showNodes(true), _showEdges(true),
    1.16      _enableParallel(false), _parEdgeDist(1),
    1.17      _showNodeText(false), _nodeTexts(false), _nodeTextSize(1),
    1.18 +    _showNodePsText(false), _nodePsTexts(false), _nodePsTextsPreamble(0),
    1.19      _undir(false),
    1.20      _pleaseRemoveOsStream(_pros) {}
    1.21  };
    1.22 @@ -224,7 +229,33 @@
    1.23      _showNodeText=true;
    1.24      return GraphToEps<NodeTextsTraits<X> >(NodeTextsTraits<X>(*this,x));
    1.25    }
    1.26 -   template<class X> struct EdgeWidthsTraits : public T {
    1.27 +  template<class X> struct NodePsTextsTraits : public T {
    1.28 +    const X &_nodePsTexts;
    1.29 +    NodePsTextsTraits(const T &t,const X &x) : T(t), _nodePsTexts(x) {}
    1.30 +  };
    1.31 +  ///Inserts a PostScript block to the nodes
    1.32 +
    1.33 +  ///With this command it is possible to insert a verbatim PostScript
    1.34 +  ///block to the nodes.
    1.35 +  ///The PS current point will be moved to the centre of the node before
    1.36 +  ///the PostScript block inserted.
    1.37 +  ///
    1.38 +  ///Before and after the block a newline character is inserted to you
    1.39 +  ///don't have to bother with the separators.
    1.40 +  ///
    1.41 +  ///\param x must be a node map with type that can be pushed to a standard
    1.42 +  ///ostream.
    1.43 +  ///
    1.44 +  ///\sa nodePsTextsPreamble()
    1.45 +  ///\todo Offer the choise not to move to the centre but pass the coordinates
    1.46 +  ///to the Postscript block inserted.
    1.47 +  template<class X> GraphToEps<NodePsTextsTraits<X> > nodePsTexts(const X &x)
    1.48 +  {
    1.49 +    dontPrint=true;
    1.50 +    _showNodePsText=true;
    1.51 +    return GraphToEps<NodePsTextsTraits<X> >(NodePsTextsTraits<X>(*this,x));
    1.52 +  }
    1.53 +  template<class X> struct EdgeWidthsTraits : public T {
    1.54      const X &_edgeWidths;
    1.55      EdgeWidthsTraits(const T &t,const X &x) : T(t), _edgeWidths(x) {}
    1.56    };
    1.57 @@ -337,6 +368,14 @@
    1.58    ///Sets the size of the node texts
    1.59    ///
    1.60    GraphToEps<T> &nodeTextSize(double d) {_nodeTextSize=d;return *this;}
    1.61 +  ///Gives a preamble block for node Postscript block.
    1.62 +  
    1.63 +  ///Gives a preamble block for node Postscript block.
    1.64 +  ///
    1.65 +  ///\sa nodePsTexts()
    1.66 +  GraphToEps<T> & nodePsTextsPreamble(const char *str) {
    1.67 +    _nodePsTextsPreamble=s ;return *this;
    1.68 +  }
    1.69    ///Sets whether the the graph is undirected
    1.70  
    1.71    ///Sets whether the the graph is undirected
    1.72 @@ -401,9 +440,8 @@
    1.73      os << "\ngsave\n";
    1.74      if(_scale!=1.0) os << _scale << " dup scale\n";
    1.75      
    1.76 -    os << "%Edges:\ngsave\n";
    1.77 -    
    1.78 -    if(_showEdges)
    1.79 +    if(_showEdges) {
    1.80 +      os << "%Edges:\ngsave\n";      
    1.81        if(_enableParallel) {
    1.82  	std::vector<Edge> el;
    1.83  	for(EdgeIt e(g);e!=INVALID;++e)
    1.84 @@ -419,21 +457,29 @@
    1.85  	    sw+=_edgeWidths[*e]*_edgeWidthScale+_parEdgeDist;
    1.86  	  sw-=_parEdgeDist;
    1.87  	  sw/=-2.0;
    1.88 -	  xy<double> d(_coords[g.target(*i)]-_coords[g.source(*i)]);
    1.89 -	  double l=sqrt(d.normSquare());
    1.90 -	  d/=l;
    1.91 -	  
    1.92 +	  xy<double> dvec(_coords[g.target(*i)]-_coords[g.source(*i)]);
    1.93 +	  double l=sqrt(dvec.normSquare());
    1.94 +	  xy<double> d(dvec/l);
    1.95 + 	  xy<double> m;
    1.96 +// 	  m=xy<double>(_coords[g.target(*i)]+_coords[g.source(*i)])/2.0;
    1.97 +
    1.98 +//  	  m=xy<double>(_coords[g.source(*i)])+
    1.99 +// 	    dvec*(double(_nodeSizes[g.source(*i)])/
   1.100 +// 	       (_nodeSizes[g.source(*i)]+_nodeSizes[g.target(*i)]));
   1.101 +
   1.102 + 	  m=xy<double>(_coords[g.source(*i)])+
   1.103 +	    d*(l+_nodeSizes[g.source(*i)]-_nodeSizes[g.target(*i)])/2.0;
   1.104 +
   1.105  	  for(typename std::vector<Edge>::iterator e=i;e!=j;++e) {
   1.106  	    sw+=_edgeWidths[*e]*_edgeWidthScale/2.0;
   1.107 -	    xy<double> m(_coords[g.target(*e)]+_coords[g.source(*e)]);
   1.108 -	    m=m/2.0+rot(d)*sw/.75;
   1.109 +	    xy<double> mm=m+rot(d)*sw/.75;
   1.110  	    if(_drawArrows) {
   1.111  	      const int INERPOL_PREC=20;
   1.112  	      xy<double> s=_coords[g.source(*e)];
   1.113  	      xy<double> t=_coords[g.target(*e)];
   1.114  	      double rn=_nodeSizes[g.target(*e)]*_nodeScale;
   1.115  	      rn*=rn;
   1.116 -	      Bezier3 bez(s,m,m,t);
   1.117 +	      Bezier3 bez(s,mm,mm,t);
   1.118  	      double t1=0,t2=1;
   1.119  	      for(int i=0;i<INERPOL_PREC;++i)
   1.120  		if((bez((t1+t2)/2)-t).normSquare()>rn) t1=(t1+t2)/2;
   1.121 @@ -472,7 +518,7 @@
   1.122  	    else {
   1.123  	      os << _coords[g.source(*e)].x << ' '
   1.124  		 << _coords[g.source(*e)].y << ' '
   1.125 -		 << m.x << ' ' << m.y << ' '
   1.126 +		 << mm.x << ' ' << mm.y << ' '
   1.127  		 << _coords[g.target(*e)].x << ' '
   1.128  		 << _coords[g.target(*e)].y << ' '
   1.129  		 << _edgeColors[*e].getR() << ' '
   1.130 @@ -509,24 +555,37 @@
   1.131  		  << _edgeColors[e].getG() << ' '
   1.132  		  << _edgeColors[e].getB() << ' '
   1.133  		  << _edgeWidths[e]*_edgeWidthScale << " l\n";
   1.134 -    os << "grestore\n%Nodes:\ngsave\n";
   1.135 -    if(_showNodes)
   1.136 +      os << "grestore\n";
   1.137 +    }
   1.138 +    if(_showNodes) {
   1.139 +      os << "%Nodes:\ngsave\n";
   1.140        for(NodeIt n(g);n!=INVALID;++n)
   1.141  	os << _coords[n].x << ' ' << _coords[n].y << ' '
   1.142  	   << _nodeSizes[n]*_nodeScale << ' '
   1.143  	   << _nodeColors[n].getR() << ' '
   1.144  	   << _nodeColors[n].getG() << ' '
   1.145 -	   << _nodeColors[n].getB() << " n\n"; 
   1.146 +	   << _nodeColors[n].getB() << " n\n";
   1.147 +      os << "grestore\n";
   1.148 +    }
   1.149      if(_showNodeText) {
   1.150 -      os << "grestore\n%Node texts:\ngsave\n";
   1.151 +      os << "%Node texts:\ngsave\n";
   1.152        os << "/fosi " << _nodeTextSize << " def\n";
   1.153        os << "(Helvetica) findfont fosi scalefont setfont\n";
   1.154        os << "0 0 0 setrgbcolor\n";
   1.155        for(NodeIt n(g);n!=INVALID;++n)
   1.156  	os << _coords[n].x << ' ' << _coords[n].y
   1.157  	   << " (" << _nodeTexts[n] << ") cshow\n";
   1.158 +      os << "grestore\n";
   1.159      }
   1.160 -    os << "grestore\ngrestore\n";
   1.161 +    if(_showNodePsText) {
   1.162 +      os << "%Node PS blocks:\ngsave\n";
   1.163 +      for(NodeIt n(g);n!=INVALID;++n)
   1.164 +	os << _coords[n].x << ' ' << _coords[n].y
   1.165 +	   << " moveto\n" << _nodePsTexts[n] << "\n";
   1.166 +      os << "grestore\n";
   1.167 +    }
   1.168 +    
   1.169 +    os << "grestore\n";
   1.170  
   1.171      //CleanUp:
   1.172      if(_pleaseRemoveOsStream) {delete &os;}
   1.173 @@ -576,22 +635,6 @@
   1.174      (DefaultGraphToEpsTraits<G>(g,*new std::ofstream(file_name),true));
   1.175  }
   1.176  
   1.177 -//Generates an EPS file from a graph.
   1.178 -//\param g is a reference to the graph to be printed
   1.179 -//\param file_name is the output file_name.
   1.180 -//
   1.181 -//This function also has a lot of \ref named-templ-param "named parameters",
   1.182 -//they are declared as the members of class \ref GraphToEps. The following
   1.183 -//example shows how to use these parameters.
   1.184 -//\code
   1.185 -// graphToEps(g).scale(10).coords(coords)
   1.186 -//              .nodeScale(2).nodeSizes(sizes)
   1.187 -//              .edgeWidthScale(.4);
   1.188 -//\endcode
   1.189 -//\sa GraphToEps
   1.190 -//\todo Avoid duplicated documentation
   1.191 -//\bug Exception handling is missing? (Or we can just ignore it?)
   1.192 -
   1.193  } //END OF NAMESPACE LEMON
   1.194  
   1.195  #endif // LEMON_GRAPH_TO_EPS_H