"Fossies" - the Fresh Open Source Software Archive

Member "asymptote-2.61/bbox.h" (18 Nov 2019, 4503 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 "bbox.h" see the Fossies "Dox" file reference documentation.

    1 /*****
    2  * bbox.h
    3  * Andy Hammerlindl 2002/06/06
    4  *
    5  * Stores a rectangle that encloses a drawing object.
    6  *****/
    7 
    8 #ifndef BBOX_H
    9 #define BBOX_H
   10 
   11 #include "pair.h"
   12 #include "settings.h"
   13 
   14 namespace camp {
   15 
   16 template<class T>
   17 inline T min(T a, T b)
   18 {
   19   return (a < b) ? a : b;
   20 }
   21 
   22 template<class T>  
   23 inline T max(T a, T b)
   24 {
   25   return (a > b) ? a : b;
   26 }
   27 
   28 // The box that encloses a path
   29 struct bbox {
   30   bool empty;
   31   double left;
   32   double bottom;
   33   double right;
   34   double top;
   35   
   36   // Start bbox about the origin
   37   bbox()
   38     : empty(true), left(0.0), bottom(0.0), right(0.0), top(0.0)
   39   {
   40   }
   41 
   42   bbox(double left, double bottom, double right, double top)
   43     : empty(false), left(left), bottom(bottom), right(right), top(top)
   44   {
   45   }
   46 
   47   // Start a bbox with a point
   48   bbox(const pair& z)
   49     : empty(false), left(z.getx()), bottom(z.gety()),
   50       right(z.getx()), top(z.gety())
   51   {
   52   }
   53 
   54   bool nonempty() const {
   55     return !empty;
   56   }
   57  
   58   // Add a point to a bbox
   59   bbox add(const pair& z)
   60   {
   61     double x = z.getx(), y = z.gety();
   62 
   63     if (empty) {
   64       left = right = x;
   65       top = bottom = y;
   66       empty = false;
   67     }
   68     else {
   69       if (x < left)
   70         left = x;  
   71       else if (x > right)
   72         right = x;  
   73       if (y < bottom)
   74         bottom = y;
   75       else if (y > top)
   76         top = y;
   77     }
   78 
   79     return *this;
   80   }
   81 
   82   // Add a point to a nonempty bbox
   83   void addnonempty(const pair& z)
   84   {
   85     double x = z.getx(), y = z.gety();
   86     if (x < left)
   87       left = x;  
   88     else if (x > right)
   89       right = x;  
   90     if (y < bottom)
   91       bottom = y;
   92     else if (y > top)
   93       top = y;
   94   }
   95 
   96   // Add a point to a nonempty bbox, updating bounding times
   97   void addnonempty(const pair& z, bbox& times, double t)
   98   {
   99     double x = z.getx(), y = z.gety();
  100 
  101     if (x < left) {
  102       left = x;  
  103       times.left = t;
  104     }
  105     else if (x > right) {
  106       right = x;  
  107       times.right = t;
  108     }
  109     if (y < bottom) {
  110       bottom = y;
  111       times.bottom = t;
  112     }
  113     else if (y > top) {
  114       top = y;
  115       times.top = t;
  116     }
  117   }
  118 
  119   bbox operator+= (const pair& z)
  120   {
  121     add(z);
  122     return *this;
  123   }
  124 
  125   bbox operator*= (double x)
  126   {
  127     left *= x;
  128     right *= x;
  129     top *= x;
  130     bottom *=x;
  131     return *this;
  132   }
  133 
  134   // Add two bounding boxes
  135   friend bbox operator+ (const bbox& b1, const bbox& b2)
  136   {
  137     if (b1.empty)
  138       return b2;
  139     else if (b2.empty)
  140       return b1;
  141     else
  142       return bbox(min(b1.left, b2.left),
  143                   max(b1.right, b2.right),
  144                   min(b1.bottom, b2.bottom),
  145                   max(b1.top, b2.top));
  146   }
  147 
  148   // Add one bounding box to another
  149   void add(const bbox& b)
  150   {
  151     if (this->empty)
  152       *this = b;
  153     else if (!b.empty) {
  154       left = min(left, b.left);
  155       right = max(right, b.right);
  156       bottom = min(bottom, b.bottom);
  157       top = max(top, b.top);
  158     }
  159   }
  160 
  161   bbox operator+= (const bbox& b)
  162   {
  163     add(b);
  164     return *this;
  165   }
  166 
  167   void clip(const bbox& b) {
  168     if(this->empty) return;
  169     left = max(left, b.left);
  170     right = min(right, b.right);
  171     bottom = max(bottom, b.bottom);
  172     top = min(top, b.top);
  173     if(left > right || bottom > top) 
  174       *this=bbox();
  175   }
  176   
  177   void shift(const pair& p) {
  178     left += p.getx();
  179     right += p.getx();
  180     bottom += p.gety();
  181     top += p.gety();
  182   }
  183   
  184   pair Min() const {
  185     return pair(left,bottom);
  186   }
  187   
  188   pair Max() const {
  189     return pair(right,top);
  190   }
  191   
  192   double diameter() {
  193     return (Max()-Min()).length();
  194   }
  195   
  196   bbox LowRes() const
  197   {
  198     return bbox(floor(left),floor(bottom),ceil(right),ceil(top));
  199   }
  200   
  201   friend ostream& operator<< (ostream& out, const bbox& b)
  202   {
  203     out << b.left << " " << b.bottom << " " << b.right << " " << b.top;
  204     return out;
  205   }
  206 };
  207 
  208 // Add results of both bounding boxes, say for a path and a pen.
  209 inline bbox pad(bbox b1, bbox b2)
  210 {
  211   if (b1.empty)
  212     return b2;
  213   else if (b2.empty)
  214     return b1;
  215   else {
  216     bbox b;
  217     b.empty = false;
  218     b.left = b1.left + b2.left;
  219     b.right = b1.right + b2.right;
  220     b.top = b1.top + b2.top;
  221     b.bottom = b1.bottom + b2.bottom;
  222     return b;
  223   }
  224 }
  225 
  226 inline bbox svgbbox(const bbox& B, pair shift=pair(0,0))
  227 {
  228   bbox b=B;
  229   double height=b.top-b.bottom;
  230   double threshold=12.0*settings::tex2ps;
  231   if(height < threshold) {
  232     double offset=threshold-height;
  233     b.top += offset;
  234     b.bottom += offset;
  235   }
  236   b.shift(pair(1.99*settings::cm,1.9*settings::cm)+shift);
  237   return b;
  238 }
  239 
  240 } // namespace camp
  241 
  242 GC_DECLARE_PTRFREE(camp::bbox);
  243 
  244 #endif