src/work/alpar/graph_to_eps.cc
changeset 1051 4ebe32765b48
parent 1050 bcc0766a7b86
child 1055 f901ff02b2d7
equal deleted inserted replaced
2:9750b321bd89 3:3876f3a68abe
       
     1 #include <iostream>
     1 #include<math.h>
     2 #include<math.h>
       
     3 
     2 #include<lemon/xy.h>
     4 #include<lemon/xy.h>
     3 #include<lemon/maps.h>
     5 #include<lemon/maps.h>
     4 #include<lemon/list_graph.h>
     6 #include<lemon/list_graph.h>
     5 
     7 
     6 
     8 
    47   typedef typename Graph::InEdgeIt InEdgeIt;
    49   typedef typename Graph::InEdgeIt InEdgeIt;
    48   typedef typename Graph::OutEdgeIt OutEdgeIt;
    50   typedef typename Graph::OutEdgeIt OutEdgeIt;
    49   
    51   
    50 
    52 
    51   const Graph &g;
    53   const Graph &g;
       
    54 
       
    55   std::ostream& os;
       
    56   
    52   ConstMap<typename Graph::Node,xy<double> > _coords;
    57   ConstMap<typename Graph::Node,xy<double> > _coords;
    53   ConstMap<typename Graph::Node,double > _nodeSizes;
    58   ConstMap<typename Graph::Node,double > _nodeSizes;
    54 
    59 
    55   ConstMap<typename Graph::Node,Color > _nodeColors;
    60   ConstMap<typename Graph::Node,Color > _nodeColors;
    56   ConstMap<typename Graph::Edge,Color > _edgeColors;
    61   ConstMap<typename Graph::Edge,Color > _edgeColors;
    68   double _arrowLength, _arrowWidth;
    73   double _arrowLength, _arrowWidth;
    69   
    74   
    70   ///Constructor
    75   ///Constructor
    71 
    76 
    72   ///Constructor
    77   ///Constructor
    73   ///\param _g is a reference to the underlying graph
    78   ///\param _g is a reference to the graph to be printed
    74   DefaultGraphToEpsTraits(const G &_g) :
    79   ///\param _os is a reference to the output stream.
    75     g(_g), _coords(xy<double>(1,1)), _nodeSizes(1.0),
    80   ///By default it is <tt>std::cout</tt>
       
    81   DefaultGraphToEpsTraits(const G &_g,std::ostream& _os=std::cout) :
       
    82     g(_g), os(_os),
       
    83     _coords(xy<double>(1,1)), _nodeSizes(1.0),
    76     _nodeColors(Color(1,1,1)), _edgeColors(Color(0,0,0)),
    84     _nodeColors(Color(1,1,1)), _edgeColors(Color(0,0,0)),
    77     _edgeWidths(1), _edgeWidthScale(0.3),
    85     _edgeWidths(1), _edgeWidthScale(0.3),
    78     _nodeScale(1.0), _xBorder(10), _yBorder(10), _scale(1.0),
    86     _nodeScale(1.0), _xBorder(10), _yBorder(10), _scale(1.0),
    79     _nodeBorderQuotient(.1),
    87     _nodeBorderQuotient(.1),
    80     _drawArrows(false), _arrowLength(1), _arrowWidth(0.3) {}
    88     _drawArrows(false), _arrowLength(1), _arrowWidth(0.3) {}
   212   
   220   
   213   ~GraphToEps() 
   221   ~GraphToEps() 
   214   {
   222   {
   215     if(dontPrint) return;
   223     if(dontPrint) return;
   216     
   224     
   217     cout << "%!PS-Adobe-2.0 EPSF-2.0\n";
   225     os << "%!PS-Adobe-2.0 EPSF-2.0\n";
   218     //\todo: Chech whether the graph is empty.
   226     //\todo: Chech whether the graph is empty.
   219     BoundingBox<double> bb;
   227     BoundingBox<double> bb;
   220     for(NodeIt n(g);n!=INVALID;++n) {
   228     for(NodeIt n(g);n!=INVALID;++n) {
   221       double ns=_nodeSizes[n]*_nodeScale;
   229       double ns=_nodeSizes[n]*_nodeScale;
   222       xy<double> p(ns,ns);
   230       xy<double> p(ns,ns);
   223       bb+=p+_coords[n];
   231       bb+=p+_coords[n];
   224       bb+=-p+_coords[n];
   232       bb+=-p+_coords[n];
   225       }
   233       }
   226     cout << "%%BoundingBox: "
   234     os << "%%BoundingBox: "
   227 	 << bb.left()*  _scale-_xBorder << ' '
   235 	 << bb.left()*  _scale-_xBorder << ' '
   228 	 << bb.bottom()*_scale-_yBorder << ' '
   236 	 << bb.bottom()*_scale-_yBorder << ' '
   229 	 << bb.right()* _scale+_xBorder << ' '
   237 	 << bb.right()* _scale+_xBorder << ' '
   230 	 << bb.top()*   _scale+_yBorder << '\n';
   238 	 << bb.top()*   _scale+_yBorder << '\n';
   231     //x1 y1 x2 y2 cr cg cb w
   239     //x1 y1 x2 y2 cr cg cb w
   232     cout << "/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def\n";
   240     os << "/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def\n";
   233     cout << "/c { newpath dup 3 index add 2 index moveto 0 360 arc } bind def\n";
   241     os << "/c { newpath dup 3 index add 2 index moveto 0 360 arc } bind def\n";
   234     // x y r cr cg cb
   242     // x y r cr cg cb
   235     cout << "/n { setrgbcolor 2 index 2 index 2 index c fill\n"
   243     os << "/n { setrgbcolor 2 index 2 index 2 index c fill\n"
   236 	 << "     0 0 0 setrgbcolor dup "
   244 	 << "     0 0 0 setrgbcolor dup "
   237 	 << _nodeBorderQuotient << " mul setlinewidth "
   245 	 << _nodeBorderQuotient << " mul setlinewidth "
   238 	 << 1+_nodeBorderQuotient/2 << " div c stroke\n"
   246 	 << 1+_nodeBorderQuotient/2 << " div c stroke\n"
   239 	 << "   } bind def\n";
   247 	 << "   } bind def\n";
   240     cout << "/arrl " << _arrowLength << " def\n";
   248     os << "/arrl " << _arrowLength << " def\n";
   241     cout << "/arrw " << _arrowWidth << " def\n";
   249     os << "/arrw " << _arrowWidth << " def\n";
   242     // l dx_norm dy_norm
   250     // l dx_norm dy_norm
   243     cout << "/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def\n";
   251     os << "/lrl { 2 index mul exch 2 index mul exch rlineto pop} bind def\n";
   244     //len w dx_norm dy_norm x1 y1 cr cg cb
   252     //len w dx_norm dy_norm x1 y1 cr cg cb
   245     cout << "/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def\n"
   253     os << "/arr { setrgbcolor /y1 exch def /x1 exch def /dy exch def /dx exch def\n"
   246 	 << "       /w exch def /len exch def\n"
   254 	 << "       /w exch def /len exch def\n"
   247       //	 << "       0.1 setlinewidth x1 y1 moveto dx len mul dy len mul rlineto stroke"
   255       //	 << "       0.1 setlinewidth x1 y1 moveto dx len mul dy len mul rlineto stroke"
   248 	 << "       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto\n"
   256 	 << "       newpath x1 dy w 2 div mul add y1 dx w 2 div mul sub moveto\n"
   249 	 << "       len w sub arrl sub dx dy lrl\n"
   257 	 << "       len w sub arrl sub dx dy lrl\n"
   250 	 << "       arrw dy dx neg lrl\n"
   258 	 << "       arrw dy dx neg lrl\n"
   253 	 << "       dx arrl w add mul neg dy w 2 div arrw add mul sub\n"
   261 	 << "       dx arrl w add mul neg dy w 2 div arrw add mul sub\n"
   254 	 << "       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto\n"
   262 	 << "       dy arrl w add mul neg dx w 2 div arrw add mul add rlineto\n"
   255 	 << "       arrw dy dx neg lrl\n"
   263 	 << "       arrw dy dx neg lrl\n"
   256 	 << "       len w sub arrl sub neg dx dy lrl\n"
   264 	 << "       len w sub arrl sub neg dx dy lrl\n"
   257 	 << "       closepath fill } bind def\n";
   265 	 << "       closepath fill } bind def\n";
   258     cout << "\ngsave\n";
   266     os << "\ngsave\n";
   259     if(_scale!=1.0) cout << _scale << " dup scale\n";
   267     if(_scale!=1.0) os << _scale << " dup scale\n";
   260     cout << "%Edges:\ngsave\n";
   268     os << "%Edges:\ngsave\n";
   261     for(NodeIt n(g);n!=INVALID;++n)
   269     for(NodeIt n(g);n!=INVALID;++n)
   262       for(OutEdgeIt e(g,n);e!=INVALID;++e)
   270       for(OutEdgeIt e(g,n);e!=INVALID;++e)
   263 	if(_drawArrows) {
   271 	if(_drawArrows) {
   264 	  xy<double> d(_coords[g.target(e)]-_coords[g.source(e)]);
   272 	  xy<double> d(_coords[g.target(e)]-_coords[g.source(e)]);
   265 	  double l=sqrt(d.normSquare());
   273 	  double l=sqrt(d.normSquare());
   266 	  d/=l;
   274 	  d/=l;
   267 	  xy<double> x1(d*_nodeScale*_nodeSizes[g.source(e)]+
   275 	  xy<double> x1(d*_nodeScale*_nodeSizes[g.source(e)]+
   268 			_coords[g.source(e)]);
   276 			_coords[g.source(e)]);
   269 	  cout << l-(_nodeSizes[g.source(e)]+
   277 	  os << l-(_nodeSizes[g.source(e)]+
   270 		     _nodeSizes[g.target(e)])*_nodeScale << ' '
   278 		     _nodeSizes[g.target(e)])*_nodeScale << ' '
   271 	       << _edgeWidths[e]*_edgeWidthScale << ' '
   279 	       << _edgeWidths[e]*_edgeWidthScale << ' '
   272 	       << d.x << ' ' << d.y << ' '
   280 	       << d.x << ' ' << d.y << ' '
   273 	       << x1.x << ' ' << x1.y << ' '
   281 	       << x1.x << ' ' << x1.y << ' '
   274 	       << _edgeColors[e].getR() << ' '
   282 	       << _edgeColors[e].getR() << ' '
   275 	       << _edgeColors[e].getG() << ' '
   283 	       << _edgeColors[e].getG() << ' '
   276 	       << _edgeColors[e].getB() << " arr\n";
   284 	       << _edgeColors[e].getB() << " arr\n";
   277 	}
   285 	}
   278     	else cout << _coords[g.source(e)].x << ' '
   286     	else os << _coords[g.source(e)].x << ' '
   279 		  << _coords[g.source(e)].y << ' '
   287 		  << _coords[g.source(e)].y << ' '
   280 		  << _coords[g.target(e)].x << ' '
   288 		  << _coords[g.target(e)].x << ' '
   281 		  << _coords[g.target(e)].y << ' '
   289 		  << _coords[g.target(e)].y << ' '
   282 		  << _edgeColors[e].getR() << ' '
   290 		  << _edgeColors[e].getR() << ' '
   283 		  << _edgeColors[e].getG() << ' '
   291 		  << _edgeColors[e].getG() << ' '
   284 		  << _edgeColors[e].getB() << ' '
   292 		  << _edgeColors[e].getB() << ' '
   285 		  << _edgeWidths[e]*_edgeWidthScale << " l\n";
   293 		  << _edgeWidths[e]*_edgeWidthScale << " l\n";
   286     cout << "grestore\n%Nodes:\ngsave\n";
   294     os << "grestore\n%Nodes:\ngsave\n";
   287     for(NodeIt n(g);n!=INVALID;++n)
   295     for(NodeIt n(g);n!=INVALID;++n)
   288       cout << _coords[n].x << ' ' << _coords[n].y << ' '
   296       os << _coords[n].x << ' ' << _coords[n].y << ' '
   289 	   << _nodeSizes[n]*_nodeScale << ' '
   297 	   << _nodeSizes[n]*_nodeScale << ' '
   290 	   << _nodeColors[n].getR() << ' '
   298 	   << _nodeColors[n].getR() << ' '
   291 	   << _nodeColors[n].getG() << ' '
   299 	   << _nodeColors[n].getG() << ' '
   292 	   << _nodeColors[n].getB() << " n\n"; 
   300 	   << _nodeColors[n].getB() << " n\n"; 
   293     cout << "grestore\ngrestore\n";
   301     os << "grestore\ngrestore\n";
   294   } 
   302   } 
   295 };
   303 };
   296 
   304 
   297 
   305 
   298 ///Generates an EPS file from a graph
   306 ///Generates an EPS file from a graph
   299 
   307 
   300 ///\ingroup misc
   308 ///\ingroup misc
   301 ///Generates an EPS file from a graph.
   309 ///Generates an EPS file from a graph.
       
   310 ///\param g is a reference to the graph to be printed
       
   311 ///\param os is a reference to the output stream.
       
   312 ///By default it is <tt>std::cout</tt>
   302 ///
   313 ///
   303 ///This function has a lot of \ref named-templ-param "named parameters",
   314 ///This function also has a lot of \ref named-templ-param "named parameters",
   304 ///they are declared as the members of class \ref GraphToEps. The following
   315 ///they are declared as the members of class \ref GraphToEps. The following
   305 ///example shows how to use these parameters.
   316 ///example shows how to use these parameters.
   306 ///\code
   317 ///\code
   307 /// graphToEps(g).scale(10).coords(coords)
   318 /// graphToEps(g).scale(10).coords(coords)
   308 ///              .nodeScale(2).nodeSizes(sizes)
   319 ///              .nodeScale(2).nodeSizes(sizes)
   309 ///              .edgeWidthScale(.4);
   320 ///              .edgeWidthScale(.4);
   310 ///\endcode
   321 ///\endcode
   311 ///\sa GraphToEps
   322 ///\sa GraphToEps
   312 template<class G>
   323 template<class G>
   313 GraphToEps<DefaultGraphToEpsTraits<G> > graphToEps(G &g)
   324 GraphToEps<DefaultGraphToEpsTraits<G> > graphToEps(G &g,std::ostream& os=std::cout)
   314 {
   325 {
   315   return GraphToEps<DefaultGraphToEpsTraits<G> >(DefaultGraphToEpsTraits<G>(g));
   326   return GraphToEps<DefaultGraphToEpsTraits<G> >(DefaultGraphToEpsTraits<G>(g));
   316 }
   327 }
   317  
   328  
   318 }
   329 }