|
SISCone
2.0.5
|
00001 00002 // File: geom_2d.cpp // 00003 // Description: source file for two-dimensional geometry tools // 00004 // This file is part of the SISCone project. // 00005 // WARNING: this is not the main SISCone trunk but // 00006 // an adaptation to spherical coordinates // 00007 // For more details, see http://projects.hepforge.org/siscone // 00008 // // 00009 // Copyright (c) 2006-2008 Gavin Salam and Gregory Soyez // 00010 // // 00011 // This program is free software; you can redistribute it and/or modify // 00012 // it under the terms of the GNU General Public License as published by // 00013 // the Free Software Foundation; either version 2 of the License, or // 00014 // (at your option) any later version. // 00015 // // 00016 // This program is distributed in the hope that it will be useful, // 00017 // but WITHOUT ANY WARRANTY; without even the implied warranty of // 00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // 00019 // GNU General Public License for more details. // 00020 // // 00021 // You should have received a copy of the GNU General Public License // 00022 // along with this program; if not, write to the Free Software // 00023 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA // 00024 // // 00025 // $Revision:: 255 $// 00026 // $Date:: 2008-07-12 17:40:35 +0200 (Sat, 12 Jul 2008) $// 00028 00029 #include "geom_2d.h" 00030 #include <algorithm> 00031 00032 namespace siscone_spherical{ 00033 00034 #define PHI_RANGE_MASK 0xFFFFFFFF 00035 00036 /********************************************************* 00037 * class CSphtheta_phi_range implementation * 00038 * class for holding a covering range in eta-phi * 00039 * * 00040 * This class deals with ranges in the eta-phi plane. It * 00041 * implements methods to test if two ranges overlap and * 00042 * to take the union of two overlapping intervals. * 00043 *********************************************************/ 00044 00045 using namespace std; 00046 00047 // static member default init 00048 //---------------------------- 00049 double CSphtheta_phi_range::theta_min = 0.0; 00050 double CSphtheta_phi_range::theta_max = M_PI; 00051 00052 // default ctor 00053 //-------------- 00054 CSphtheta_phi_range::CSphtheta_phi_range(){ 00055 theta_range = 0; 00056 phi_range = 0; 00057 } 00058 00059 // ctor with initialisation 00060 // we initialise with a centre (in eta,phi) and a radius 00061 // - c_theta theta coordinate of the centre 00062 // - c_phi phi coordinate of the centre 00063 // - R radius 00064 //------------------------------------------------------- 00065 CSphtheta_phi_range::CSphtheta_phi_range(double c_theta, double c_phi, double R){ 00066 // determination of the eta range 00067 //------------------------------- 00068 double xmin = max(c_theta-R,theta_min+0.00001); 00069 double xmax = min(c_theta+R,theta_max-0.00001); 00070 00071 unsigned int cell_min = get_theta_cell(xmin); 00072 unsigned int cell_max = get_theta_cell(xmax); 00073 00074 // warning: if cell_max==2^31, 2*cell_max==0 hence, 00075 // even if the next formula is formally (2*cell_max-cell_min), 00076 // expressing it as (cell_max-cell_min)+cell_max is safe. 00077 theta_range = (cell_max-cell_min)+cell_max; 00078 00079 // determination of the phi range 00080 // !! taking care of periodicity !! 00081 // !! and the theta dependence !! 00082 //--------------------------------- 00083 double ymin,ymax; 00084 double extra = asin(R/M_PI); 00085 if (xmin<=theta_min+extra){ 00086 ymin = -M_PI+0.00001; 00087 ymax = M_PI-0.00001; 00088 } else if (xmax>=theta_max-extra){ 00089 ymin = -M_PI+0.00001; 00090 ymax = M_PI-0.00001; 00091 } else { 00092 extra = max(1.0/sin(xmin), 1.0/sin(xmax)); 00093 ymin = (c_phi-R)*extra; 00094 while (ymin<-M_PI) ymin+=twopi; 00095 while (ymin> M_PI) ymin-=twopi; 00096 ymax = (c_phi-R)*extra; 00097 while (ymax<-M_PI) ymax+=twopi; 00098 while (ymax> M_PI) ymax-=twopi; 00099 } 00100 cell_min = get_phi_cell(ymin); 00101 cell_max = get_phi_cell(ymax); 00102 00103 // Also, if the interval goes through pi, inversion is needed 00104 if (ymax>ymin) 00105 phi_range = (cell_max-cell_min)+cell_max; 00106 else { 00107 phi_range = (cell_min==cell_max) 00108 ? PHI_RANGE_MASK 00109 : ((PHI_RANGE_MASK^(cell_min-cell_max)) + cell_max); 00110 } 00111 } 00112 00113 // assignment of range 00114 // - r range to assign to current one 00115 //--------------------------------------- 00116 CSphtheta_phi_range& CSphtheta_phi_range::operator = (const CSphtheta_phi_range &r){ 00117 theta_range = r.theta_range; 00118 phi_range = r.phi_range; 00119 00120 return *this; 00121 } 00122 00123 // add a particle to the range 00124 // - eta eta coordinate of the particle 00125 // - phi phi coordinate of the particle 00126 // \return 0 on success, 1 on error 00127 //---------------------------------------- 00128 int CSphtheta_phi_range::add_particle(const double theta, const double phi){ 00129 // deal with the eta coordinate 00130 theta_range |= get_theta_cell(theta); 00131 00132 // deal with the phi coordinate 00133 phi_range |= get_phi_cell(phi); 00134 00135 return 0; 00136 } 00137 00138 00139 // test overlap 00140 // - r1 first range 00141 // - r2 second range 00142 // return true if overlap, false otherwise. 00143 //------------------------------------------ 00144 bool is_range_overlap(const CSphtheta_phi_range &r1, const CSphtheta_phi_range &r2){ 00145 // check overlap in eta AND phi 00146 return ((r1.theta_range & r2.theta_range) && (r1.phi_range & r2.phi_range)); 00147 } 00148 00149 // compute union 00150 // Note: we assume that the two intervals overlap 00151 // - r1 first range 00152 // - r2 second range 00153 // \return union of the two ranges 00154 //------------------------------------------ 00155 const CSphtheta_phi_range range_union (const CSphtheta_phi_range &r1, const CSphtheta_phi_range &r2){ 00156 CSphtheta_phi_range tmp; 00157 00158 // compute union in eta 00159 tmp.theta_range = r1.theta_range | r2.theta_range; 00160 00161 // compute union in phi 00162 tmp.phi_range = r1.phi_range | r2.phi_range; 00163 00164 return tmp; 00165 } 00166 00167 }