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

3D图形编程

开发平台:

Visual C++

  1. // Template Numerical Toolkit (TNT) for Linear Algebra
  2. //
  3. // BETA VERSION INCOMPLETE AND SUBJECT TO CHANGE
  4. // Please see http://math.nist.gov/tnt for updates
  5. //
  6. // R. Pozo
  7. // Mathematical and Computational Sciences Division
  8. // National Institute of Standards and Technology
  9. // 2D Regions for arrays and matrices
  10. #ifndef REGION2D_H
  11. #define REGION2D_H
  12. #include "index.h"
  13. #include <iostream.h>
  14. #include <assert.h>
  15. // const_Region2D needs the T parameter -- cannot rely on 
  16. // Array2D::element_type for definition later. (possible compiler
  17. // g++ bug?)
  18. template <class Array2D, class T>
  19. class const_Region2D;
  20. template <class Array2D /*, class T */>
  21. class Region2D
  22. {
  23.     protected:
  24.         Array2D &  A_;
  25.         Subscript offset_[2];       // 0-offset internally
  26.         Subscript dim_[2];
  27.     public:
  28.         typedef typename Array2D::value_type T;
  29.         typedef Subscript   size_type;
  30.         typedef         T   value_type;
  31.         typedef         T   element_type;
  32.         typedef         T*  pointer;
  33.         typedef         T*  iterator;
  34.         typedef         T&  reference;
  35.         typedef const   T*  const_iterator;
  36.         typedef const   T&  const_reference;
  37.         Array2D & array() { return A_; }
  38.         const Array2D & array()  const { return A_; }
  39.         Subscript lbound() const { return A_.lbound(); }
  40.         Subscript num_rows() const { return dim_[0]; }
  41.         Subscript num_cols() const { return dim_[1]; }
  42.         Subscript offset(Subscript i) const                 // 1-offset
  43.         {
  44. #ifdef TNT_BOUNDS_CHECK
  45.             assert( A_.lbound() <= i);
  46.             assert( i<= dim_[0] + A_.lbound()-1);
  47. #endif
  48.             return offset_[i-A_.lbound()];
  49.         }
  50.         Subscript dim(Subscript i) const
  51.         {
  52. #ifdef TNT_BOUNDS_CHECK
  53.             assert( A_.lbound() <= i);
  54.             assert( i<= dim_[0] + A_.lbound()-1);
  55. #endif
  56.             return dim_[i-A_.lbound()];
  57.         }
  58.         Region2D(Array2D &A, Subscript i1, Subscript i2, Subscript j1,
  59.                 Subscript j2) : A_(A)
  60.         {
  61. #ifdef TNT_BOUNDS_CHECK
  62.             assert( i1 <= i2 );
  63.             assert( j1 <= j2);
  64.             assert( A.lbound() <= i1);
  65.             assert( i2<= A.dim(A.lbound()) + A.lbound()-1);
  66.             assert( A.lbound() <= j1);
  67.             assert( j2<= A.dim(A.lbound()+1) + A.lbound()-1 );
  68. #endif
  69.             offset_[0] = i1-A.lbound();
  70.             offset_[1] = j1-A.lbound();
  71.             dim_[0] = i2-i1+1;
  72.             dim_[1] = j2-j1+1;
  73.         }
  74.         Region2D(Array2D &A, const Index1D &I, const Index1D &J) : A_(A)
  75.         {
  76. #ifdef TNT_BOUNDS_CHECK
  77.             assert( I.lbound() <= I.ubound() );
  78.             assert( J.lbound() <= J.ubound() );
  79.             assert( A.lbound() <= I.lbound());
  80.             assert( I.ubound()<= A.dim(A.lbound()) + A.lbound()-1);
  81.             assert( A.lbound() <= J.lbound());
  82.             assert( J.ubound() <= A.dim(A.lbound()+1) + A.lbound()-1 );
  83. #endif
  84.             offset_[0] = I.lbound()-A.lbound();
  85.             offset_[1] = J.lbound()-A.lbound();
  86.             dim_[0] = I.ubound() - I.lbound() + 1;
  87.             dim_[1] = J.ubound() - J.lbound() + 1;
  88.         }
  89.         Region2D(Region2D<Array2D> &A, Subscript i1, Subscript i2,
  90.             Subscript j1, Subscript j2) : A_(A.A_)
  91.         {
  92. #ifdef TNT_BOUNDS_CHECK
  93.             assert( i1 <= i2 );
  94.             assert( j1 <= j2);
  95.             assert( A.lbound() <= i1);
  96.             assert( i2<= A.dim(A.lbound()) + A.lbound()-1);
  97.             assert( A.lbound() <= j1);
  98.             assert( j2<= A.dim(A.lbound()+1) + A.lbound()-1 );
  99. #endif
  100.             offset_[0] = (i1 - A.lbound()) + A.offset_[0];
  101.             offset_[1] = (j1 - A.lbound()) + A.offset_[1];
  102.             dim_[0] = i2-i1 + 1;
  103.             dim_[1] = j2-j1+1;
  104.         }
  105.         Region2D<Array2D> operator()(Subscript i1, Subscript i2,
  106.                 Subscript j1, Subscript j2)
  107.         {
  108. #ifdef TNT_BOUNDS_CHECK
  109.             assert( i1 <= i2 );
  110.             assert( j1 <= j2);
  111.             assert( A_.lbound() <= i1);
  112.             assert( i2<= dim_[0] + A_.lbound()-1);
  113.             assert( A_.lbound() <= j1);
  114.             assert( j2<= dim_[1] + A_.lbound()-1 );
  115. #endif
  116.             return Region2D<Array2D>(A_, 
  117.                     i1+offset_[0], offset_[0] + i2, 
  118.                     j1+offset_[1], offset_[1] + j2);
  119.         }
  120.         Region2D<Array2D> operator()(const Index1D &I,
  121.                 const Index1D &J)
  122.         {
  123. #ifdef TNT_BOUNDS_CHECK
  124.             assert( I.lbound() <= I.ubound() );
  125.             assert( J.lbound() <= J.ubound() );
  126.             assert( A_.lbound() <= I.lbound());
  127.             assert( I.ubound()<= dim_[0] + A_.lbound()-1);
  128.             assert( A_.lbound() <= J.lbound());
  129.             assert( J.ubound() <= dim_[1] + A_.lbound()-1 );
  130. #endif
  131.             return Region2D<Array2D>(A_, I.lbound()+offset_[0],
  132.                 offset_[0] + I.ubound(), offset_[1]+J.lbound(),
  133.                 offset_[1] + J.ubound());
  134.         }
  135.         inline T & operator()(Subscript i, Subscript j)
  136.         {
  137. #ifdef TNT_BOUNDS_CHECK
  138.             assert( A_.lbound() <= i);
  139.             assert( i<= dim_[0] + A_.lbound()-1);
  140.             assert( A_.lbound() <= j);
  141.             assert( j<= dim_[1] + A_.lbound()-1 );
  142. #endif
  143.             return A_(i+offset_[0], j+offset_[1]);
  144.         }
  145.         inline const T & operator() (Subscript i, Subscript j) const
  146.         {
  147. #ifdef TNT_BOUNDS_CHECK
  148.             assert( A_.lbound() <= i);
  149.             assert( i<= dim_[0] + A_.lbound()-1);
  150.             assert( A_.lbound() <= j);
  151.             assert( j<= dim_[1] + A_.lbound()-1 );
  152. #endif
  153.             return A_(i+offset_[0], j+offset_[1]);
  154.         }
  155.         Region2D<Array2D> & operator=(const Region2D<Array2D> &R)
  156.         {
  157.             Subscript M = num_rows(); 
  158.             Subscript N = num_cols();
  159.             // make sure both sides conform
  160.             assert(M == R.num_rows());
  161.             assert(N == R.num_cols());
  162.             Subscript start = R.lbound();
  163.             Subscript Mend =  start + M - 1;
  164.             Subscript Nend =  start + N - 1;
  165.             for (Subscript i=start; i<=Mend; i++)
  166.               for (Subscript j=start; j<=Nend; j++)
  167.                 (*this)(i,j) = R(i,j);
  168.             return *this;
  169.         }
  170.         Region2D<Array2D> & operator=(const const_Region2D<Array2D,T> &R)
  171.         {
  172.             Subscript M = num_rows(); 
  173.             Subscript N = num_cols();
  174.             // make sure both sides conform
  175.             assert(M == R.num_rows());
  176.             assert(N == R.num_cols());
  177.             Subscript start = R.lbound();
  178.             Subscript Mend =  start + M - 1;
  179.             Subscript Nend =  start + N - 1;
  180.             for (Subscript i=start; i<=Mend; i++)
  181.               for (Subscript j=start; j<=Nend; j++)
  182.                 (*this)(i,j) = R(i,j);
  183.             return *this;
  184.         }
  185.         Region2D<Array2D> & operator=(const Array2D &R)
  186.         {
  187.             Subscript M = num_rows(); 
  188.             Subscript N = num_cols();
  189.             // make sure both sides conform
  190.             assert(M == R.num_rows());
  191.             assert(N == R.num_cols());
  192.             Subscript start = R.lbound();
  193.             Subscript Mend =  start + M - 1;
  194.             Subscript Nend =  start + N - 1;
  195.             for (Subscript i=start; i<=Mend; i++)
  196.               for (Subscript j=start; j<=Nend; j++)
  197.                 (*this)(i,j) = R(i,j);
  198.             return *this;
  199.         }
  200.         Region2D<Array2D> & operator=(const  T &scalar)
  201.         {
  202.             Subscript start = lbound();
  203.             Subscript Mend = lbound() + num_rows() - 1;
  204.             Subscript Nend = lbound() + num_cols() - 1;
  205.             for (Subscript i=start; i<=Mend; i++)
  206.               for (Subscript j=start; j<=Nend; j++)
  207.                 (*this)(i,j) = scalar;
  208.             return *this;
  209.         }
  210. };
  211. //************************
  212. template <class Array2D, class T>
  213. class const_Region2D
  214. {
  215.     protected:
  216.         const Array2D &  A_;
  217.         Subscript offset_[2];       // 0-offset internally
  218.         Subscript dim_[2];
  219.     public:
  220.         typedef         T   value_type;
  221.         typedef         T   element_type;
  222.         typedef const   T*  const_iterator;
  223.         typedef const   T&  const_reference;
  224.         const Array2D & array() const { return A_; }
  225.         Subscript lbound() const { return A_.lbound(); }
  226.         Subscript num_rows() const { return dim_[0]; }
  227.         Subscript num_cols() const { return dim_[1]; }
  228.         Subscript offset(Subscript i) const                 // 1-offset
  229.         {
  230. #ifdef TNT_BOUNDS_CHECK
  231.             assert( TNT_BASE_OFFSET <= i);
  232.             assert( i<= dim_[0] + TNT_BASE_OFFSET-1);
  233. #endif
  234.             return offset_[i-TNT_BASE_OFFSET];
  235.         }
  236.         Subscript dim(Subscript i) const
  237.         {
  238. #ifdef TNT_BOUNDS_CHECK
  239.             assert( TNT_BASE_OFFSET <= i);
  240.             assert( i<= dim_[0] + TNT_BASE_OFFSET-1);
  241. #endif
  242.             return dim_[i-TNT_BASE_OFFSET];
  243.         }
  244.         const_Region2D(const Array2D &A, Subscript i1, Subscript i2, 
  245.                 Subscript j1, Subscript j2) : A_(A)
  246.         {
  247. #ifdef TNT_BOUNDS_CHECK
  248.             assert( i1 <= i2 );
  249.             assert( j1 <= j2);
  250.             assert( TNT_BASE_OFFSET <= i1);
  251.             assert( i2<= A.dim(TNT_BASE_OFFSET) + TNT_BASE_OFFSET-1);
  252.             assert( TNT_BASE_OFFSET <= j1);
  253.             assert( j2<= A.dim(TNT_BASE_OFFSET+1) + TNT_BASE_OFFSET-1 );
  254. #endif
  255.             offset_[0] = i1-TNT_BASE_OFFSET;
  256.             offset_[1] = j1-TNT_BASE_OFFSET;
  257.             dim_[0] = i2-i1+1;
  258.             dim_[1] = j2-j1+1;
  259.         }
  260.         const_Region2D(const Array2D &A, const Index1D &I, const Index1D &J) 
  261.                 : A_(A)
  262.         {
  263. #ifdef TNT_BOUNDS_CHECK
  264.             assert( I.lbound() <= I.ubound() );
  265.             assert( J.lbound() <= J.ubound() );
  266.             assert( TNT_BASE_OFFSET <= I.lbound());
  267.             assert( I.ubound()<= A.dim(TNT_BASE_OFFSET) + TNT_BASE_OFFSET-1);
  268.             assert( TNT_BASE_OFFSET <= J.lbound());
  269.             assert( J.ubound() <= A.dim(TNT_BASE_OFFSET+1) + TNT_BASE_OFFSET-1 );
  270. #endif
  271.             offset_[0] = I.lbound()-TNT_BASE_OFFSET;
  272.             offset_[1] = J.lbound()-TNT_BASE_OFFSET;
  273.             dim_[0] = I.ubound() - I.lbound() + 1;
  274.             dim_[1] = J.ubound() - J.lbound() + 1;
  275.         }
  276.         const_Region2D(const_Region2D<Array2D,T> &A, Subscript i1, 
  277.                 Subscript i2,
  278.             Subscript j1, Subscript j2) : A_(A.A_)
  279.         {
  280. #ifdef TNT_BOUNDS_CHECK
  281.             assert( i1 <= i2 );
  282.             assert( j1 <= j2);
  283.             assert( TNT_BASE_OFFSET <= i1);
  284.             assert( i2<= A.dim(TNT_BASE_OFFSET) + TNT_BASE_OFFSET-1);
  285.             assert( TNT_BASE_OFFSET <= j1);
  286.             assert( j2<= A.dim(TNT_BASE_OFFSET+1) + TNT_BASE_OFFSET-1 );
  287. #endif
  288.             offset_[0] = (i1 - TNT_BASE_OFFSET) + A.offset_[0];
  289.             offset_[1] = (j1 - TNT_BASE_OFFSET) + A.offset_[1];
  290.             dim_[0] = i2-i1 + 1;
  291.             dim_[1] = j2-j1+1;
  292.         }
  293.         const_Region2D<Array2D,T> operator()(Subscript i1, Subscript i2,
  294.                 Subscript j1, Subscript j2)
  295.         {
  296. #ifdef TNT_BOUNDS_CHECK
  297.             assert( i1 <= i2 );
  298.             assert( j1 <= j2);
  299.             assert( TNT_BASE_OFFSET <= i1);
  300.             assert( i2<= dim_[0] + TNT_BASE_OFFSET-1);
  301.             assert( TNT_BASE_OFFSET <= j1);
  302.             assert( j2<= dim_[0] + TNT_BASE_OFFSET-1 );
  303. #endif
  304.             return const_Region2D<Array2D,T>(A_, 
  305.                     i1+offset_[0], offset_[0] + i2, 
  306.                     j1+offset_[1], offset_[1] + j2);
  307.         }
  308.         const_Region2D<Array2D,T> operator()(const Index1D &I,
  309.                 const Index1D &J)
  310.         {
  311. #ifdef TNT_BOUNDS_CHECK
  312.             assert( I.lbound() <= I.ubound() );
  313.             assert( J.lbound() <= J.ubound() );
  314.             assert( TNT_BASE_OFFSET <= I.lbound());
  315.             assert( I.ubound()<= dim_[0] + TNT_BASE_OFFSET-1);
  316.             assert( TNT_BASE_OFFSET <= J.lbound());
  317.             assert( J.ubound() <= dim_[1] + TNT_BASE_OFFSET-1 );
  318. #endif
  319.             return const_Region2D<Array2D,T>(A_, I.lbound()+offset_[0],
  320.                 offset_[0] + I.ubound(), offset_[1]+J.lbound(),
  321.                 offset_[1] + J.ubound());
  322.         }
  323.         inline const T & operator() (Subscript i, Subscript j) const
  324.         {
  325. #ifdef TNT_BOUNDS_CHECK
  326.             assert( TNT_BASE_OFFSET <= i);
  327.             assert( i<= dim_[0] + TNT_BASE_OFFSET-1);
  328.             assert( TNT_BASE_OFFSET <= j);
  329.             assert( j<= dim_[1] + TNT_BASE_OFFSET-1 );
  330. #endif
  331.             return A_(i+offset_[0], j+offset_[1]);
  332.         }
  333. };
  334. //  ************** ostream algorithms *******************************
  335. template <class Array2D,class T>
  336. ostream& operator<<(ostream &s, const const_Region2D<Array2D,T> &A)
  337. {
  338.     Subscript start = A.lbound();
  339.     Subscript Mend=A.lbound()+ A.num_rows() - 1;
  340.     Subscript Nend=A.lbound() + A.num_cols() - 1;
  341.     s << A.num_rows() << "  " << A.num_cols() << endl;
  342.     for (Subscript i=start; i<=Mend; i++)
  343.     {
  344.         for (Subscript j=start; j<=Nend; j++)
  345.         {
  346.             s << A(i,j) << " ";
  347.         }
  348.         s << endl;
  349.     }
  350.     return s;
  351. }
  352. template <class Array2D>
  353. ostream& operator<<(ostream &s, const Region2D<Array2D> &A)
  354. {
  355.     Subscript start = A.lbound();
  356.     Subscript Mend=A.lbound()+ A.num_rows() - 1;
  357.     Subscript Nend=A.lbound() + A.num_cols() - 1;
  358.     s << A.num_rows() << "  " << A.num_cols() << endl;
  359.     for (Subscript i=start; i<=Mend; i++)
  360.     {
  361.         for (Subscript j=start; j<=Nend; j++)
  362.         {
  363.             s << A(i,j) << " ";
  364.         }
  365.         s << endl;
  366.     }
  367.     return s;
  368. }
  369. #endif
  370. // REGION2D_H