00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #ifndef DETDESC_SOLIDMATH_H
00049 #define DETDESC_SOLIDMATH_H 1
00050
00051 #include "DetDesc/ISolid.h"
00052 #include "DetDesc/SolidTicks.h"
00053
00061 namespace SolidTicks
00062 {
00063
00072 template < class OUTPUTTYPE >
00073 inline unsigned int
00074 SolveQuadraticEquation
00075 ( const double a ,
00076 const double b ,
00077 const double c ,
00078 OUTPUTTYPE out )
00079 {
00080 if( 0 == a )
00081 {
00082
00083 if( b == 0 ) { return 0 ; }
00084
00085 *out++ = -1.0 * c / b ;
00086 *out++ = -1.0 * c / b ;
00087 return 1;
00088 }
00089 double d = b * b - 4.0 * a * c ;
00090
00091 if( d < 0 ) { return 0; }
00092
00093 d = sqrt( d ) ;
00094 *out++ = 0.5 * ( -b - d ) / a ;
00095 *out++ = 0.5 * ( -b + d ) / a ;
00096
00097 return 0 == d ? 1 : 2 ;
00098 };
00099
00110 template < class OUTPUTTYPE, class aPoint, class aVector >
00111 inline unsigned int
00112 LineIntersectsTheSphere
00113 ( const aPoint & point ,
00114 const aVector & vect ,
00115 const double radius ,
00116 OUTPUTTYPE out )
00117 {
00118
00119 if( radius <= 0 ) { return 0 ; }
00120
00121 double v2 = vect.mag2();
00122 if( v2 <= 0 ) { return 0 ; }
00123 double p2 = point.mag2() ;
00124 double pv = point.Dot(vect) ;
00129 const double a = v2 ;
00130 const double b = 2.0*pv ;
00131 const double c = p2 - radius * radius ;
00132
00133 return SolidTicks::SolveQuadraticEquation( a , b , c , out );
00134 };
00135
00146 template < class OUTPUTTYPE, class aPoint, class aVector >
00147 inline unsigned int
00148 LineIntersectsTheSphere2
00149 ( const aPoint & point ,
00150 const aVector & vect ,
00151 const double r2 ,
00152 OUTPUTTYPE out )
00153 {
00154
00155 if( r2 <= 0 ) { return 0 ; }
00156
00157 double v2 = vect.mag2();
00158 if( v2 <= 0 ) { return 0 ; }
00159 double p2 = point.mag2() ;
00160 double pv = point.Dot(vect) ;
00165 const double a = v2 ;
00166 const double b = 2.0*pv ;
00167 const double c = p2 - r2 ;
00168
00169 return SolidTicks::SolveQuadraticEquation( a , b , c , out );
00170 };
00171
00182 template < class OUTPUTTYPE, class aPoint, class aVector >
00183 inline unsigned int
00184 LineIntersectsTheCylinder
00185 ( const aPoint & point ,
00186 const aVector & vect ,
00187 const double radius ,
00188 OUTPUTTYPE out )
00189
00190 {
00191
00192 if( radius <= 0 ) { return 0 ; }
00193
00194 const double v2 = vect.x()*vect.x() + vect.y()*vect.y() ;
00195 if( v2 <= 0 ) { return 0 ; }
00196
00197 const double p2 = point.x() * point.x() + point.y() * point.y() ;
00198 const double pv = point.x() * vect.x() + point.y() * vect.y() ;
00203 const double a = v2 ;
00204 const double b = 2.0*pv ;
00205 const double c = p2 - radius * radius ;
00206
00207 return SolidTicks::SolveQuadraticEquation( a , b , c , out );
00208 };
00209
00220 template < class OUTPUTTYPE, class aPoint, class aVector >
00221 inline unsigned int
00222 LineIntersectsTheX
00223 ( const aPoint & point ,
00224 const aVector & vect ,
00225 const double X ,
00226 OUTPUTTYPE out )
00227
00228 {
00232 if( 0 == vect.x() ) { return 0; }
00233 *out++ = ( X - point.x() ) / vect.x() ;
00234 return 1;
00235 };
00236
00247 template < class OUTPUTTYPE, class aPoint, class aVector >
00248 inline unsigned int
00249 LineIntersectsTheY
00250 ( const aPoint & point ,
00251 const aVector & vect ,
00252 const double Y ,
00253 OUTPUTTYPE out )
00254
00255 {
00259 if( 0 == vect.y() ) { return 0; }
00260 *out++ = ( Y - point.y() ) / vect.y() ;
00261 return 1;
00262 };
00263
00274 template < class OUTPUTTYPE, class aPoint, class aVector >
00275 inline unsigned int
00276 LineIntersectsTheZ
00277 ( const aPoint & point ,
00278 const aVector& vect ,
00279 const double Z ,
00280 OUTPUTTYPE out )
00281
00282 {
00286 if( 0 == vect.z() ) { return 0; }
00287 *out++ = ( Z - point.z() ) / vect.z() ;
00288 return 1;
00289 };
00290
00301 template < class OUTPUTTYPE, class aPoint, class aVector >
00302 inline unsigned int
00303 LineIntersectsThePhi
00304 ( const aPoint & point ,
00305 const aVector & vect ,
00306 const double Phi ,
00307 OUTPUTTYPE out )
00308
00309 {
00310 const double sinphi = sin( Phi ) ;
00311 const double cosphi = cos( Phi ) ;
00312 const double d = vect.x() * sinphi - vect.y() * cosphi ;
00313 if( 0 == d ) { return 0; }
00314
00315 const double e = vect.y() * point.x() - vect.x() * point.y() ;
00316 if( e * d > 0 ) { return 0 ; }
00317 *out++ = ( point.y() * cosphi - point.x() * sinphi ) / d ;
00318 return 1;
00319 };
00320
00331 template < class OUTPUTTYPE, class aPoint, class aVector >
00332 inline unsigned int
00333 LineIntersectsTheTheta
00334 ( const aPoint & point ,
00335 const aVector & vect ,
00336 const double Theta ,
00337 OUTPUTTYPE out )
00338
00339 {
00343 const double sinthe = sin( Theta ) ;
00344 const double costhe = cos( Theta ) ;
00345
00346 const double c2 = costhe * costhe ;
00347 const double s2 = sinthe * sinthe ;
00348
00349 const double a =
00350 c2 * vect.x() * vect.x() +
00351 c2 * vect.y() * vect.y() -
00352 s2 * vect.z() * vect.z() ;
00353 double b =
00354 c2 * vect.x() * point.x() +
00355 c2 * vect.y() * point.y() -
00356 s2 * vect.z() * point.z() ;
00357 const double c =
00358 c2 * point.x() * point.x() +
00359 c2 * point.y() * point.y() -
00360 s2 * point.z() * point.z() ;
00361
00362 b *= 2.0;
00363
00364
00365 return SolidTicks::SolveQuadraticEquation( a , b, c, out );
00366 };
00367
00368
00384 template < class OUTPUTTYPE, class aPoint, class aVector >
00385 inline unsigned int
00386 LineIntersectsTheCone
00387 ( const aPoint & point ,
00388 const aVector & vect ,
00389 const double r1 ,
00390 const double r2 ,
00391 const double z1 ,
00392 const double z2 ,
00393 OUTPUTTYPE out )
00394
00395 {
00405 const double drdz = (r2-r1)/(z2-z1) ;
00406 const double p1 = r1 - z1*drdz + drdz*point.z() ;
00407 const double p2 = drdz * vect.z() ;
00408
00409 double a = vect.x () * vect.x () + vect.y () * vect.y () ;
00410 a -= p2*p2 ;
00411 double b = vect.x () * point.x() + vect.y () * point.y() ;
00412 b -= p2*p1 ;
00413 b *= 2.0 ;
00414 double c = point.x() * point.x() + point.y() * point.y() ;
00415 c -= p1*p1 ;
00416
00417
00418 return SolidTicks::SolveQuadraticEquation( a , b, c, out );
00419 };
00420
00421 };
00422
00423
00424
00425
00426 #endif // DETDESC_SOLIDMATH_H
00427