COIN-OR::LEMON - Graph Library

Changeset 1086:caa13d291528 in lemon-0.x for src/lemon/graph_to_eps.h


Ignore:
Timestamp:
01/18/05 13:02:27 (16 years ago)
Author:
Alpar Juttner
Branch:
default
Phase:
public
Convert:
svn:c9d7d8f5-90d6-0310-b91f-818b3a526b0e/lemon/trunk@1482
Message:

In graphToEps(), nodes may have different shapes (circles or squares).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/lemon/graph_to_eps.h

    r1085 r1086  
    8181  ConstMap<typename Graph::Node,xy<double> > _coords;
    8282  ConstMap<typename Graph::Node,double > _nodeSizes;
     83  ConstMap<typename Graph::Node,int > _nodeShapes;
    8384
    8485  ConstMap<typename Graph::Node,Color > _nodeColors;
     
    124125                          bool _pros=false) :
    125126    g(_g), os(_os),
    126     _coords(xy<double>(1,1)), _nodeSizes(1.0),
     127    _coords(xy<double>(1,1)), _nodeSizes(1.0), _nodeShapes(0),
    127128    _nodeColors(Color(1,1,1)), _edgeColors(Color(0,0,0)),
    128129    _edgeWidths(1), _edgeWidthScale(0.3),
     
    155156  bool dontPrint;
    156157
     158  enum NodeShapes { CIRCLE=0, SQUARE=1 };
     159                   
    157160  class edgeLess {
    158161    const Graph &g;
     
    215218    return GraphToEps<NodeSizesTraits<X> >(NodeSizesTraits<X>(*this,x));
    216219  }
     220  template<class X> struct NodeShapesTraits : public T {
     221    const X &_nodeShapes;
     222    NodeShapesTraits(const T &t,const X &x) : T(t), _nodeShapes(x) {}
     223  };
     224  ///Sets the map of the node shapes
     225
     226  ///Sets the map of the node shapes
     227  ///\param x must be a node map with \c int (or convertible) values.
     228  ///\todo Incomplete doc.
     229  template<class X> GraphToEps<NodeShapesTraits<X> > nodeShapes(const X &x)
     230  {
     231    dontPrint=true;
     232    return GraphToEps<NodeShapesTraits<X> >(NodeShapesTraits<X>(*this,x));
     233  }
    217234  template<class X> struct NodeTextsTraits : public T {
    218235    const X &_nodeTexts;
     
    387404  ///Use it to show the undirected edges as a pair of directed ones.
    388405  GraphToEps<T> &bidir(bool b=true) {_undir=!b;return *this;}
    389  
     406
     407protected:
     408  bool isInsideNode(xy<double> p, double r,int t)
     409  {
     410    switch(t) {
     411    case CIRCLE:
     412      return p.normSquare()<=r*r;
     413    case SQUARE:
     414      return p.x<=r&&p.x>=-r&&p.y<=r&&p.y>=-r;
     415    }
     416    return false;
     417  }
     418
     419public:
    390420  ~GraphToEps()
    391421  {
     
    410440       << "      4 2 roll 1 index 1 index curveto stroke } bind def\n";
    411441    os << "/l { setlinewidth setrgbcolor newpath moveto lineto stroke } bind def\n";
     442    //x y r
    412443    os << "/c { newpath dup 3 index add 2 index moveto 0 360 arc closepath } bind def\n";
     444    //x y r
     445    os << "/sq { newpath 2 index 1 index add 2 index 2 index add moveto\n"
     446       << "      2 index 1 index sub 2 index 2 index add lineto\n"
     447       << "      2 index 1 index sub 2 index 2 index sub lineto\n"
     448       << "      2 index 1 index add 2 index 2 index sub lineto\n"
     449       << "      closepath pop pop pop} bind def\n";
    413450    // x y r cr cg cb
    414     os << "/n { setrgbcolor 2 index 2 index 2 index c fill\n"
     451    os << "/nc { setrgbcolor 2 index 2 index 2 index c fill\n"
    415452       << "     0 0 0 setrgbcolor dup "
    416453       << _nodeBorderQuotient << " mul setlinewidth "
    417454       << 1+_nodeBorderQuotient/2 << " div c stroke\n"
     455       << "   } bind def\n";
     456    os << "/nsq { setrgbcolor 2 index 2 index 2 index sq fill\n"
     457       << "     0 0 0 setrgbcolor dup "
     458       << _nodeBorderQuotient << " mul setlinewidth "
     459       << 1+_nodeBorderQuotient/2 << " div sq stroke\n"
    418460       << "   } bind def\n";
    419461    os << "/arrl " << _arrowLength << " def\n";
     
    475517            xy<double> mm=m+rot(d)*sw/.75;
    476518            if(_drawArrows) {
     519              int node_shape;
    477520              const int INERPOL_PREC=20;
    478521              xy<double> s=_coords[g.source(*e)];
    479522              xy<double> t=_coords[g.target(*e)];
    480523              double rn=_nodeSizes[g.target(*e)]*_nodeScale;
    481               rn*=rn;
     524              node_shape=_nodeShapes[g.target(*e)];
    482525              Bezier3 bez(s,mm,mm,t);
    483526              double t1=0,t2=1;
    484527              for(int i=0;i<INERPOL_PREC;++i)
    485                 if((bez((t1+t2)/2)-t).normSquare()>rn) t1=(t1+t2)/2;
    486                 else t2=(t1+t2)/2;
     528                if(isInsideNode(bez((t1+t2)/2)-t,rn,node_shape)) t2=(t1+t2)/2;
     529                else t1=(t1+t2)/2;
    487530              xy<double> apoint=bez((t1+t2)/2);
    488               rn = _nodeSizes[g.target(*e)]*_nodeScale+_arrowLength+
    489                 _edgeWidths[*e]*_edgeWidthScale;
     531              rn = _arrowLength+_edgeWidths[*e]*_edgeWidthScale;
    490532              rn*=rn;
    491               t1=0;t2=1;
     533              t2=(t1+t2)/2;t1=0;
    492534              for(int i=0;i<INERPOL_PREC;++i)
    493                 if((bez((t1+t2)/2)-t).normSquare()>rn) t1=(t1+t2)/2;
     535                if((bez((t1+t2)/2)-apoint).normSquare()>rn) t1=(t1+t2)/2;
    494536                else t2=(t1+t2)/2;
    495537              xy<double> linend=bez((t1+t2)/2);       
    496538              bez=bez.before((t1+t2)/2);
    497               rn=_nodeSizes[g.source(*e)]*_nodeScale; rn*=rn;
    498               t1=0;t2=1;
    499               for(int i=0;i<INERPOL_PREC;++i)
    500                 if((bez((t1+t2)/2)-s).normSquare()>rn) t2=(t1+t2)/2;
    501                 else t1=(t1+t2)/2;
    502               bez=bez.after((t1+t2)/2);
     539//            rn=_nodeSizes[g.source(*e)]*_nodeScale;
     540//            node_shape=_nodeShapes[g.source(*e)];
     541//            t1=0;t2=1;
     542//            for(int i=0;i<INERPOL_PREC;++i)
     543//              if(isInsideNode(bez((t1+t2)/2)-t,rn,node_shape)) t1=(t1+t2)/2;
     544//              else t2=(t1+t2)/2;
     545//            bez=bez.after((t1+t2)/2);
    503546              os << _edgeWidths[*e]*_edgeWidthScale << " setlinewidth "
    504547                 << _edgeColors[*e].getR() << ' '
     
    560603    if(_showNodes) {
    561604      os << "%Nodes:\ngsave\n";
    562       for(NodeIt n(g);n!=INVALID;++n)
     605      for(NodeIt n(g);n!=INVALID;++n) {
    563606        os << _coords[n].x << ' ' << _coords[n].y << ' '
    564607           << _nodeSizes[n]*_nodeScale << ' '
    565608           << _nodeColors[n].getR() << ' '
    566609           << _nodeColors[n].getG() << ' '
    567            << _nodeColors[n].getB() << " n\n";
     610           << _nodeColors[n].getB() << ' ';
     611        switch(_nodeShapes[n]) {
     612        case CIRCLE:
     613          os<< "nc";break;
     614        case SQUARE:
     615          os<< "nsq";break;
     616        }
     617        os<<'\n';
     618      }
    568619      os << "grestore\n";
    569620    }
Note: See TracChangeset for help on using the changeset viewer.