00001 // 00002 // ******************************************************************** 00003 // * License and Disclaimer * 00004 // * * 00005 // * The Geant4 software is copyright of the Copyright Holders of * 00006 // * the Geant4 Collaboration. It is provided under the terms and * 00007 // * conditions of the Geant4 Software License, included in the file * 00008 // * LICENSE and available at http://cern.ch/geant4/license . These * 00009 // * include a list of copyright holders. * 00010 // * * 00011 // * Neither the authors of this software system, nor their employing * 00012 // * institutes,nor the agencies providing financial support for this * 00013 // * work make any representation or warranty, express or implied, * 00014 // * regarding this software system or assume any liability for its * 00015 // * use. Please see the license in the file LICENSE and URL above * 00016 // * for the full disclaimer and the limitation of liability. * 00017 // * * 00018 // * This code implementation is the result of the scientific and * 00019 // * technical work of the GEANT4 collaboration. * 00020 // * By using, copying, modifying or distributing the software (or * 00021 // * any work based on the software) you agree to acknowledge its * 00022 // * use in resulting scientific publications, and indicate your * 00023 // * acceptance of all terms of the Geant4 Software license. * 00024 // ******************************************************************** 00025 // 00026 // 00027 // $Id$ 00028 // 00029 // -------------------------------------------------------------------- 00030 // GEANT 4 inline definitions file 00031 // 00032 // G4Hyperbola.icc 00033 // 00034 // Implementation of inline methods of G4Hyperbola 00035 // -------------------------------------------------------------------- 00036 00037 inline 00038 void G4Hyperbola::Init(const G4Axis2Placement3D& position0, 00039 G4double semiAxis0, G4double semiImagAxis0) 00040 { 00041 position= position0; 00042 semiAxis= semiAxis0; 00043 semiImagAxis= semiImagAxis0; 00044 00045 ratioAxisImagAxis= semiAxis/semiImagAxis; 00046 00047 // needed only for 2D hyperbolas 00048 toUnitHyperbola = G4Scale3D(1/semiAxis, 1/semiImagAxis, 0) 00049 * position.GetToPlacementCoordinates(); 00050 00051 forTangent= semiAxis*semiAxis/(semiImagAxis*semiImagAxis); 00052 } 00053 00054 inline 00055 G4double G4Hyperbola::GetSemiAxis() const 00056 { 00057 return semiAxis; 00058 } 00059 00060 inline 00061 G4double G4Hyperbola::GetSemiImagAxis() const 00062 { 00063 return semiImagAxis; 00064 } 00065 00067 00068 inline 00069 G4double G4Hyperbola::GetPMax() const 00070 { 00071 return -1; 00072 } 00073 00074 inline 00075 G4Point3D G4Hyperbola::GetPoint(G4double param) const 00076 { 00077 return G4Point3D( position.GetLocation() 00078 + semiAxis*std::cosh(param)*position.GetPX() 00079 + semiImagAxis*std::sinh(param)*position.GetPY() ); 00080 } 00081 00082 inline 00083 G4double G4Hyperbola::GetPPoint(const G4Point3D& pt) const 00084 { 00085 G4Point3D ptLocal= position.GetToPlacementCoordinates()*pt; 00086 G4double xval= ptLocal.y()/ptLocal.x()*ratioAxisImagAxis; 00087 return 0.5*std::log((1+xval)/(1-xval)); // atanh(xval) 00088 } 00089 00091 00092 /* 00093 #include "G4CurveRayIntersection.hh" 00094 00095 inline 00096 void G4Hyperbola::IntersectRay2D(const G4Ray& ray, 00097 G4CurveRayIntersection& is) 00098 { 00099 is.Init(*this, ray); 00100 00101 // similar to G4Ellipse::IntersectRay2D 00102 00103 // 2D operations would be faster 00104 G4Point3D s= toUnitHyperbola*ray.GetStart(); 00105 G4Vector3D d= toUnitHyperbola*ray.GetDir(); 00106 00107 // solve (s+i*t)^2 = 1 for i (the distance) 00108 00109 G4double sd= s.x()*d.x()-s.y()*d.y(); 00110 G4double dd= d.x()*d.x()-d.y()*d.y(); // can be 0 00111 G4double ss= s.x()*s.x()-s.y()*s.y(); 00112 00113 if (std::abs(dd) < kCarTolerance*kCarTolerance) { 00114 00115 // coeff of i^2 == 0 00116 G4double i= (1-ss)/(2*sd); 00117 G4CurveRayIntersection isTmp(*this, ray); 00118 isTmp.ResetDistance(i); 00119 is.Update(isTmp); 00120 return; 00121 00122 } 00123 00124 G4double discr= sd*sd-dd*(ss-1); 00125 if (discr >= 0) { 00126 00127 // 2 intersections (maybe 1, but this case is rare) 00128 G4double sqrtdiscr= std::sqrt(discr); 00129 // find the smallest positive i 00130 G4double i= -sd-sqrtdiscr; 00131 if (i<kCarTolerance) { 00132 i= -sd+sqrtdiscr; 00133 if (i<kCarTolerance) { 00134 return; 00135 } 00136 } 00137 i/= dd; 00138 G4CurveRayIntersection isTmp(*this, ray); 00139 isTmp.ResetDistance(i); 00140 is.Update(isTmp); 00141 00142 } 00143 } 00144 */ 00145 00146 inline 00147 G4int G4Hyperbola::IntersectRay2D(const G4Ray& ray) 00148 { 00149 // NOT VERIFIED 00150 00151 // similar to G4Ellipse::IntersectRay2D 00152 00153 // 2D operations would be faster 00154 G4Point3D st= toUnitHyperbola*ray.GetStart(); 00155 G4Vector3D d= toUnitHyperbola*ray.GetDir(); 00156 00157 // solve (st+i*t)^2 = 1 for i (the distance) 00158 00159 G4double sd= st.x()*d.x()-st.y()*d.y(); 00160 G4double dd= d.x()*d.x()-d.y()*d.y(); // can be 0 00161 G4double ss= st.x()*st.x()-st.y()*st.y(); 00162 00163 if (std::abs(dd) < kCarTolerance*kCarTolerance) { 00164 00165 // coeff of i^2 == 0 00166 return 0; 00167 00168 } 00169 00170 G4int nbinter = 0; 00171 00172 G4double discr= sd*sd-dd*(ss-1); 00173 if (discr >= 0) 00174 { 00175 // 2 intersections (maybe 1, but this case is rare) 00176 G4double sqrtdiscr= std::sqrt(discr); 00177 // find the smallest positive i 00178 G4double i= -sd-sqrtdiscr; 00179 if (i > kCarTolerance) 00180 nbinter++; 00181 00182 i= -sd+sqrtdiscr; 00183 if (i<kCarTolerance) 00184 nbinter++; 00185 } 00186 00187 return nbinter; 00188 }