RotatedBox.h

00001 //===========================================================================
00002 // GoTools - SINTEF Geometry Tools version 1.1
00003 //
00004 // GoTools module: CORE
00005 //
00006 // Copyright (C) 2000-2007 SINTEF ICT, Applied Mathematics, Norway.
00007 //
00008 // This program is free software; you can redistribute it and/or          
00009 // modify it under the terms of the GNU General Public License            
00010 // as published by the Free Software Foundation version 2 of the License. 
00011 //
00012 // This program is distributed in the hope that it will be useful,        
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of         
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          
00015 // GNU General Public License for more details.                           
00016 //
00017 // You should have received a copy of the GNU General Public License      
00018 // along with this program; if not, write to the Free Software            
00019 // Foundation, Inc.,                                                      
00020 // 59 Temple Place - Suite 330,                                           
00021 // Boston, MA  02111-1307, USA.                                           
00022 //
00023 // Contact information: E-mail: tor.dokken@sintef.no                      
00024 // SINTEF ICT, Department of Applied Mathematics,                         
00025 // P.O. Box 124 Blindern,                                                 
00026 // 0314 Oslo, Norway.                                                     
00027 //
00028 // Other licenses are also available for this software, notably licenses
00029 // for:
00030 // - Building commercial software.                                        
00031 // - Building software whose source code you wish to keep private.        
00032 //===========================================================================
00033 #ifndef _ROTATEDBOX_H
00034 #define _ROTATEDBOX_H
00035 
00036 #include "CompositeBox.h"
00037 #include "MatrixXD.h"
00038 #include <boost/shared_ptr.hpp>
00039 
00040 namespace Go
00041 {
00044 
00045 
00046 
00052 class RotatedBox
00053 {
00054 public:
00059     template <typename RandomAccessIterator>
00060     RotatedBox(RandomAccessIterator start,
00061                int dim,
00062                int num_u,
00063                int num_v,
00064                const Point* axis)
00065     {
00066         // Make coordinate system.
00067         setCs(axis, dim);
00068         // Make box.
00069         setFromArray(start, dim, num_u, num_v);
00070     }
00071 
00075     RotatedBox(const Point& low, const Point& high,
00076                const Point* axis)
00077     {
00078         // Make coordinate system.
00079         setCs(axis, low.size());
00080         // Make box.
00081         setFromPoints(low, high);
00082     }
00083 
00085     ~RotatedBox()
00086     {
00087     }
00088 
00095     template <typename RandomAccessIterator>
00096     void setFromArray(RandomAccessIterator start,
00097                       int dim,
00098                       int num_u,
00099                       int num_v)
00100     {
00101         // Make a temporary array of points
00102         std::vector<double> pts(dim*num_u*num_v);
00103         std::copy(start, start + dim*num_u*num_v, &pts[0]);
00104         // Transform the points.
00105         if (dim == 2) {
00106             for (int i = 0; i < num_u*num_v; ++i) {
00107                 Point p(&pts[0] + i*2,
00108                         &pts[0] + (i+1)*2, false);
00109                 p = cs2_*p;
00110                 pts[i*2] = p[0];
00111                 pts[i*2+1] = p[1];
00112             }
00113         } else if (dim == 3) {
00114             for (int i = 0; i < num_u*num_v; ++i) {
00115                 Point p(&pts[0] + i*3,
00116                         &pts[0] + (i+1)*3, false);
00117                 p = cs3_*p;
00118                 pts[i*3] = p[0];
00119                 pts[i*3+1] = p[1];
00120                 pts[i*3+2] = p[2];
00121             }
00122         } else {
00123             THROW("Only supports 2 and 3 dimensions.");
00124         }
00125         // Make the composite box.
00126         box_.reset(new CompositeBox(&pts[0], dim, num_u, num_v));
00127     }
00128 
00131     void setFromPoints(const Point& low, const Point& high)
00132     {
00133         int dim = low.size();
00134         // Transform the points.
00135         if (dim == 2) {
00136             Point p1 = cs2_*low;
00137             Point p2 = cs2_*high;
00138             // Make the composite box.
00139             box_.reset(new CompositeBox(p1, p2));
00140         } else if (dim == 3) {
00141             Point p1 = cs3_*low;
00142             Point p2 = cs3_*high;
00143             // Make the composite box.
00144             box_.reset(new CompositeBox(p1, p2));
00145         } else {
00146             THROW("Only supports 2 and 3 dimensions.");
00147         }
00148     }
00149 
00151     int  dimension()  const
00152     {
00153         return box_->dimension();
00154     }
00155 
00158     const CompositeBox& box() const
00159     {
00160         return *box_;
00161     }
00162 
00166     bool containsPoint(const Point& pt,
00167                        double toli = 0.0,
00168                        double tole = 0.0) const
00169     {
00170         int dim = dimension();
00171         Point rotp;
00172         if (dim == 2) {
00173             rotp = cs2_*pt;
00174         } else if (dim == 3) {
00175             rotp = cs2_*pt;
00176         } else {
00177             THROW("Only supports 2 and 3 dimensions.");
00178         }
00179         return box_->containsPoint(rotp, toli, tole);
00180     }
00181 
00185     bool overlaps(const RotatedBox& box,
00186                   double toli = 0.0,
00187                   double tole = 0.0) const
00188     {
00189         MatrixXD<double, 2> m2 = cs2_;
00190         m2 += -box.cs2_;
00191         if (m2.frobeniusNorm() > 1e-12) {
00192             THROW("The two RotatedBox objects have different coordinate systems.");
00193         }
00194         MatrixXD<double, 3> m3 = cs3_;
00195         m3 += -box.cs3_;
00196         if (m3.frobeniusNorm() > 1e-12) {
00197             THROW("The two RotatedBox objects have different coordinate systems.");
00198         }
00199         return box_->overlaps(box.box(), toli, tole);
00200     }
00201 
00205     bool containsBox(const RotatedBox& box,
00206                      double toli = 0.0,
00207                      double tole = 0.0) const
00208     {
00209         MatrixXD<double, 2> m2 = cs2_;
00210         m2 += -box.cs2_;
00211         if (m2.frobeniusNorm() > 1e-12) {
00212             THROW("The two RotatedBox objects have different coordinate systems.");
00213         }
00214         MatrixXD<double, 3> m3 = cs3_;
00215         m3 += -box.cs3_;
00216         if (m3.frobeniusNorm() > 1e-12) {
00217             THROW("The two RotatedBox objects have different coordinate systems.");
00218         }
00219         return box_->containsBox(box.box(), toli, tole);
00220     }
00221 
00222 
00223 private:
00224     void setCs(const Point* axis, int dim)
00225     {
00226         // What we actually compute is the inverse coordinate system.
00227         // This way when we multiply a vector with cs we get its
00228         // coordinates in the system given by (axis[0], Rot(Pi/2)*axis[0]).
00229         // Initiate the other array to zero to avoid an exception
00230         if (dim == 2) {
00231             cs2_(0,0) = axis[0][0];
00232             cs2_(0,1) = axis[0][1];
00233             cs2_(1,0) = -axis[0][1];
00234             cs2_(1,1) = axis[0][0];
00235 
00236             cs3_(0,0) = cs3_(0,1) = cs3_(0,2) = 0.0;
00237             cs3_(1,0) = cs3_(1,1) = cs3_(1,2) = 0.0;
00238             cs3_(2,0) = cs3_(2,1) = cs3_(2,2) = 0.0;
00239         } else if (dim == 3) {
00240             Point zaxis = axis[0] % axis[1];
00241             zaxis.normalize();
00242             cs3_(0,0) = axis[0][0];
00243             cs3_(0,1) = axis[0][1];
00244             cs3_(0,2) = axis[0][2];
00245             cs3_(1,0) = axis[1][0];
00246             cs3_(1,1) = axis[1][1];
00247             cs3_(1,2) = axis[1][2];
00248             cs3_(2,0) = zaxis[0];
00249             cs3_(2,1) = zaxis[1];
00250             cs3_(2,2) = zaxis[2];
00251 
00252             cs2_(0,0) = cs2_(0,1) = 0.0;
00253             cs2_(1,0) = cs2_(1,1) = 0.0;
00254         } else {
00255             THROW("Only supports 2 and 3 dimensions.");
00256         }
00257     }
00258 
00259     // Data members
00260     boost::shared_ptr<CompositeBox> box_;
00261     MatrixXD<double, 2> cs2_;
00262     MatrixXD<double, 3> cs3_;
00263 };
00264 
00266 } // namespace Go
00267 
00268 
00269 
00270 #endif // _ROTATEDBOX_H
00271 
00272 

Generated on Mon Jun 11 14:48:18 2007 for GoTools Core Library by  doxygen 1.5.1