# 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) {