Bbox.h
上传用户:kellyonhid
上传日期:2013-10-12
资源大小:932k
文件大小:6k
源码类别:

3D图形编程

开发平台:

Visual C++

  1. //############################################################
  2. // Bbox.h
  3. // Kari Pulli
  4. // 3/17/96
  5. // A 3D bounding box for Pnt3
  6. //############################################################
  7. // we use min and max for our own purposes, so make sure the
  8. // stdlib macros are not defined.  Do this outside of _Bbox_h
  9. // test, so every invocation of bbox.h including the last one
  10. // will clear the namespace, in case bbox.h is included before
  11. // stdlib.h.
  12. #ifdef max
  13. #undef max
  14. #endif
  15. #ifdef min
  16. #undef min
  17. #endif
  18. #ifndef _Bbox_h
  19. #define _Bbox_h
  20. #include <vector.h>
  21. #include <iostream.h>
  22. #include "Pnt3.h"
  23. class Bbox {
  24. private:
  25.   Pnt3 lo,hi;
  26.   Pnt3 c;      // center
  27.   int  cdone;  // has the center been calculated
  28.   void calcCenter(void)
  29.     { 
  30.       if (!cdone) { 
  31. cdone=1;
  32. c = lo; c += hi; c *= .5;
  33.       }
  34.     }
  35.   
  36. public:
  37.   Bbox(void) { clear(); }
  38.   Bbox(Pnt3 const &_lo, Pnt3 const &_hi)
  39.     : lo(_lo), hi(_hi), cdone(0) {}
  40.   ~Bbox(void) {}
  41.   void clear(void)
  42.     {
  43.       hi.set(-1.e33,-1.e33,-1.e33);
  44.       lo.set( 1.e33, 1.e33, 1.e33);
  45.       cdone = 0;
  46.     }
  47.   void add(float x, float y, float z)
  48.     {
  49.       if (x > hi[0]) hi[0] = x;
  50.       if (x < lo[0]) lo[0] = x;
  51.       if (y > hi[1]) hi[1] = y;
  52.       if (y < lo[1]) lo[1] = y;
  53.       if (z > hi[2]) hi[2] = z;
  54.       if (z < lo[2]) lo[2] = z;
  55.       cdone = 0;
  56.     }
  57.   void add(const double *a)
  58.     { add(a[0], a[1], a[2]); }
  59.   void add(const float *a)
  60.     { add(a[0], a[1], a[2]); }
  61.   void add(const Bbox &box)
  62.     { add(box.lo); add(box.hi); }
  63.   const Pnt3 &max(void) const  { return hi; }
  64.   const Pnt3 &min(void) const  { return lo; }
  65.   Pnt3   center(void)          { calcCenter(); return c; }
  66.   float  diag(void) const      { return dist(hi,lo); }
  67.   float maxDim(void) const
  68.     {
  69.       float tmp, ans = hi[0] - lo[0];
  70.       for (int i=1; i<3; i++)
  71. if ((tmp = hi[i] - lo[i]) > ans) ans = tmp;
  72.       return ans;
  73.     }
  74.   float minDim(void) const
  75.     {
  76.       float tmp, ans = hi[0] - lo[0];
  77.       for (int i=1; i<3; i++)
  78. if ((tmp = hi[i] - lo[i]) < ans) ans = tmp;
  79.       return ans;
  80.     }
  81.   float size(void) const  // assume the box is a cube
  82.     { return hi[0]-lo[0]; }
  83.   bool valid (void) const // has anything been added?
  84.     { return size() >= 0; }
  85.   int outside(const Pnt3 &p, float d = 0.0) const
  86.     {
  87.       return (p[0] > hi[0]+d || p[0] < lo[0]-d ||
  88.       p[1] > hi[1]+d || p[1] < lo[1]-d ||
  89.       p[2] > hi[2]+d || p[2] < lo[2]-d);
  90.     }
  91.   void makeCube(float scale)
  92.     {
  93.       // around the center, expand all dimensions equal
  94.       // to the largest one, then scale
  95.       calcCenter();
  96.       float   len = maxDim()*.5*scale;
  97.       Pnt3 tmp(len,len,len);
  98.       hi = c+tmp;
  99.       lo = c-tmp;
  100.     }
  101.   Bbox octant(int i)
  102.     {
  103.       // i in [0,7], e.g. 6 == x hi, y hi, z lo
  104.       calcCenter();
  105.       Bbox ret(*this);
  106.       if (i&4) ret.lo[0] = c[0];
  107.       else     ret.hi[0] = c[0];
  108.       if (i&2) ret.lo[1] = c[1];
  109.       else     ret.hi[1] = c[1];
  110.       if (i&1) ret.lo[2] = c[2];
  111.       else     ret.hi[2] = c[2];
  112.       ret.cdone = 0;
  113.       return ret;
  114.     }
  115.   int inOctant(Pnt3 &p)
  116.     {
  117.       calcCenter();
  118.       return 4*(p[0]>=c[0]) + 2*(p[1]>=c[1]) + (p[2]>=c[2]);
  119.     }
  120.   Pnt3 corner(int i) const
  121.     {
  122.       return Pnt3((i&4) ? hi[0] : lo[0],
  123.   (i&2) ? hi[1] : lo[1],
  124.   (i&1) ? hi[2] : lo[2]);
  125.     }
  126.   Bbox worldBox(float m[16]) const // transformation matrix, OpenGL order
  127.     {
  128.       Bbox ret;
  129.       Pnt3 p;
  130.       ret.add(p.set(hi[0],hi[1],hi[2]).xform(m));
  131.       ret.add(p.set(hi[0],hi[1],lo[2]).xform(m));
  132.       ret.add(p.set(hi[0],lo[1],hi[2]).xform(m));
  133.       ret.add(p.set(hi[0],lo[1],lo[2]).xform(m));
  134.       ret.add(p.set(lo[0],hi[1],hi[2]).xform(m));
  135.       ret.add(p.set(lo[0],hi[1],lo[2]).xform(m));
  136.       ret.add(p.set(lo[0],lo[1],hi[2]).xform(m));
  137.       ret.add(p.set(lo[0],lo[1],lo[2]).xform(m));
  138.       return ret;
  139.     }
  140.   // return pairs of points in e that define the edges
  141.   // of this box
  142.   void edgeList(vector<Pnt3> &e) const
  143.     {
  144.       e.resize(24);
  145.       e[0].set(lo[0],lo[1],lo[2]);
  146.       e[1].set(hi[0],lo[1],lo[2]);
  147.       e[2].set(lo[0],lo[1],lo[2]);
  148.       e[3].set(lo[0],hi[1],lo[2]);
  149.       e[4].set(lo[0],lo[1],lo[2]);
  150.       e[5].set(lo[0],lo[1],hi[2]);
  151.       e[6].set(hi[0],hi[1],hi[2]);
  152.       e[7].set(hi[0],hi[1],lo[2]);
  153.       e[8].set(hi[0],hi[1],hi[2]);
  154.       e[9].set(hi[0],lo[1],hi[2]);
  155.       e[10].set(hi[0],hi[1],hi[2]);
  156.       e[11].set(lo[0],hi[1],hi[2]);
  157.       e[12].set(hi[0],hi[1],lo[2]);
  158.       e[13].set(lo[0],hi[1],lo[2]);
  159.       e[14].set(hi[0],hi[1],lo[2]);
  160.       e[15].set(hi[0],lo[1],lo[2]);
  161.       e[16].set(hi[0],lo[1],hi[2]);
  162.       e[17].set(lo[0],lo[1],hi[2]);
  163.       e[18].set(hi[0],lo[1],hi[2]);
  164.       e[19].set(hi[0],lo[1],lo[2]);
  165.       e[20].set(lo[0],hi[1],hi[2]);
  166.       e[21].set(lo[0],lo[1],hi[2]);
  167.       e[22].set(lo[0],hi[1],hi[2]);
  168.       e[23].set(lo[0],hi[1],lo[2]);
  169.     }
  170.   float max_dist(const Pnt3 &p)
  171.     {
  172.       float d, md = 0.0;
  173.       d = dist(corner(0), p); if (d > md) md = d;
  174.       d = dist(corner(1), p); if (d > md) md = d;
  175.       d = dist(corner(2), p); if (d > md) md = d;
  176.       d = dist(corner(3), p); if (d > md) md = d;
  177.       d = dist(corner(4), p); if (d > md) md = d;
  178.       d = dist(corner(5), p); if (d > md) md = d;
  179.       d = dist(corner(6), p); if (d > md) md = d;
  180.       d = dist(corner(7), p); if (d > md) md = d;
  181.       return md;
  182.     }
  183.   bool intersect(const Bbox &b)
  184.     {
  185.       // find whether any of the faces separate the boxes
  186.       if (hi[0] < b.lo[0]) return false;
  187.       if (hi[1] < b.lo[1]) return false;
  188.       if (hi[2] < b.lo[2]) return false;
  189.       if (b.hi[0] < lo[0]) return false;
  190.       if (b.hi[1] < lo[1]) return false;
  191.       if (b.hi[2] < lo[2]) return false;
  192.       return true;      
  193.     }
  194. };
  195. inline ostream& 
  196. operator<<(ostream &out, const Bbox &a)
  197.   return out << "Bbox: " << a.min() << " " << a.max();
  198. }
  199. #endif