fcc_lattice.h
Go to the documentation of this file.
00001 // Copyright (c) 2009-2010  INRIA Sophia-Antipolis (France).
00002 // All rights reserved.
00003 //
00004 //This file is part of ESBTL.
00005 //
00006 //ESBTL is free software: you can redistribute it and/or modify
00007 //it under the terms of the GNU General Public License as published by
00008 //the Free Software Foundation, either version 3 of the License, or
00009 //(at your option) any later version.
00010 //
00011 //ESBTL is distributed in the hope that it will be useful,
00012 //but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //GNU General Public License for more details.
00015 //
00016 //You should have received a copy of the GNU General Public License
00017 //along with ESBTL.  If not, see <http://www.gnu.org/licenses/>.
00018 //
00019 //
00020 //Additional permission under GNU GPL version 3 section 7
00021 //
00022 //If you modify this Library, or any covered work, by linking or
00023 //combining it with CGAL (or a modified version of that library), the
00024 //licensors of this Library grant you additional permission to convey
00025 //the resulting work. Corresponding Source for a non-source form of
00026 //such a combination shall include the source code for the parts of CGAL
00027 //used as well as that of the covered work. 
00028 //
00029 //
00030 //
00031 // Author(s)     :  Sébastien Loriot
00032 
00033 
00034 
00035 #include <cmath>
00036 
00037 #ifndef ESBTL_FCC_LATTICE_H
00038 #define ESBTL_FCC_LATTICE_H
00039 
00040 namespace ESBTL {
00042   namespace internal_fcc_lattice{
00043     template <class Point_3,class FT,class Output_iterator>
00044     void even_layer(const FT& center_x,const FT& center_y,const FT& layer_z,const FT& unit_move,unsigned size,Output_iterator out){
00045       const FT x_s=center_x - (size-1)*unit_move;
00046       const FT y_s=center_y - (size-1)*unit_move;
00047       
00048       for (unsigned i=0;i<size;++i)
00049         for (unsigned j=0;j<size;++j)
00050           *out++=Point_3(x_s+2*i*unit_move,y_s+2*j*unit_move,layer_z);
00051 
00052       for (unsigned i=0;i<size-1;++i)
00053         for (unsigned j=0;j<size-1;++j)
00054           *out++=Point_3(x_s+unit_move+2*i*unit_move,y_s+unit_move+2*j*unit_move,layer_z);
00055     }
00056 
00057 
00058     template <class Point_3,class FT,class Output_iterator>
00059     void odd_layer(const FT& center_x,const FT& center_y,const FT& layer_z,const FT& unit_move,unsigned size,Output_iterator out){
00060       const FT x_s=center_x - (size-1)*unit_move;
00061       const FT y_s=center_y - (size-1)*unit_move;
00062       
00063       for (unsigned i=0;i<size;++i)
00064         for (unsigned j=0;j<size-1;++j)
00065           *out++=Point_3(x_s+2*i*unit_move,y_s+unit_move+2*j*unit_move,layer_z);
00066 
00067       for (unsigned i=0;i<size-1;++i)
00068         for (unsigned j=0;j<size;++j)
00069           *out++=Point_3(x_s+unit_move+2*i*unit_move,y_s+2*j*unit_move,layer_z);
00070     }
00071 
00072   } //namespace internal_fcc_lattice
00084   template<class Point_3,class Output_iterator>
00085   void fcc_lattice(const Point_3& center, double radius, double min_edge_length,Output_iterator out){
00086     double unit_move=sqrt(2*radius);
00087     unsigned size = static_cast<unsigned>( ceil( min_edge_length/2./unit_move ) )+1;
00088 
00089     double z_s=center.z() - (size-1)*unit_move;
00090     for (unsigned i=0;i<size;++i)
00091       internal_fcc_lattice::even_layer<Point_3>(center.x(),center.y(),z_s+2*i*unit_move,unit_move,size,out);
00092     for (unsigned i=0;i<size-1;++i)
00093       internal_fcc_lattice::odd_layer<Point_3>(center.x(),center.y(),z_s+2*i*unit_move+unit_move,unit_move,size,out);    
00094   }
00095   
00105   template<class Point_3,class Output_iterator>
00106   inline
00107   void fcc_lattice(const std::pair<Point_3,double>& cube, double radius, double expand_value,Output_iterator out){
00108     double edge=cube.second;
00109     Point_3 center(cube.first.x()+edge/2.,cube.first.y()+edge/2.,cube.first.z()+edge/2.);
00110     return fcc_lattice(center,radius,edge+expand_value,out);
00111   }
00112     
00113 
00114 } //namespace ESBTL
00115 
00116 #endif //ESBTL_FCC_LATTICE_H