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
00049
00050
00051
00052
00053
00054 #ifndef __G4TWISTEDTUBS__
00055 #define __G4TWISTEDTUBS__
00056
00057 #include "G4VSolid.hh"
00058 #include "G4TwistTubsFlatSide.hh"
00059 #include "G4TwistTubsSide.hh"
00060 #include "G4TwistTubsHypeSide.hh"
00061
00062 class G4SolidExtentList;
00063 class G4ClippablePolygon;
00064
00065 class G4TwistedTubs : public G4VSolid
00066 {
00067 public:
00068
00069 G4TwistedTubs(const G4String &pname,
00070 G4double twistedangle,
00071 G4double endinnerrad,
00072 G4double endouterrad,
00073 G4double halfzlen,
00074 G4double dphi);
00075
00076 G4TwistedTubs(const G4String &pname,
00077 G4double twistedangle,
00078 G4double endinnerrad,
00079 G4double endouterrad,
00080 G4double halfzlen,
00081 G4int nseg,
00082 G4double totphi);
00083
00084 G4TwistedTubs(const G4String &pname,
00085 G4double twistedangle,
00086 G4double innerrad,
00087 G4double outerrad,
00088 G4double negativeEndz,
00089 G4double positiveEndz,
00090 G4double dphi);
00091
00092 G4TwistedTubs(const G4String &pname,
00093 G4double twistedangle,
00094 G4double innerrad,
00095 G4double outerrad,
00096 G4double negativeEndz,
00097 G4double positiveEndz,
00098 G4int nseg,
00099 G4double totphi);
00100
00101 virtual ~G4TwistedTubs();
00102
00103 void ComputeDimensions(G4VPVParameterisation * ,
00104 const G4int ,
00105 const G4VPhysicalVolume * );
00106
00107 G4bool CalculateExtent(const EAxis paxis,
00108 const G4VoxelLimits &pvoxellimit,
00109 const G4AffineTransform &ptransform,
00110 G4double &pmin,
00111 G4double &pmax ) const;
00112
00113 G4double DistanceToIn (const G4ThreeVector &p,
00114 const G4ThreeVector &v ) const;
00115
00116 G4double DistanceToIn (const G4ThreeVector &p ) const;
00117
00118 G4double DistanceToOut(const G4ThreeVector &p,
00119 const G4ThreeVector &v,
00120 const G4bool calcnorm=G4bool(false),
00121 G4bool *validnorm=0,
00122 G4ThreeVector *n=0 ) const;
00123
00124 G4double DistanceToOut(const G4ThreeVector &p) const;
00125
00126 EInside Inside (const G4ThreeVector &p) const;
00127
00128 G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const;
00129
00130 void DescribeYourselfTo (G4VGraphicsScene &scene) const;
00131 G4Polyhedron *CreatePolyhedron () const;
00132 G4NURBS *CreateNURBS () const;
00133 G4Polyhedron *GetPolyhedron () const;
00134
00135 std::ostream &StreamInfo(std::ostream& os) const;
00136
00137
00138
00139 inline G4double GetDPhi () const { return fDPhi ; }
00140 inline G4double GetPhiTwist () const { return fPhiTwist ; }
00141 inline G4double GetInnerRadius () const { return fInnerRadius; }
00142 inline G4double GetOuterRadius () const { return fOuterRadius; }
00143 inline G4double GetInnerStereo () const { return fInnerStereo; }
00144 inline G4double GetOuterStereo () const { return fOuterStereo; }
00145 inline G4double GetZHalfLength () const { return fZHalfLength; }
00146 inline G4double GetKappa () const { return fKappa ; }
00147
00148 inline G4double GetTanInnerStereo () const { return fTanInnerStereo ; }
00149 inline G4double GetTanInnerStereo2() const { return fTanInnerStereo2 ; }
00150 inline G4double GetTanOuterStereo () const { return fTanOuterStereo ; }
00151 inline G4double GetTanOuterStereo2() const { return fTanOuterStereo2 ; }
00152
00153 inline G4double GetEndZ (G4int i) const { return fEndZ[i] ; }
00154 inline G4double GetEndPhi (G4int i) const { return fEndPhi[i]; }
00155 inline G4double GetEndInnerRadius (G4int i) const
00156 { return fEndInnerRadius[i]; }
00157 inline G4double GetEndOuterRadius (G4int i) const
00158 { return fEndOuterRadius[i]; }
00159 inline G4double GetEndInnerRadius () const
00160 { return (fEndInnerRadius[0] > fEndInnerRadius[1] ?
00161 fEndInnerRadius[0] : fEndInnerRadius[1]); }
00162 inline G4double GetEndOuterRadius () const
00163 { return (fEndOuterRadius[0] > fEndOuterRadius[1] ?
00164 fEndOuterRadius[0] : fEndOuterRadius[1]); }
00165
00166 G4VisExtent GetExtent () const;
00167 G4GeometryType GetEntityType() const;
00168 G4VSolid* Clone() const;
00169
00170 G4double GetCubicVolume();
00171
00172
00173 G4double GetSurfaceArea();
00174
00175
00176
00177 G4ThreeVector GetPointOnSurface() const ;
00178
00179 public:
00180
00181 G4TwistedTubs(__void__&);
00182
00183
00184
00185
00186 G4TwistedTubs(const G4TwistedTubs& rhs);
00187 G4TwistedTubs& operator=(const G4TwistedTubs& rhs);
00188
00189
00190 #ifdef G4TWISTDEBUG
00191 G4VTwistSurface * GetOuterHype() const { return fOuterHype; }
00192 #endif
00193
00194 private:
00195
00196 inline void SetFields(G4double phitwist, G4double innerrad,
00197 G4double outerrad,
00198 G4double negativeEndz, G4double positiveEndz);
00199
00200 void CreateSurfaces();
00201
00202 static void AddPolyToExtent( const G4ThreeVector &v0,
00203 const G4ThreeVector &v1,
00204 const G4ThreeVector &w1,
00205 const G4ThreeVector &w0,
00206 const G4VoxelLimits &voxellimit,
00207 const EAxis axis,
00208 G4SolidExtentList &extentlist );
00209 private:
00210
00211 G4double fPhiTwist;
00212 G4double fInnerRadius;
00213 G4double fOuterRadius;
00214 G4double fEndZ[2];
00215 G4double fDPhi;
00216 G4double fZHalfLength;
00217
00218 G4double fInnerStereo;
00219 G4double fOuterStereo;
00220 G4double fTanInnerStereo;
00221 G4double fTanOuterStereo;
00222 G4double fKappa;
00223 G4double fEndInnerRadius[2];
00224 G4double fEndOuterRadius[2];
00225 G4double fEndPhi[2];
00226
00227 G4double fInnerRadius2;
00228 G4double fOuterRadius2;
00229 G4double fTanInnerStereo2;
00230 G4double fTanOuterStereo2;
00231 G4double fEndZ2[2];
00232
00233 G4VTwistSurface *fLowerEndcap;
00234 G4VTwistSurface *fUpperEndcap;
00235 G4VTwistSurface *fLatterTwisted;
00236 G4VTwistSurface *fFormerTwisted;
00237 G4VTwistSurface *fInnerHype;
00238 G4VTwistSurface *fOuterHype;
00239
00240 G4double fCubicVolume;
00241 G4double fSurfaceArea;
00242
00243 mutable G4Polyhedron* fpPolyhedron;
00244
00245 class LastState
00246 {
00247 public:
00248 LastState()
00249 {
00250 p.set(kInfinity,kInfinity,kInfinity);
00251 inside = kOutside;
00252 }
00253 ~LastState(){}
00254 LastState(const LastState& r) : p(r.p), inside(r.inside){}
00255 LastState& operator=(const LastState& r)
00256 {
00257 if (this == &r) { return *this; }
00258 p = r.p; inside = r.inside;
00259 return *this;
00260 }
00261 public:
00262 G4ThreeVector p;
00263 EInside inside;
00264 };
00265
00266 class LastVector
00267 {
00268 public:
00269 LastVector()
00270 {
00271 p.set(kInfinity,kInfinity,kInfinity);
00272 vec.set(kInfinity,kInfinity,kInfinity);
00273 surface = new G4VTwistSurface*[1];
00274 }
00275 ~LastVector()
00276 {
00277 delete [] surface;
00278 }
00279 LastVector(const LastVector& r) : p(r.p), vec(r.vec)
00280 {
00281 surface = new G4VTwistSurface*[1];
00282 surface[0] = r.surface[0];
00283 }
00284 LastVector& operator=(const LastVector& r)
00285 {
00286 if (&r == this) { return *this; }
00287 p = r.p; vec = r.vec;
00288 delete [] surface; surface = new G4VTwistSurface*[1];
00289 surface[0] = r.surface[0];
00290 return *this;
00291 }
00292 public:
00293 G4ThreeVector p;
00294 G4ThreeVector vec;
00295 G4VTwistSurface **surface;
00296 };
00297
00298 class LastValue
00299 {
00300 public:
00301 LastValue()
00302 {
00303 p.set(kInfinity,kInfinity,kInfinity);
00304 value = DBL_MAX;
00305 }
00306 ~LastValue(){}
00307 LastValue(const LastValue& r) : p(r.p), value(r.value){}
00308 LastValue& operator=(const LastValue& r)
00309 {
00310 if (this == &r) { return *this; }
00311 p = r.p; value = r.value;
00312 return *this;
00313 }
00314 public:
00315 G4ThreeVector p;
00316 G4double value;
00317 };
00318
00319 class LastValueWithDoubleVector
00320 {
00321 public:
00322 LastValueWithDoubleVector()
00323 {
00324 p.set(kInfinity,kInfinity,kInfinity);
00325 vec.set(kInfinity,kInfinity,kInfinity);
00326 value = DBL_MAX;
00327 }
00328 ~LastValueWithDoubleVector(){}
00329 LastValueWithDoubleVector(const LastValueWithDoubleVector& r)
00330 : p(r.p), vec(r.vec), value(r.value){}
00331 LastValueWithDoubleVector& operator=(const LastValueWithDoubleVector& r)
00332 {
00333 if (this == &r) { return *this; }
00334 p = r.p; vec = r.vec; value = r.value;
00335 return *this;
00336 }
00337 public:
00338 G4ThreeVector p;
00339 G4ThreeVector vec;
00340 G4double value;
00341 };
00342
00343 LastState fLastInside;
00344 LastVector fLastNormal;
00345 LastValue fLastDistanceToIn;
00346 LastValue fLastDistanceToOut;
00347 LastValueWithDoubleVector fLastDistanceToInWithV;
00348 LastValueWithDoubleVector fLastDistanceToOutWithV;
00349
00350 };
00351
00352
00353
00354
00355
00356
00357
00358 inline
00359 void G4TwistedTubs::SetFields(G4double phitwist, G4double innerrad,
00360 G4double outerrad, G4double negativeEndz,
00361 G4double positiveEndz)
00362 {
00363 fCubicVolume = 0.;
00364 fPhiTwist = phitwist;
00365 fEndZ[0] = negativeEndz;
00366 fEndZ[1] = positiveEndz;
00367 fEndZ2[0] = fEndZ[0] * fEndZ[0];
00368 fEndZ2[1] = fEndZ[1] * fEndZ[1];
00369 fInnerRadius = innerrad;
00370 fOuterRadius = outerrad;
00371 fInnerRadius2 = fInnerRadius * fInnerRadius;
00372 fOuterRadius2 = fOuterRadius * fOuterRadius;
00373
00374 if (std::fabs(fEndZ[0]) >= std::fabs(fEndZ[1])) {
00375 fZHalfLength = std::fabs(fEndZ[0]);
00376 } else {
00377 fZHalfLength = std::fabs(fEndZ[1]);
00378 }
00379
00380 G4double parity = (fPhiTwist > 0 ? 1 : -1);
00381 G4double tanHalfTwist = std::tan(0.5 * fPhiTwist);
00382 G4double innerNumerator = std::fabs(fInnerRadius * tanHalfTwist) * parity;
00383 G4double outerNumerator = std::fabs(fOuterRadius * tanHalfTwist) * parity;
00384
00385 fTanInnerStereo = innerNumerator / fZHalfLength;
00386 fTanOuterStereo = outerNumerator / fZHalfLength;
00387 fTanInnerStereo2 = fTanInnerStereo * fTanInnerStereo;
00388 fTanOuterStereo2 = fTanOuterStereo * fTanOuterStereo;
00389 fInnerStereo = std::atan2(innerNumerator, fZHalfLength);
00390 fOuterStereo = std::atan2(outerNumerator, fZHalfLength);
00391 fEndInnerRadius[0] = std::sqrt(fInnerRadius2 + fEndZ2[0] * fTanInnerStereo2);
00392 fEndInnerRadius[1] = std::sqrt(fInnerRadius2 + fEndZ2[1] * fTanInnerStereo2);
00393 fEndOuterRadius[0] = std::sqrt(fOuterRadius2 + fEndZ2[0] * fTanOuterStereo2);
00394 fEndOuterRadius[1] = std::sqrt(fOuterRadius2 + fEndZ2[1] * fTanOuterStereo2);
00395
00396 fKappa = tanHalfTwist / fZHalfLength;
00397 fEndPhi[0] = std::atan2(fEndZ[0] * tanHalfTwist, fZHalfLength);
00398 fEndPhi[1] = std::atan2(fEndZ[1] * tanHalfTwist, fZHalfLength);
00399
00400 #ifdef G4TWISTDEBUG
00401 G4cout << "/********* G4TwistedTubs::SetFields() Field Parameters ***************** " << G4endl;
00402 G4cout << "/* fPhiTwist : " << fPhiTwist << G4endl;
00403 G4cout << "/* fEndZ(0, 1) : " << fEndZ[0] << " , " << fEndZ[1] << G4endl;
00404 G4cout << "/* fEndPhi(0, 1) : " << fEndPhi[0] << " , " << fEndPhi[1] << G4endl;
00405 G4cout << "/* fInnerRadius, fOuterRadius : " << fInnerRadius << " , " << fOuterRadius << G4endl;
00406 G4cout << "/* fEndInnerRadius(0, 1) : " << fEndInnerRadius[0] << " , "
00407 << fEndInnerRadius[1] << G4endl;
00408 G4cout << "/* fEndOuterRadius(0, 1) : " << fEndOuterRadius[0] << " , "
00409 << fEndOuterRadius[1] << G4endl;
00410 G4cout << "/* fInnerStereo, fOuterStereo : " << fInnerStereo << " , " << fOuterStereo << G4endl;
00411 G4cout << "/* tanHalfTwist, fKappa : " << tanHalfTwist << " , " << fKappa << G4endl;
00412 G4cout << "/*********************************************************************** " << G4endl;
00413 #endif
00414 }
00415
00416 #endif