"Fossies" - the Fresh Open Source Software Archive

Member "asymptote-2.61/flatguide.h" (18 Nov 2019, 4231 Bytes) of package /linux/misc/asymptote-2.61.src.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "flatguide.h" see the Fossies "Dox" file reference documentation.

    1 /*****
    2  * flatguide.h
    3  * Andy Hammerlindl 2005/02/23
    4  *
    5  * The data structure that builds up a knotlist.  This is done by calling in
    6  * order the methods to set knots, specifiers, and tensions.
    7  * Used by the guide solving routines.
    8  *
    9  * NOTE: figure out how nullpath{}..a should be handled.
   10  *****/
   11 
   12 #ifndef FLATGUIDE_H
   13 #define FLATGUIDE_H
   14 
   15 #include "knot.h"
   16 #include "guideflags.h"
   17 
   18 namespace camp {
   19 
   20 class flatguide
   21 {
   22   // A cached solution of the path.  When traversing through a tree of guides,
   23   // if a cycle tag is encountered, then the path is solved up to that point.
   24   // If the guide continues from there (which rarely occurs in practice), all of
   25   // the control points solved are added as control specifiers, and then solved
   26   // into a path again.  In the (usual) case that a cycle ends a path, the
   27   // cached path avoids this second pass.
   28   bool solved;
   29   
   30   // Used by reverse(guide) to indicate the presence of an unresolved
   31   // interior cycle.
   32   bool precycle;
   33   
   34   path p;
   35 
   36   cvector<knot> nodes;
   37 
   38   // Information before the first knot.  For a non-cyclic guide, this is
   39   // ignored.  For a cyclic guide, it may be useful, but I can't determine a
   40   // sensible way to use it yet.
   41   tension tout;
   42   spec *out;
   43 
   44   // Information for the next knot to come.
   45   tension tin;
   46   spec *in;
   47 
   48   static spec open;
   49 
   50   tension& tref(side s)
   51   {
   52     switch (s) {
   53       case OUT:
   54         return nodes.empty() ? tout : nodes.back().tout;
   55       case IN:
   56       default:
   57         return tin;
   58     }
   59   }
   60 
   61   // Returns a reference to a spec* so that it may be assigned.
   62   spec*& sref(side s)
   63   {
   64     switch (s) {
   65       case OUT:
   66         return nodes.empty() ? out : nodes.back().out;
   67       case IN:
   68       default:
   69         return in;
   70     }
   71   }
   72 
   73   void addPre(path& p, Int j);
   74   void addPoint(path& p, Int j);
   75   void addPost(path& p, Int j);
   76 
   77   void clearNodes() {
   78     nodes.clear();
   79     in=&open;
   80     tin=tension();
   81   }
   82   void clearPath() {
   83     p=path();
   84     solved=false;
   85   }
   86 
   87   void uncheckedAdd(path p, bool allowsolve=true);
   88 
   89   // Sets solved to false, indicating that the path has been updated since last
   90   // being solved.  Also, copies a solved path back in as knots and control
   91   // specifiers, as it will have to be solved again.
   92   void update() {
   93     if (solved) {
   94       solved=false;
   95       clearNodes();
   96       add(p);
   97       clearPath();
   98     }
   99   }
  100       
  101 public:
  102   flatguide()
  103     : solved(true), precycle(false), p(), out(&open), in(&open) {}
  104 
  105   Int size() const {
  106     return (Int) nodes.size();
  107   }
  108   
  109   knot Nodes(Int i) const {
  110     return nodes[i];
  111   }
  112   
  113   void setTension(tension t, side s) {
  114     update();
  115     tref(s)=t;
  116   }
  117   void setSpec(spec *p, side s) {
  118     assert(p);
  119     update();
  120     spec *&ref=sref(s);
  121     // Control specifiers trump normal direction specifiers.
  122     if (!ref || !ref->controlled() || p->controlled())
  123       ref=p;
  124   }
  125 
  126   void add(pair z) {
  127     update();
  128     // Push the pair onto the vector as a knot, using the current in-specifier
  129     // and in-tension for the in side for the knot. Use default values for the
  130     // out side, as those will be set after the point is added.
  131     nodes.push_back(knot(z,in,&open,tin,tension()));
  132 
  133     // Reset the in-spec and in-tension to defaults;
  134     tin=tension();
  135     in=&open;
  136   }
  137 
  138   // Reverts to an empty state.
  139   void add(path p, bool allowsolve=true) {
  140     update();
  141     uncheckedAdd(p,allowsolve);
  142   }
  143 
  144   void clear() {
  145     clearNodes();
  146     clearPath();
  147   }
  148 
  149   void close() {
  150     if(!nodes.empty()) {
  151       nodes.front().in=in;
  152       nodes.front().tin=tin;
  153     }
  154   }
  155   
  156   void resolvecycle() {
  157     if(!nodes.empty())
  158       nodes.push_back(nodes.front());
  159   }
  160   
  161   void precyclic(bool b) {
  162     precycle=b;
  163   }
  164   
  165   bool precyclic() {
  166     return precycle;
  167   }
  168   
  169   // Once all information has been added, release the flat result.
  170   simpleknotlist list(bool cycles=false) {
  171     if(cycles && !nodes.empty()) close();
  172     return simpleknotlist(nodes,cycles);
  173   }
  174 
  175   // Yield a path from the guide as represented here.
  176   path solve(bool cycles=false) {
  177     if (solved)
  178       return p;
  179     else {
  180       simpleknotlist l=list(cycles);
  181       p=camp::solve(l);
  182       solved=true;
  183       return p;
  184     }
  185   }
  186 };
  187 
  188 } // namespace camp
  189 
  190 #endif // FLATGUIDE_H