Import Geant4 10.4.0 source tree

This commit is contained in:
Gabriele Cosmo
2017-12-08 12:52:30 +01:00
parent 98e455a940
commit fc6af9e721
2166 changed files with 276760 additions and 100873 deletions
+46 -1
View File
@@ -1,4 +1,4 @@
$Id: History 104894 2017-06-26 13:30:00Z gcosmo $
$Id: History 107555 2017-11-22 15:26:59Z gcosmo $
-------------------------------------------------------------------
=========================================================
@@ -17,6 +17,51 @@ committal in the CVS repository !
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
November 22, 2017 G.Cosmo geom-csg-V10-03-38
- Fix in SurfaceNormal() for G4Trap, G4Para, G4Trd to assure explicit
counting of the surfaces where the point is placed on edges.
October 20, 2017 G.Cosmo geom-csg-V10-03-37
- Removed redundant overloaded implementation for StreamInfo() in G4UBox
wrapper.
October 9, 2017 G.Cosmo geom-csg-V10-03-36
- Enabled adapter for G4UTorus wrapper, according to migration done in
VecGeom for UnplacedTorus2.
September 1, 2017 E.Tcherniaev geom-csg-V10-03-35
- G4Trap: use specialization (fTrapType 3) for traps that could be also
defined as G4Trd, where isosceles trapeziod is in the XY section, instead
of XZ (faces at Xmin/Xmax symmetrical and have Z-component of normals equal
to zero). Factorised code with case statements for the different
specialisations.
August 14, 2017 E.Tcherniaev geom-csg-V10-03-34
- Reviewed implementation of G4Orb, made more compact and performant.
July 20, 2017 E.Tcherniaev geom-csg-V10-03-33, 32
- Use G4RandomRadiusInRing() in G4CSGSolid::GetRadiusInRing().
July 19, 2017 G.Cosmo geom-csg-V10-03-31
- Enabled adapter also in G4USphere wrapper.
July 13, 2017 E.Tcherniaev geom-csg-V10-03-30
- Improved calculation of bounding box in G4CutTubs and related wrapper.
July 11, 2017 G.Cosmo geom-csg-V10-03-29
- Added G4UPara wrapper for enabling VecGeom Parallelepiped shape.
- Removed inheritance from G4Tubs for G4CutTubs.
July 10, 2017 G.Cosmo geom-csg-V10-03-28
- Added G4UCutTubs wrapper for enabling VecGeom CutTube shape.
- Removed clone class G4OTubs no longer necessary and make G4CutTubs
directly inheriting (temporary) from G4Tubs.
July 4, 2017 E.Tcherniaev geom-csg-V10-03-27
- G4Box: minor optimisation in DistanceToOut(p).
- G4Para: optimisation in Inside(), DistanceToIn/Out(p), use std::abs(xx)
in place of std::max(xx,-xx).
June 26, 2017 E.Tcherniaev geom-csg-V10-03-26
- G4Trd: allow Dx and Dy parameters be equal to zero where appropriate.
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4CSGSolid.hh 83572 2014-09-01 15:23:27Z gcosmo $
// $Id: G4CSGSolid.hh 105315 2017-07-20 14:35:13Z gcosmo $
//
//
// --------------------------------------------------------------------
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4CutTubs.hh 104316 2017-05-24 13:04:23Z gcosmo $
// $Id: G4CutTubs.hh 105075 2017-07-11 14:22:53Z gcosmo $
//
//
// --------------------------------------------------------------------
@@ -46,9 +46,19 @@
#ifndef G4CUTTUBS_HH
#define G4CUTTUBS_HH
#include "G4OTubs.hh"
#if defined(G4GEOM_USE_USOLIDS)
#define G4GEOM_USE_UCTUBS 1
#endif
class G4CutTubs : public G4OTubs
#if defined(G4GEOM_USE_UCTUBS)
#define G4UCutTubs G4CutTubs
#include "G4UCutTubs.hh"
#else
#include "G4CSGSolid.hh"
#include "G4Polyhedron.hh"
class G4CutTubs : public G4CSGSolid
{
public: // with description
@@ -69,9 +79,26 @@ class G4CutTubs : public G4OTubs
// Accessors
inline G4double GetInnerRadius () const;
inline G4double GetOuterRadius () const;
inline G4double GetZHalfLength () const;
inline G4double GetStartPhiAngle () const;
inline G4double GetDeltaPhiAngle () const;
inline G4double GetSinStartPhi () const;
inline G4double GetCosStartPhi () const;
inline G4double GetSinEndPhi () const;
inline G4double GetCosEndPhi () const;
inline G4ThreeVector GetLowNorm () const;
inline G4ThreeVector GetHighNorm () const;
inline G4ThreeVector GetHighNorm () const;
// Modifiers
inline void SetInnerRadius (G4double newRMin);
inline void SetOuterRadius (G4double newRMax);
inline void SetZHalfLength (G4double newDz);
inline void SetStartPhiAngle (G4double newSPhi, G4bool trig=true);
inline void SetDeltaPhiAngle (G4double newDPhi);
// Methods for solid
inline G4double GetCubicVolume();
@@ -120,8 +147,30 @@ class G4CutTubs : public G4OTubs
G4CutTubs& operator=(const G4CutTubs& rhs);
// Copy constructor and assignment operator.
// Older names for access functions
inline G4double GetRMin() const;
inline G4double GetRMax() const;
inline G4double GetDz () const;
inline G4double GetSPhi() const;
inline G4double GetDPhi() const;
protected:
inline void Initialize();
//
// Reset relevant values to zero
inline void CheckSPhiAngle(G4double sPhi);
inline void CheckDPhiAngle(G4double dPhi);
inline void CheckPhiAngles(G4double sPhi, G4double dPhi);
//
// Reset relevant flags and angle values
inline void InitializeTrigonometry();
//
// Recompute relevant trigonometric values and cache them
G4ThreeVector ApproxSurfaceNormal( const G4ThreeVector& p ) const;
//
// Algorithm for SurfaceNormal() following the original
@@ -140,9 +189,18 @@ class G4CutTubs : public G4OTubs
private:
G4ThreeVector fLowNorm, fHighNorm;
//
// Normals of Cut at -/+ Dz
G4double kRadTolerance, kAngTolerance;
//
// Radial and angular tolerances
G4double fRMin, fRMax, fDz, fSPhi, fDPhi;
//
// Radial and angular dimensions
G4double sinCPhi, cosCPhi, cosHDPhiOT, cosHDPhiIT,
sinSPhi, cosSPhi, sinEPhi, cosEPhi;
//
// Cached trigonometric values
G4bool fPhiFullCutTube;
//
@@ -151,8 +209,14 @@ class G4CutTubs : public G4OTubs
G4double halfCarTolerance, halfRadTolerance, halfAngTolerance;
//
// Cached half tolerance values
G4ThreeVector fLowNorm, fHighNorm;
//
// Normals of Cut at -/+ Dz
};
#include "G4CutTubs.icc"
#endif
#endif
+247 -12
View File
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4CutTubs.icc 102768 2017-02-22 08:55:14Z gcosmo $
// $Id: G4CutTubs.icc 105075 2017-07-11 14:22:53Z gcosmo $
//
// --------------------------------------------------------------------
// GEANT 4 inline definitions file
@@ -34,6 +34,252 @@
// Implementation of inline methods of G4CutTubs
// --------------------------------------------------------------------
inline
G4double G4CutTubs::GetInnerRadius () const
{
return fRMin;
}
inline
G4double G4CutTubs::GetOuterRadius () const
{
return fRMax;
}
inline
G4double G4CutTubs::GetZHalfLength () const
{
return fDz;
}
inline
G4double G4CutTubs::GetStartPhiAngle () const
{
return fSPhi;
}
inline
G4double G4CutTubs::GetDeltaPhiAngle () const
{
return fDPhi;
}
inline
G4double G4CutTubs::GetSinStartPhi () const
{
return sinSPhi;
}
inline
G4double G4CutTubs::GetCosStartPhi () const
{
return cosSPhi;
}
inline
G4double G4CutTubs::GetSinEndPhi () const
{
return sinEPhi;
}
inline
G4double G4CutTubs::GetCosEndPhi () const
{
return cosEPhi;
}
inline
G4ThreeVector G4CutTubs::GetLowNorm () const
{
return fLowNorm;
}
inline
G4ThreeVector G4CutTubs::GetHighNorm () const
{
return fHighNorm;
}
inline
void G4CutTubs::Initialize()
{
fCubicVolume = 0.;
fSurfaceArea = 0.;
fRebuildPolyhedron = true;
}
inline
void G4CutTubs::InitializeTrigonometry()
{
G4double hDPhi = 0.5*fDPhi; // half delta phi
G4double cPhi = fSPhi + hDPhi;
G4double ePhi = fSPhi + fDPhi;
sinCPhi = std::sin(cPhi);
cosCPhi = std::cos(cPhi);
cosHDPhiIT = std::cos(hDPhi - 0.5*kAngTolerance); // inner/outer tol half dphi
cosHDPhiOT = std::cos(hDPhi + 0.5*kAngTolerance);
sinSPhi = std::sin(fSPhi);
cosSPhi = std::cos(fSPhi);
sinEPhi = std::sin(ePhi);
cosEPhi = std::cos(ePhi);
}
inline void G4CutTubs::CheckSPhiAngle(G4double sPhi)
{
// Ensure fSphi in 0-2PI or -2PI-0 range if shape crosses 0
if ( sPhi < 0 )
{
fSPhi = CLHEP::twopi - std::fmod(std::fabs(sPhi),CLHEP::twopi);
}
else
{
fSPhi = std::fmod(sPhi,CLHEP::twopi) ;
}
if ( fSPhi+fDPhi > CLHEP::twopi )
{
fSPhi -= CLHEP::twopi ;
}
}
inline void G4CutTubs::CheckDPhiAngle(G4double dPhi)
{
fPhiFullCutTube = true;
if ( dPhi >= CLHEP::twopi-kAngTolerance*0.5 )
{
fDPhi=CLHEP::twopi;
fSPhi=0;
}
else
{
fPhiFullCutTube = false;
if ( dPhi > 0 )
{
fDPhi = dPhi;
}
else
{
std::ostringstream message;
message << "Invalid dphi." << G4endl
<< "Negative or zero delta-Phi (" << dPhi << "), for solid: "
<< GetName();
G4Exception("G4CutTubs::CheckDPhiAngle()", "GeomSolids0002",
FatalException, message);
}
}
}
inline void G4CutTubs::CheckPhiAngles(G4double sPhi, G4double dPhi)
{
CheckDPhiAngle(dPhi);
if ( (fDPhi<CLHEP::twopi) && (sPhi) ) { CheckSPhiAngle(sPhi); }
InitializeTrigonometry();
}
inline
void G4CutTubs::SetInnerRadius (G4double newRMin)
{
if ( newRMin < 0 ) // Check radii
{
std::ostringstream message;
message << "Invalid radii." << G4endl
<< "Invalid values for radii in solid " << GetName() << G4endl
<< " newRMin = " << newRMin
<< ", fRMax = " << fRMax << G4endl
<< " Negative inner radius!";
G4Exception("G4CutTubs::SetInnerRadius()", "GeomSolids0002",
FatalException, message);
}
fRMin= newRMin;
Initialize();
}
inline
void G4CutTubs::SetOuterRadius (G4double newRMax)
{
if ( newRMax <= 0 ) // Check radii
{
std::ostringstream message;
message << "Invalid radii." << G4endl
<< "Invalid values for radii in solid " << GetName() << G4endl
<< " fRMin = " << fRMin
<< ", newRMax = " << newRMax << G4endl
<< " Invalid outer radius!";
G4Exception("G4CutTubs::SetOuterRadius()", "GeomSolids0002",
FatalException, message);
}
fRMax= newRMax;
Initialize();
}
inline
void G4CutTubs::SetZHalfLength (G4double newDz)
{
if (newDz<=0) // Check z-len
{
std::ostringstream message;
message << "Invalid Z half-length." << G4endl
<< "Negative Z half-length (" << newDz << "), for solid: "
<< GetName();
G4Exception("G4CutTubs::SetZHalfLength()", "GeomSolids0002",
FatalException, message);
}
fDz= newDz;
Initialize();
}
inline
void G4CutTubs::SetStartPhiAngle (G4double newSPhi, G4bool compute)
{
// Flag 'compute' can be used to explicitely avoid recomputation of
// trigonometry in case SetDeltaPhiAngle() is invoked afterwards
CheckSPhiAngle(newSPhi);
fPhiFullCutTube = false;
if (compute) { InitializeTrigonometry(); }
Initialize();
}
inline
void G4CutTubs::SetDeltaPhiAngle (G4double newDPhi)
{
CheckPhiAngles(fSPhi, newDPhi);
Initialize();
}
// Older names for access functions
inline
G4double G4CutTubs::GetRMin () const
{
return GetInnerRadius();
}
inline
G4double G4CutTubs::GetRMax () const
{
return GetOuterRadius();
}
inline
G4double G4CutTubs::GetDz () const
{
return GetZHalfLength();
}
inline
G4double G4CutTubs::GetSPhi () const
{
return GetStartPhiAngle();
}
inline
G4double G4CutTubs::GetDPhi () const
{
return GetDeltaPhiAngle();
}
inline G4double G4CutTubs::GetCubicVolume()
{
if (fCubicVolume == 0.) { fCubicVolume = G4VSolid::GetCubicVolume(); }
@@ -45,14 +291,3 @@ inline G4double G4CutTubs::GetSurfaceArea()
if (fSurfaceArea == 0.) { fSurfaceArea = G4VSolid::GetSurfaceArea(); }
return fSurfaceArea;
}
inline
G4ThreeVector G4CutTubs::GetLowNorm () const
{
return fLowNorm;
}
inline
G4ThreeVector G4CutTubs::GetHighNorm () const
{
return fHighNorm;
}
@@ -1,197 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// $Id:$
//
//
// --------------------------------------------------------------------
// GEANT 4 class header file
//
//
// G4OTubs
//
// Class description:
//
// Temporary copy of original G4Tubs code for use by G4CutTubs.
// --------------------------------------------------------------------
#ifndef G4OTUBS_HH
#define G4OTUBS_HH
#include <CLHEP/Units/PhysicalConstants.h>
#include "G4CSGSolid.hh"
#include "G4Polyhedron.hh"
class G4OTubs : public G4CSGSolid
{
public: // with description
G4OTubs( const G4String& pName,
G4double pRMin,
G4double pRMax,
G4double pDz,
G4double pSPhi,
G4double pDPhi );
//
// Constructs a tubs with the given name and dimensions
virtual ~G4OTubs();
//
// Destructor
// Accessors
inline G4double GetInnerRadius () const;
inline G4double GetOuterRadius () const;
inline G4double GetZHalfLength () const;
inline G4double GetStartPhiAngle () const;
inline G4double GetDeltaPhiAngle () const;
inline G4double GetSinStartPhi () const;
inline G4double GetCosStartPhi () const;
inline G4double GetSinEndPhi () const;
inline G4double GetCosEndPhi () const;
// Modifiers
inline void SetInnerRadius (G4double newRMin);
inline void SetOuterRadius (G4double newRMax);
inline void SetZHalfLength (G4double newDz);
inline void SetStartPhiAngle (G4double newSPhi, G4bool trig=true);
inline void SetDeltaPhiAngle (G4double newDPhi);
// Methods for solid
inline G4double GetCubicVolume();
inline G4double GetSurfaceArea();
void BoundingLimits(G4ThreeVector& pMin, G4ThreeVector& pMax) const;
G4bool CalculateExtent( const EAxis pAxis,
const G4VoxelLimits& pVoxelLimit,
const G4AffineTransform& pTransform,
G4double& pmin, G4double& pmax ) const;
EInside Inside( const G4ThreeVector& p ) const;
G4ThreeVector SurfaceNormal( const G4ThreeVector& p ) const;
G4double DistanceToIn(const G4ThreeVector& p, const G4ThreeVector& v) const;
G4double DistanceToIn(const G4ThreeVector& p) const;
G4double DistanceToOut(const G4ThreeVector& p, const G4ThreeVector& v,
const G4bool calcNorm=G4bool(false),
G4bool *validNorm=0, G4ThreeVector *n=0) const;
G4double DistanceToOut(const G4ThreeVector& p) const;
G4GeometryType GetEntityType() const;
G4ThreeVector GetPointOnSurface() const;
G4VSolid* Clone() const;
std::ostream& StreamInfo( std::ostream& os ) const;
// Visualisation functions
void DescribeYourselfTo ( G4VGraphicsScene& scene ) const;
G4Polyhedron* CreatePolyhedron () const;
public: // without description
G4OTubs(__void__&);
//
// Fake default constructor for usage restricted to direct object
// persistency for clients requiring preallocation of memory for
// persistifiable objects.
G4OTubs(const G4OTubs& rhs);
G4OTubs& operator=(const G4OTubs& rhs);
// Copy constructor and assignment operator.
// Older names for access functions
inline G4double GetRMin() const;
inline G4double GetRMax() const;
inline G4double GetDz () const;
inline G4double GetSPhi() const;
inline G4double GetDPhi() const;
protected:
inline void Initialize();
//
// Reset relevant values to zero
inline void CheckSPhiAngle(G4double sPhi);
inline void CheckDPhiAngle(G4double dPhi);
inline void CheckPhiAngles(G4double sPhi, G4double dPhi);
//
// Reset relevant flags and angle values
inline void InitializeTrigonometry();
//
// Recompute relevant trigonometric values and cache them
virtual G4ThreeVector ApproxSurfaceNormal( const G4ThreeVector& p ) const;
//
// Algorithm for SurfaceNormal() following the original
// specification for points not on the surface
protected:
// Used by distanceToOut
//
enum ESide {kNull,kRMin,kRMax,kSPhi,kEPhi,kPZ,kMZ};
// Used by normal
//
enum ENorm {kNRMin,kNRMax,kNSPhi,kNEPhi,kNZ};
G4double kRadTolerance, kAngTolerance;
//
// Radial and angular tolerances
G4double fRMin, fRMax, fDz, fSPhi, fDPhi;
//
// Radial and angular dimensions
G4double sinCPhi, cosCPhi, cosHDPhiOT, cosHDPhiIT,
sinSPhi, cosSPhi, sinEPhi, cosEPhi;
//
// Cached trigonometric values
G4bool fPhiFullTube;
//
// Flag for identification of section or full tube
G4double halfCarTolerance, halfRadTolerance, halfAngTolerance;
//
// Cached half tolerance values
};
#include "G4OTubs.icc"
#endif
@@ -1,292 +0,0 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// $Id:$
//
// --------------------------------------------------------------------
// GEANT 4 inline definitions file
//
// G4OTubs.icc
//
// Implementation of inline methods of G4OTubs
// --------------------------------------------------------------------
inline
G4double G4OTubs::GetInnerRadius () const
{
return fRMin;
}
inline
G4double G4OTubs::GetOuterRadius () const
{
return fRMax;
}
inline
G4double G4OTubs::GetZHalfLength () const
{
return fDz;
}
inline
G4double G4OTubs::GetStartPhiAngle () const
{
return fSPhi;
}
inline
G4double G4OTubs::GetDeltaPhiAngle () const
{
return fDPhi;
}
inline
G4double G4OTubs::GetSinStartPhi () const
{
return sinSPhi;
}
inline
G4double G4OTubs::GetCosStartPhi () const
{
return cosSPhi;
}
inline
G4double G4OTubs::GetSinEndPhi () const
{
return sinEPhi;
}
inline
G4double G4OTubs::GetCosEndPhi () const
{
return cosEPhi;
}
inline
void G4OTubs::Initialize()
{
fCubicVolume = 0.;
fSurfaceArea = 0.;
fRebuildPolyhedron = true;
}
inline
void G4OTubs::InitializeTrigonometry()
{
G4double hDPhi = 0.5*fDPhi; // half delta phi
G4double cPhi = fSPhi + hDPhi;
G4double ePhi = fSPhi + fDPhi;
sinCPhi = std::sin(cPhi);
cosCPhi = std::cos(cPhi);
cosHDPhiIT = std::cos(hDPhi - 0.5*kAngTolerance); // inner/outer tol half dphi
cosHDPhiOT = std::cos(hDPhi + 0.5*kAngTolerance);
sinSPhi = std::sin(fSPhi);
cosSPhi = std::cos(fSPhi);
sinEPhi = std::sin(ePhi);
cosEPhi = std::cos(ePhi);
}
inline void G4OTubs::CheckSPhiAngle(G4double sPhi)
{
// Ensure fSphi in 0-2PI or -2PI-0 range if shape crosses 0
if ( sPhi < 0 )
{
fSPhi = CLHEP::twopi - std::fmod(std::fabs(sPhi),CLHEP::twopi);
}
else
{
fSPhi = std::fmod(sPhi,CLHEP::twopi) ;
}
if ( fSPhi+fDPhi > CLHEP::twopi )
{
fSPhi -= CLHEP::twopi ;
}
}
inline void G4OTubs::CheckDPhiAngle(G4double dPhi)
{
fPhiFullTube = true;
if ( dPhi >= CLHEP::twopi-kAngTolerance*0.5 )
{
fDPhi=CLHEP::twopi;
fSPhi=0;
}
else
{
fPhiFullTube = false;
if ( dPhi > 0 )
{
fDPhi = dPhi;
}
else
{
std::ostringstream message;
message << "Invalid dphi." << G4endl
<< "Negative or zero delta-Phi (" << dPhi << "), for solid: "
<< GetName();
G4Exception("G4Tubs::CheckDPhiAngle()", "GeomSolids0002",
FatalException, message);
}
}
}
inline void G4OTubs::CheckPhiAngles(G4double sPhi, G4double dPhi)
{
CheckDPhiAngle(dPhi);
if ( (fDPhi<CLHEP::twopi) && (sPhi) ) { CheckSPhiAngle(sPhi); }
InitializeTrigonometry();
}
inline
void G4OTubs::SetInnerRadius (G4double newRMin)
{
if ( newRMin < 0 ) // Check radii
{
std::ostringstream message;
message << "Invalid radii." << G4endl
<< "Invalid values for radii in solid " << GetName() << G4endl
<< " newRMin = " << newRMin
<< ", fRMax = " << fRMax << G4endl
<< " Negative inner radius!";
G4Exception("G4Tubs::SetInnerRadius()", "GeomSolids0002",
FatalException, message);
}
fRMin= newRMin;
Initialize();
}
inline
void G4OTubs::SetOuterRadius (G4double newRMax)
{
if ( newRMax <= 0 ) // Check radii
{
std::ostringstream message;
message << "Invalid radii." << G4endl
<< "Invalid values for radii in solid " << GetName() << G4endl
<< " fRMin = " << fRMin
<< ", newRMax = " << newRMax << G4endl
<< " Invalid outer radius!";
G4Exception("G4Tubs::SetOuterRadius()", "GeomSolids0002",
FatalException, message);
}
fRMax= newRMax;
Initialize();
}
inline
void G4OTubs::SetZHalfLength (G4double newDz)
{
if (newDz<=0) // Check z-len
{
std::ostringstream message;
message << "Invalid Z half-length." << G4endl
<< "Negative Z half-length (" << newDz << "), for solid: "
<< GetName();
G4Exception("G4Tubs::SetZHalfLength()", "GeomSolids0002",
FatalException, message);
}
fDz= newDz;
Initialize();
}
inline
void G4OTubs::SetStartPhiAngle (G4double newSPhi, G4bool compute)
{
// Flag 'compute' can be used to explicitely avoid recomputation of
// trigonometry in case SetDeltaPhiAngle() is invoked afterwards
CheckSPhiAngle(newSPhi);
fPhiFullTube = false;
if (compute) { InitializeTrigonometry(); }
Initialize();
}
inline
void G4OTubs::SetDeltaPhiAngle (G4double newDPhi)
{
CheckPhiAngles(fSPhi, newDPhi);
Initialize();
}
// Older names for access functions
inline
G4double G4OTubs::GetRMin () const
{
return GetInnerRadius();
}
inline
G4double G4OTubs::GetRMax () const
{
return GetOuterRadius();
}
inline
G4double G4OTubs::GetDz () const
{
return GetZHalfLength() ;
}
inline
G4double G4OTubs::GetSPhi () const
{
return GetStartPhiAngle();
}
inline
G4double G4OTubs::GetDPhi () const
{
return GetDeltaPhiAngle();
}
inline
G4double G4OTubs::GetCubicVolume()
{
if(fCubicVolume != 0.) {;}
else { fCubicVolume = fDPhi*fDz*(fRMax*fRMax-fRMin*fRMin); }
return fCubicVolume;
}
inline
G4double G4OTubs::GetSurfaceArea()
{
if(fSurfaceArea != 0.) {;}
else
{
fSurfaceArea = fDPhi*(fRMin+fRMax)*(2*fDz+fRMax-fRMin);
if (!fPhiFullTube)
{
fSurfaceArea = fSurfaceArea + 4*fDz*(fRMax-fRMin);
}
}
return fSurfaceArea;
}
+22 -27
View File
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4Orb.hh 104316 2017-05-24 13:04:23Z gcosmo $
// $Id: G4Orb.hh 105834 2017-08-23 08:14:34Z gcosmo $
//
//
// --------------------------------------------------------------------
@@ -38,6 +38,7 @@
// fRmax outer radius
// History:
// 08.08.17 E.Tcherniaev - revised
// 20.08.03 V.Grichine - created
// --------------------------------------------------------------------
@@ -63,19 +64,17 @@ class G4Orb : public G4CSGSolid
public: // with description
G4Orb(const G4String& pName, G4double pRmax);
virtual ~G4Orb() ;
// Accessors
~G4Orb();
// Accessors and modifiers
inline G4double GetRadius() const;
inline G4double GetRadialTolerance() const;
// Modifiers
inline void SetRadius(G4double newRmax);
// Methods for solid
// Methods for solid
inline G4double GetCubicVolume();
inline G4double GetSurfaceArea();
@@ -90,14 +89,14 @@ class G4Orb : public G4CSGSolid
const G4VoxelLimits& pVoxelLimit,
const G4AffineTransform& pTransform,
G4double& pmin, G4double& pmax) const;
EInside Inside(const G4ThreeVector& p) const;
G4ThreeVector SurfaceNormal( const G4ThreeVector& p) const;
G4double DistanceToIn(const G4ThreeVector& p,
const G4ThreeVector& v) const;
G4double DistanceToIn(const G4ThreeVector& p) const;
G4double DistanceToOut(const G4ThreeVector& p,
@@ -105,11 +104,11 @@ class G4Orb : public G4CSGSolid
const G4bool calcNorm=G4bool(false),
G4bool *validNorm=0,
G4ThreeVector *n=0) const;
G4double DistanceToOut(const G4ThreeVector& p) const;
G4GeometryType GetEntityType() const;
G4ThreeVector GetPointOnSurface() const;
G4VSolid* Clone() const;
@@ -117,35 +116,31 @@ class G4Orb : public G4CSGSolid
std::ostream& StreamInfo(std::ostream& os) const;
// Visualisation functions
void DescribeYourselfTo(G4VGraphicsScene& scene) const;
G4Polyhedron* CreatePolyhedron() const;
void DescribeYourselfTo (G4VGraphicsScene& scene) const;
G4VisExtent GetExtent () const;
G4Polyhedron* CreatePolyhedron () const;
public: // without description
G4Orb(__void__&);
// Fake default constructor for usage restricted to direct object
// persistency for clients requiring preallocation of memory for
// persistifiable objects.
// persistifiable objects
G4Orb(const G4Orb& rhs);
G4Orb& operator=(const G4Orb& rhs);
// Copy constructor and assignment operator.
// Copy constructor and assignment operator
protected:
// Used by distanceToOut
enum ESide {kNull,kRMax};
// used by normal
enum ENorm {kNRMax};
void Initialize();
private:
G4double fRmax;
G4double fRmaxTolerance;
G4double halfRmaxTol;
G4double sqrRmaxPlusTol, sqrRmaxMinusTol;
};
#include "G4Orb.icc"
+5 -3
View File
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4Orb.icc 103471 2017-04-11 07:31:42Z gcosmo $
// $Id: G4Orb.icc 105834 2017-08-23 08:14:34Z gcosmo $
//
// --------------------------------------------------------------------
// GEANT 4 inline definitions file
@@ -43,14 +43,16 @@ G4double G4Orb::GetRadius() const
inline
G4double G4Orb::GetRadialTolerance() const
{
return fRmaxTolerance;
return 2*halfRmaxTol;
}
inline
void G4Orb::SetRadius(G4double newRmax)
{
fRmax=newRmax;
fCubicVolume= 0.;
Initialize();
fCubicVolume = 0.;
fSurfaceArea = 0.;
fRebuildPolyhedron = true;
}
+12 -1
View File
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4Para.hh 104452 2017-05-31 15:41:24Z gcosmo $
// $Id: G4Para.hh 105075 2017-07-11 14:22:53Z gcosmo $
//
//
// --------------------------------------------------------------------
@@ -71,6 +71,15 @@
#ifndef G4Para_HH
#define G4Para_HH
#if defined(G4GEOM_USE_USOLIDS)
#define G4GEOM_USE_UPARA 1
#endif
#if defined(G4GEOM_USE_UPARA)
#define G4UPara G4Para
#include "G4UPara.hh"
#else
#include "G4CSGSolid.hh"
#include "G4Polyhedron.hh"
@@ -183,3 +192,5 @@ class G4Para : public G4CSGSolid
#include "G4Para.icc"
#endif
#endif
@@ -78,8 +78,6 @@ class G4UBox : public G4UAdapter<vecgeom::UnplacedBox>
inline G4GeometryType GetEntityType() const;
std::ostream& StreamInfo(std::ostream& os) const;
void BoundingLimits(G4ThreeVector& pMin, G4ThreeVector& pMax) const;
G4bool CalculateExtent(const EAxis pAxis,
@@ -0,0 +1,133 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// $Id:$
//
//
// --------------------------------------------------------------------
// GEANT 4 class header file
//
//
// G4UCutTubs
//
// Class description:
//
// Wrapper class for G4CutTubs to make use of VecGeom CutTube.
// History:
// 07.07.17 G.Cosmo, CERN/PH
// --------------------------------------------------------------------
#ifndef G4UCUTTUBS_HH
#define G4UCUTTUBS_HH
#include "G4UAdapter.hh"
#if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
#include <volumes/UnplacedCutTube.h>
#include "G4Polyhedron.hh"
class G4UCutTubs : public G4UAdapter<vecgeom::UnplacedCutTube>
{
using Shape_t = vecgeom::UnplacedCutTube;
using Base_t = G4UAdapter<vecgeom::UnplacedCutTube>;
public: // with description
G4UCutTubs( const G4String& pName,
G4double pRMin,
G4double pRMax,
G4double pDz,
G4double pSPhi,
G4double pDPhi,
G4ThreeVector pLowNorm,
G4ThreeVector pHighNorm );
// Constructs a cut-tubs with the given name, dimensions and cuts
~G4UCutTubs();
G4VSolid* Clone() const;
G4double GetInnerRadius () const;
G4double GetOuterRadius () const;
G4double GetZHalfLength () const;
G4double GetStartPhiAngle () const;
G4double GetDeltaPhiAngle () const;
G4double GetSinStartPhi () const;
G4double GetCosStartPhi () const;
G4double GetSinEndPhi () const;
G4double GetCosEndPhi () const;
G4ThreeVector GetLowNorm () const;
G4ThreeVector GetHighNorm () const;
void SetInnerRadius (G4double newRMin);
void SetOuterRadius (G4double newRMax);
void SetZHalfLength (G4double newDz);
void SetStartPhiAngle (G4double newSPhi, G4bool trig=true);
void SetDeltaPhiAngle (G4double newDPhi);
inline G4GeometryType GetEntityType() const;
void BoundingLimits(G4ThreeVector& pMin, G4ThreeVector& pMax) const;
G4bool CalculateExtent(const EAxis pAxis,
const G4VoxelLimits& pVoxelLimit,
const G4AffineTransform& pTransform,
G4double& pMin, G4double& pMax) const;
G4Polyhedron* CreatePolyhedron() const;
public: // without description
G4UCutTubs(__void__&);
// Fake default constructor for usage restricted to direct object
// persistency for clients requiring preallocation of memory for
// persistifiable objects.
G4UCutTubs(const G4UCutTubs& rhs);
G4UCutTubs& operator=(const G4UCutTubs& rhs);
// Copy constructor and assignment operator.
private:
G4double GetCutZ(const G4ThreeVector& p) const;
// Get Z value of the point on Cutted Plane
};
// --------------------------------------------------------------------
// Inline methods
// --------------------------------------------------------------------
inline G4GeometryType G4UCutTubs::GetEntityType() const
{
return "G4CutTubs";
}
#endif // G4GEOM_USE_USOLIDS
#endif
+1 -1
View File
@@ -34,7 +34,7 @@
//
// Class description:
//
// Wrapper class for UOrb to make use of UOrb from USolids module.
// Wrapper class for G4Orb to make use of VecGeom Orb.
// History:
// 30.10.13 G.Cosmo, CERN/PH
@@ -0,0 +1,143 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// $Id:$
//
//
// --------------------------------------------------------------------
// GEANT 4 class header file
//
// G4UPara
//
// Class description:
//
// Wrapper class for G4Para to make use of VecGeom Parallelepiped.
// History:
// 13.09.13 G.Cosmo, CERN/PH
// --------------------------------------------------------------------
#ifndef G4UPARA_HH
#define G4UPARA_HH
#include "G4UAdapter.hh"
#if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
#include <volumes/UnplacedParallelepiped.h>
#include "G4Polyhedron.hh"
class G4UPara : public G4UAdapter<vecgeom::UnplacedParallelepiped>
{
using Shape_t = vecgeom::UnplacedParallelepiped;
using Base_t = G4UAdapter<vecgeom::UnplacedParallelepiped>;
public: // with description
G4UPara(const G4String& pName,
G4double pDx, G4double pDy, G4double pDz,
G4double pAlpha, G4double pTheta, G4double pPhi);
G4UPara(const G4String& pName,
const G4ThreeVector pt[8]);
~G4UPara();
// Accessors
G4double GetZHalfLength() const;
G4double GetYHalfLength() const;
G4double GetXHalfLength() const;
G4ThreeVector GetSymAxis() const;
G4double GetTanAlpha() const;
// Modifiers
void SetXHalfLength(G4double val);
void SetYHalfLength(G4double val);
void SetZHalfLength(G4double val);
void SetAlpha(G4double alpha);
void SetTanAlpha(G4double val);
void SetThetaAndPhi(double pTheta, double pPhi);
void SetAllParameters(G4double pDx, G4double pDy, G4double pDz,
G4double pAlpha, G4double pTheta, G4double pPhi);
void ComputeDimensions(G4VPVParameterisation* p,
const G4int n,
const G4VPhysicalVolume* pRep);
inline G4GeometryType GetEntityType() const;
void BoundingLimits(G4ThreeVector& pMin, G4ThreeVector& pMax) const;
G4bool CalculateExtent(const EAxis pAxis,
const G4VoxelLimits& pVoxelLimit,
const G4AffineTransform& pTransform,
G4double& pMin, G4double& pMax) const;
G4VSolid* Clone() const;
G4Polyhedron* CreatePolyhedron () const;
public: // without description
G4UPara(__void__&);
// Fake default constructor for usage restricted to direct object
// persistency for clients requiring preallocation of memory for
// persistifiable objects
G4UPara(const G4UPara& rhs);
G4UPara& operator=(const G4UPara& rhs);
// Copy constructor and assignment operator
private:
void CheckParameters();
// Check parameters
void MakePlanes();
// Set side planes
private:
G4double fTalpha,fTthetaCphi,fTthetaSphi;
struct { G4double a,b,c,d; } fPlanes[4];
};
// --------------------------------------------------------------------
// Inline methods
// --------------------------------------------------------------------
inline G4GeometryType G4UPara::GetEntityType() const
{
return "G4Para";
}
#endif // G4GEOM_USE_USOLIDS
#endif
@@ -34,7 +34,7 @@
//
// Class description:
//
// Wrapper class for USphere to make use of USphere from USolids module.
// Wrapper class for G4Sphere to make use of VecGeom Sphere.
// History:
// 13.09.13 G.Cosmo, CERN/PH
@@ -42,16 +42,19 @@
#ifndef G4USPHERE_HH
#define G4USPHERE_HH
#include "G4USolid.hh"
#include "G4UAdapter.hh"
#if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
#include "USphere.hh"
#include <volumes/UnplacedSphere.h>
#include "G4Polyhedron.hh"
class G4USphere : public G4USolid
class G4USphere : public G4UAdapter<vecgeom::UnplacedSphere>
{
using Shape_t = vecgeom::UnplacedSphere;
using Base_t = G4UAdapter<vecgeom::UnplacedSphere>;
public: // with description
G4USphere(const G4String& pName,
@@ -69,8 +72,6 @@ class G4USphere : public G4USolid
G4VSolid* Clone() const;
inline USphere* GetShape() const;
G4double GetInnerRadius () const;
G4double GetOuterRadius () const;
G4double GetStartPhiAngle () const;
@@ -121,11 +122,6 @@ class G4USphere : public G4USolid
// Inline methods
// --------------------------------------------------------------------
inline USphere* G4USphere::GetShape() const
{
return (USphere*) fShape;
}
inline G4GeometryType G4USphere::GetEntityType() const
{
return "G4Sphere";
+6 -10
View File
@@ -42,16 +42,19 @@
#ifndef G4UTORUS_HH
#define G4UTORUS_HH
#include "G4USolid.hh"
#include "G4UAdapter.hh"
#if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
#include "UTorus.hh"
#include <volumes/UnplacedTorus2.h>
#include "G4Polyhedron.hh"
class G4UTorus : public G4USolid
class G4UTorus : public G4UAdapter<vecgeom::UnplacedTorus2>
{
using Shape_t = vecgeom::UnplacedTorus2;
using Base_t = G4UAdapter<vecgeom::UnplacedTorus2>;
public: // with description
G4UTorus(const G4String& pName,
@@ -67,8 +70,6 @@ class G4UTorus : public G4USolid
G4VSolid* Clone() const;
inline UTorus* GetShape() const;
G4double GetRmin() const;
G4double GetRmax() const;
G4double GetRtor() const;
@@ -115,11 +116,6 @@ class G4UTorus : public G4USolid
// Inline methods
// --------------------------------------------------------------------
inline UTorus* G4UTorus::GetShape() const
{
return (UTorus*) fShape;
}
inline G4GeometryType G4UTorus::GetEntityType() const
{
return "G4Torus";
+5 -4
View File
@@ -11,7 +11,7 @@
#
# Generated on : 24/9/2010
#
# $Id: sources.cmake 103471 2017-04-11 07:31:42Z gcosmo $
# $Id: sources.cmake 105075 2017-07-11 14:22:53Z gcosmo $
#
#------------------------------------------------------------------------------
@@ -44,8 +44,6 @@ GEANT4_DEFINE_MODULE(NAME G4csg
G4CutTubs.icc
G4Orb.hh
G4Orb.icc
G4OTubs.hh
G4OTubs.icc
G4Para.hh
G4Para.icc
G4Sphere.hh
@@ -60,7 +58,9 @@ GEANT4_DEFINE_MODULE(NAME G4csg
G4Tubs.icc
G4UBox.hh
G4UCons.hh
G4UCutTubs.hh
G4UOrb.hh
G4UPara.hh
G4USphere.hh
G4UTorus.hh
G4UTrap.hh
@@ -72,7 +72,6 @@ GEANT4_DEFINE_MODULE(NAME G4csg
G4Cons.cc
G4CutTubs.cc
G4Orb.cc
G4OTubs.cc
G4Para.cc
G4Sphere.cc
G4Torus.cc
@@ -81,7 +80,9 @@ GEANT4_DEFINE_MODULE(NAME G4csg
G4Tubs.cc
G4UBox.cc
G4UCons.cc
G4UCutTubs.cc
G4UOrb.cc
G4UPara.cc
G4USphere.cc
G4UTorus.cc
G4UTrap.cc
+6 -6
View File
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4Box.cc 104316 2017-05-24 13:04:23Z gcosmo $
// $Id: G4Box.cc 105023 2017-07-05 09:55:35Z gcosmo $
//
//
//
@@ -482,11 +482,11 @@ G4double G4Box::DistanceToOut(const G4ThreeVector& p) const
DumpInfo();
}
#endif
G4double dist = std::max(std::max(
std::abs(p.x())-fDx,
std::abs(p.y())-fDy),
std::abs(p.z())-fDz);
return (dist < 0) ? -dist : 0.;
G4double dist = std::min(std::min(
fDx-std::abs(p.x()),
fDy-std::abs(p.y())),
fDz-std::abs(p.z()));
return (dist > 0) ? dist : 0.;
}
//////////////////////////////////////////////////////////////////////////
+3 -7
View File
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4CSGSolid.cc 83572 2014-09-01 15:23:27Z gcosmo $
// $Id: G4CSGSolid.cc 105315 2017-07-20 14:35:13Z gcosmo $
//
// --------------------------------------------------------------------
@@ -32,6 +32,7 @@
#include "G4CSGSolid.hh"
#include "Randomize.hh"
#include "G4RandomTools.hh"
#include "G4Polyhedron.hh"
#include "G4AutoLock.hh"
@@ -110,12 +111,7 @@ G4CSGSolid& G4CSGSolid::operator = (const G4CSGSolid& rhs)
G4double G4CSGSolid::GetRadiusInRing(G4double rmin, G4double rmax) const
{
// Generate radius in annular ring according to uniform area
//
if (rmin<=0.) { return rmax*std::sqrt(G4UniformRand()); }
if (rmin!=rmax) { return std::sqrt(G4UniformRand()
* (sqr(rmax)-sqr(rmin))+sqr(rmin)); }
return rmin;
return G4RandomRadiusInRing(rmin, rmax);
}
std::ostream& G4CSGSolid::StreamInfo(std::ostream& os) const
+126 -26
View File
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4CutTubs.cc 104316 2017-05-24 13:04:23Z gcosmo $
// $Id: G4CutTubs.cc 105118 2017-07-13 10:43:55Z gcosmo $
//
//
// class G4CutTubs
@@ -40,11 +40,13 @@
#include "G4CutTubs.hh"
#if !defined(G4GEOM_USE_UCTUBS)
#include "G4GeomTools.hh"
#include "G4VoxelLimits.hh"
#include "G4AffineTransform.hh"
#include "G4BoundingEnvelope.hh"
#include "G4GeometryTolerance.hh"
#include "G4BoundingEnvelope.hh"
#include "G4VPVParameterisation.hh"
@@ -53,7 +55,6 @@
#include "meshdefs.hh"
#include "G4VGraphicsScene.hh"
#include "G4Polyhedron.hh"
using namespace CLHEP;
@@ -67,8 +68,7 @@ G4CutTubs::G4CutTubs( const G4String &pName,
G4double pDz,
G4double pSPhi, G4double pDPhi,
G4ThreeVector pLowNorm,G4ThreeVector pHighNorm )
: G4OTubs(pName, pRMin, pRMax, pDz, pSPhi, pDPhi),
fPhiFullCutTube(true)
: G4CSGSolid(pName), fRMin(pRMin), fRMax(pRMax), fDz(pDz), fSPhi(0), fDPhi(0)
{
kRadTolerance = G4GeometryTolerance::GetInstance()->GetRadialTolerance();
kAngTolerance = G4GeometryTolerance::GetInstance()->GetAngularTolerance();
@@ -77,11 +77,28 @@ G4CutTubs::G4CutTubs( const G4String &pName,
halfRadTolerance = kRadTolerance*0.5;
halfAngTolerance = kAngTolerance*0.5;
if (pDz<=0) // Check z-len
{
std::ostringstream message;
message << "Negative Z half-length (" << pDz << ") in solid: " << GetName();
G4Exception("G4CutTubs::G4CutTubs()", "GeomSolids0002", FatalException, message);
}
if ( (pRMin >= pRMax) || (pRMin < 0) ) // Check radii
{
std::ostringstream message;
message << "Invalid values for radii in solid: " << GetName()
<< G4endl
<< " pRMin = " << pRMin << ", pRMax = " << pRMax;
G4Exception("G4CutTubs::G4CutTubs()", "GeomSolids0002", FatalException, message);
}
// Check angles
//
CheckPhiAngles(pSPhi, pDPhi);
// Check on Cutted Planes Normals
// If there is NO CUT, propose to use G4Tubs instead
//
if(pDPhi<twopi) { fPhiFullCutTube=false; }
if ( ( !pLowNorm.x()) && ( !pLowNorm.y())
&& ( !pHighNorm.x()) && (!pHighNorm.y()) )
{
@@ -146,9 +163,13 @@ G4CutTubs::G4CutTubs( const G4String &pName,
// for usage restricted to object persistency.
//
G4CutTubs::G4CutTubs( __void__& a )
: G4OTubs(a), fLowNorm(G4ThreeVector()),
fHighNorm(G4ThreeVector()), fPhiFullCutTube(false),
halfCarTolerance(0.), halfRadTolerance(0.), halfAngTolerance(0.)
: G4CSGSolid(a), kRadTolerance(0.), kAngTolerance(0.),
fRMin(0.), fRMax(0.), fDz(0.), fSPhi(0.), fDPhi(0.),
sinCPhi(0.), cosCPhi(0.), cosHDPhiOT(0.), cosHDPhiIT(0.),
sinSPhi(0.), cosSPhi(0.), sinEPhi(0.), cosEPhi(0.),
fPhiFullCutTube(false),
halfCarTolerance(0.), halfRadTolerance(0.), halfAngTolerance(0.),
fLowNorm(G4ThreeVector()), fHighNorm(G4ThreeVector())
{
}
@@ -165,11 +186,19 @@ G4CutTubs::~G4CutTubs()
// Copy constructor
G4CutTubs::G4CutTubs(const G4CutTubs& rhs)
: G4OTubs(rhs), fLowNorm(rhs.fLowNorm), fHighNorm(rhs.fHighNorm),
: G4CSGSolid(rhs),
kRadTolerance(rhs.kRadTolerance), kAngTolerance(rhs.kAngTolerance),
fRMin(rhs.fRMin), fRMax(rhs.fRMax), fDz(rhs.fDz),
fSPhi(rhs.fSPhi), fDPhi(rhs.fDPhi),
sinCPhi(rhs.sinCPhi), cosCPhi(rhs.cosCPhi),
cosHDPhiOT(rhs.cosHDPhiOT), cosHDPhiIT(rhs.cosHDPhiIT),
sinSPhi(rhs.sinSPhi), cosSPhi(rhs.cosSPhi),
sinEPhi(rhs.sinEPhi), cosEPhi(rhs.cosEPhi),
fPhiFullCutTube(rhs.fPhiFullCutTube),
halfCarTolerance(rhs.halfCarTolerance),
halfRadTolerance(rhs.halfRadTolerance),
halfAngTolerance(rhs.halfAngTolerance)
halfAngTolerance(rhs.halfAngTolerance),
fLowNorm(rhs.fLowNorm), fHighNorm(rhs.fHighNorm)
{
}
@@ -185,15 +214,22 @@ G4CutTubs& G4CutTubs::operator = (const G4CutTubs& rhs)
// Copy base class data
//
G4OTubs::operator=(rhs);
G4CSGSolid::operator=(rhs);
// Copy data
//
fLowNorm = rhs.fLowNorm; fHighNorm = rhs.fHighNorm;
kRadTolerance = rhs.kRadTolerance; kAngTolerance = rhs.kAngTolerance;
fRMin = rhs.fRMin; fRMax = rhs.fRMax; fDz = rhs.fDz;
fSPhi = rhs.fSPhi; fDPhi = rhs.fDPhi;
sinCPhi = rhs.sinCPhi; cosCPhi = rhs.cosCPhi;
cosHDPhiOT = rhs.cosHDPhiOT; cosHDPhiIT = rhs.cosHDPhiIT;
sinSPhi = rhs.sinSPhi; cosSPhi = rhs.cosSPhi;
sinEPhi = rhs.sinEPhi; cosEPhi = rhs.cosEPhi;
fPhiFullCutTube = rhs.fPhiFullCutTube;
halfCarTolerance = rhs.halfCarTolerance;
halfRadTolerance = rhs.halfRadTolerance;
halfAngTolerance = rhs.halfAngTolerance;
fLowNorm = rhs.fLowNorm; fHighNorm = rhs.fHighNorm;
return *this;
}
@@ -207,25 +243,84 @@ void G4CutTubs::BoundingLimits(G4ThreeVector& pMin, G4ThreeVector& pMax) const
G4double rmin = GetInnerRadius();
G4double rmax = GetOuterRadius();
G4double dz = GetZHalfLength();
G4double dphi = GetDeltaPhiAngle();
G4double sinSphi = GetSinStartPhi();
G4double cosSphi = GetCosStartPhi();
G4double sinEphi = GetSinEndPhi();
G4double cosEphi = GetCosEndPhi();
G4ThreeVector norm;
G4double xynorm, znorm;
G4double mag, topx, topy, dists, diste;
G4bool iftop;
// get zmin
// Find Zmin
//
G4double zmin;
norm = GetLowNorm();
xynorm = std::sqrt(norm.x()*norm.x()+norm.y()*norm.y());
znorm = std::abs(norm.z());
G4double zmin = -(dz + rmax*xynorm/znorm);
mag = std::sqrt(norm.x()*norm.x() + norm.y()*norm.y());
topx = (mag == 0) ? 0 : -rmax*norm.x()/mag;
topy = (mag == 0) ? 0 : -rmax*norm.y()/mag;
dists = sinSphi*topx - cosSphi*topy;
diste = -sinEphi*topx + cosEphi*topy;
if (dphi > pi)
{
iftop = true;
if (dists > 0 && diste > 0)iftop = false;
}
else
{
iftop = false;
if (dists <= 0 && diste <= 0) iftop = true;
}
if (iftop)
{
zmin = -(norm.x()*topx + norm.y()*topy)/norm.z() - dz;
}
else
{
G4double z1 = -rmin*(norm.x()*cosSphi + norm.y()*sinSphi)/norm.z() - dz;
G4double z2 = -rmin*(norm.x()*cosEphi + norm.y()*sinEphi)/norm.z() - dz;
G4double z3 = -rmax*(norm.x()*cosSphi + norm.y()*sinSphi)/norm.z() - dz;
G4double z4 = -rmax*(norm.x()*cosEphi + norm.y()*sinEphi)/norm.z() - dz;
zmin = std::min(std::min(std::min(z1,z2),z3),z4);
}
// get zmax
// Find Zmax
//
G4double zmax;
norm = GetHighNorm();
xynorm = std::sqrt(norm.x()*norm.x()+norm.y()*norm.y());
znorm = std::abs(norm.z());
G4double zmax = dz + rmax*xynorm/znorm;
mag = std::sqrt(norm.x()*norm.x() + norm.y()*norm.y());
topx = (mag == 0) ? 0 : -rmax*norm.x()/mag;
topy = (mag == 0) ? 0 : -rmax*norm.y()/mag;
dists = sinSphi*topx - cosSphi*topy;
diste = -sinEphi*topx + cosEphi*topy;
if (dphi > pi)
{
iftop = true;
if (dists > 0 && diste > 0) iftop = false;
}
else
{
iftop = false;
if (dists <= 0 && diste <= 0) iftop = true;
}
if (iftop)
{
zmax = -(norm.x()*topx + norm.y()*topy)/norm.z() + dz;
}
else
{
G4double z1 = -rmin*(norm.x()*cosSphi + norm.y()*sinSphi)/norm.z() + dz;
G4double z2 = -rmin*(norm.x()*cosEphi + norm.y()*sinEphi)/norm.z() + dz;
G4double z3 = -rmax*(norm.x()*cosSphi + norm.y()*sinSphi)/norm.z() + dz;
G4double z4 = -rmax*(norm.x()*cosEphi + norm.y()*sinEphi)/norm.z() + dz;
zmax = std::max(std::max(std::max(z1,z2),z3),z4);
}
// Find bounding box
//
if (GetDeltaPhiAngle() < twopi)
if (dphi < twopi)
{
G4TwoVector vmin,vmax;
G4GeomTools::DiskExtent(rmin,rmax,
@@ -558,6 +653,8 @@ G4ThreeVector G4CutTubs::SurfaceNormal( const G4ThreeVector& p ) const
G4ThreeVector G4CutTubs::ApproxSurfaceNormal( const G4ThreeVector& p ) const
{
enum ENorm {kNRMin,kNRMax,kNSPhi,kNEPhi,kNZ};
ENorm side ;
G4ThreeVector norm ;
G4double rho, phi ;
@@ -1216,7 +1313,9 @@ G4double G4CutTubs::DistanceToOut( const G4ThreeVector& p,
const G4bool calcNorm,
G4bool *validNorm,
G4ThreeVector *n ) const
{
{
enum ESide {kNull,kRMin,kRMax,kSPhi,kEPhi,kPZ,kMZ};
ESide side=kNull , sider=kNull, sidephi=kNull ;
G4double snxt=kInfinity, srd=kInfinity,sz=kInfinity, sphi=kInfinity ;
G4double deltaR, t1, t2, t3, b, c, d2, roMin2 ;
@@ -1817,7 +1916,7 @@ G4Polyhedron* G4CutTubs::CreatePolyhedron () const
typedef G4int G4int4[4];
G4Polyhedron *ph = new G4Polyhedron;
G4Polyhedron *ph1 = G4OTubs::CreatePolyhedron();
G4Polyhedron *ph1 = new G4PolyhedronTubs (fRMin, fRMax, fDz, fSPhi, fDPhi);
G4int nn=ph1->GetNoVertices();
G4int nf=ph1->GetNoFacets();
G4double3* xyz = new G4double3[nn]; // number of nodes
@@ -2016,3 +2115,4 @@ void G4CutTubs::GetMaxMinZ(G4double& zmin,G4double& zmax)const
if (in_range_hi) { zmax = std::max(zmax, z1); }
else { zmax = z1; }
}
#endif
File diff suppressed because it is too large Load Diff
+141 -320
View File
@@ -1,4 +1,3 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
@@ -23,7 +22,7 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4Orb.cc 104316 2017-05-24 13:04:23Z gcosmo $
// $Id: G4Orb.cc 105834 2017-08-23 08:14:34Z gcosmo $
//
// class G4Orb
//
@@ -31,12 +30,12 @@
//
// History:
//
// 08.08.17 E.Tcherniaev - complete revision, speed-up
// 27.10.16 E.Tcherniaev - reimplemented CalculateExtent()
// 05.04.12 M.Kelsey - GetPointOnSurface() throw flat in cos(theta)
// 30.06.04 V.Grichine - bug fixed in DistanceToIn(p,v) on Rmax surface
// 20.08.03 V.Grichine - created
//
//////////////////////////////////////////////////////////////
// --------------------------------------------------------------------
#include "G4Orb.hh"
@@ -50,59 +49,36 @@
#include "G4VPVParameterisation.hh"
#include "G4RandomDirection.hh"
#include "Randomize.hh"
#include "meshdefs.hh"
#include "G4VGraphicsScene.hh"
#include "G4VisExtent.hh"
using namespace CLHEP;
// Private enum: Not for external use - used by distanceToOut
enum ESide {kNull,kRMax};
// used by normal
enum ENorm {kNRMax};
////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// constructor - check positive radius
//
// Constructor
G4Orb::G4Orb( const G4String& pName, G4double pRmax )
: G4CSGSolid(pName), fRmax(pRmax)
: G4CSGSolid(pName), fRmax(pRmax)
{
const G4double fEpsilon = 2.e-11; // relative tolerance of fRmax
G4double kRadTolerance
= G4GeometryTolerance::GetInstance()->GetRadialTolerance();
// Check radius
//
if ( pRmax < 10*kCarTolerance )
{
G4Exception("G4Orb::G4Orb()", "GeomSolids0002", FatalException,
"Invalid radius < 10*kCarTolerance.");
}
fRmaxTolerance = std::max( kRadTolerance, fEpsilon*fRmax);
Initialize();
}
///////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// Fake default constructor - sets only member data and allocates memory
// for usage restricted to object persistency.
//
// for usage restricted to object persistency
G4Orb::G4Orb( __void__& a )
: G4CSGSolid(a), fRmax(0.), fRmaxTolerance(0.)
: G4CSGSolid(a), fRmax(0.), halfRmaxTol(0.),
sqrRmaxPlusTol(0.), sqrRmaxMinusTol(0.)
{
}
/////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// Destructor
@@ -115,7 +91,8 @@ G4Orb::~G4Orb()
// Copy constructor
G4Orb::G4Orb(const G4Orb& rhs)
: G4CSGSolid(rhs), fRmax(rhs.fRmax), fRmaxTolerance(rhs.fRmaxTolerance)
: G4CSGSolid(rhs), fRmax(rhs.fRmax), halfRmaxTol(rhs.halfRmaxTol),
sqrRmaxPlusTol(rhs.sqrRmaxPlusTol), sqrRmaxMinusTol(rhs.sqrRmaxMinusTol)
{
}
@@ -123,7 +100,7 @@ G4Orb::G4Orb(const G4Orb& rhs)
//
// Assignment operator
G4Orb& G4Orb::operator = (const G4Orb& rhs)
G4Orb& G4Orb::operator = (const G4Orb& rhs)
{
// Check assignment to self
//
@@ -136,15 +113,39 @@ G4Orb& G4Orb::operator = (const G4Orb& rhs)
// Copy data
//
fRmax = rhs.fRmax;
fRmaxTolerance = rhs.fRmaxTolerance;
halfRmaxTol = rhs.halfRmaxTol;
sqrRmaxPlusTol = rhs.sqrRmaxPlusTol;
sqrRmaxMinusTol = rhs.sqrRmaxMinusTol;
return *this;
}
//////////////////////////////////////////////////////////////////////////
//
// Check radius and initialize dada members
void G4Orb::Initialize()
{
const G4double fEpsilon = 2.e-11; // relative tolerance of fRmax
// Check radius
//
if ( fRmax < 10*kCarTolerance )
{
G4Exception("G4Orb::Initialize()", "GeomSolids0002", FatalException,
"Invalid radius < 10*kCarTolerance.");
}
halfRmaxTol = 0.5 * std::max(kCarTolerance, fEpsilon*fRmax);
G4double rmaxPlusTol = fRmax + halfRmaxTol;
G4double rmaxMinusTol = fRmax - halfRmaxTol;
sqrRmaxPlusTol = rmaxPlusTol*rmaxPlusTol;
sqrRmaxMinusTol = rmaxMinusTol*rmaxMinusTol;
}
//////////////////////////////////////////////////////////////////////////
//
// Dispatch to parameterisation for replication mechanism dimension
// computation & modification.
// computation & modification
void G4Orb::ComputeDimensions( G4VPVParameterisation* p,
const G4int n,
@@ -172,7 +173,8 @@ void G4Orb::BoundingLimits(G4ThreeVector& pMin, G4ThreeVector& pMax) const
<< GetName() << " !"
<< "\npMin = " << pMin
<< "\npMax = " << pMax;
G4Exception("G4Orb::BoundingLimits()", "GeomMgt0001", JustWarning, message);
G4Exception("G4Orb::BoundingLimits()", "GeomMgt0001",
JustWarning, message);
DumpInfo();
}
}
@@ -260,166 +262,86 @@ G4bool G4Orb::CalculateExtent(const EAxis pAxis,
return exist;
}
///////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// Return whether point inside/outside/on surface
// Split into radius checks
//
// Return whether point is inside/outside/on surface
EInside G4Orb::Inside( const G4ThreeVector& p ) const
{
G4double rad2,tolRMax;
EInside in;
rad2 = p.x()*p.x()+p.y()*p.y()+p.z()*p.z();
G4double radius = std::sqrt(rad2);
// G4double radius = std::sqrt(rad2);
// Check radial surface
// sets `in'
tolRMax = fRmax - fRmaxTolerance*0.5;
if ( radius <= tolRMax ) { in = kInside; }
else
{
tolRMax = fRmax + fRmaxTolerance*0.5;
if ( radius <= tolRMax ) { in = kSurface; }
else { in = kOutside; }
}
return in;
G4double rr = p.mag2();
if (rr > sqrRmaxPlusTol) return kOutside;
return (rr > sqrRmaxMinusTol) ? kSurface : kInside;
}
/////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// Return unit normal of surface closest to p
G4ThreeVector G4Orb::SurfaceNormal( const G4ThreeVector& p ) const
{
G4double radius = std::sqrt(p.x()*p.x()+p.y()*p.y()+p.z()*p.z());
return G4ThreeVector(p.x()/radius,p.y()/radius,p.z()/radius);
return (1/p.mag())*p;
}
///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// Calculate distance to shape from outside, along normalised vector
// - return kInfinity if no intersection, or intersection distance <= tolerance
//
// -> If point is outside outer radius, compute intersection with rmax
// - if no intersection return
// - if valid phi,theta return intersection Dist
// Calculate distance to the surface of the orb from outside
// - return kInfinity if no intersection or
// intersection distance <= tolerance
G4double G4Orb::DistanceToIn( const G4ThreeVector& p,
const G4ThreeVector& v ) const
{
G4double snxt = kInfinity; // snxt = default return value
G4double radius, pDotV3d; // , tolORMax2, tolIRMax2;
G4double c, d2, sd = kInfinity;
const G4double dRmax = 100.*fRmax;
// General Precalcs
radius = std::sqrt(p.x()*p.x() + p.y()*p.y() + p.z()*p.z());
pDotV3d = p.x()*v.x() + p.y()*v.y() + p.z()*v.z();
// Radial Precalcs
// tolORMax2 = (fRmax+fRmaxTolerance*0.5)*(fRmax+fRmaxTolerance*0.5);
// tolIRMax2 = (fRmax-fRmaxTolerance*0.5)*(fRmax-fRmaxTolerance*0.5);
// Outer spherical shell intersection
// - Only if outside tolerant fRmax
// - Check for if inside and outer G4Orb heading through solid (-> 0)
// - No intersect -> no intersection with G4Orb
// Check if point is on the surface and traveling away
//
// Shell eqn: x^2+y^2+z^2 = RSPH^2
//
// => (px+svx)^2+(py+svy)^2+(pz+svz)^2=R^2
//
// => (px^2+py^2+pz^2) +2sd(pxvx+pyvy+pzvz)+sd^2(vx^2+vy^2+vz^2)=R^2
// => rad2 +2sd(pDotV3d) +sd^2 =R^2
//
// => sd=-pDotV3d+-std::sqrt(pDotV3d^2-(rad2-R^2))
G4double rr = p.mag2();
G4double pv = p.dot(v);
if (rr >= sqrRmaxMinusTol && pv >= 0) return kInfinity;
c = (radius - fRmax)*(radius + fRmax);
// Find intersection
//
// Sphere eqn: x^2 + y^2 + z^2 = R^2
//
// => (px + t*vx)^2 + (py + t*vy)^2 + (pz + t*vz)^2 = R^2
// => r^2 + 2t(p.v) + t^2 = R^2
// => tmin = -(p.v) - Sqrt((p.v)^2 - (r^2 - R^2))
//
G4double D = pv*pv - rr + fRmax*fRmax;
if (D < 0) return kInfinity; // no intersection
if( radius > fRmax-fRmaxTolerance*0.5 ) // not inside in terms of Inside(p)
G4double sqrtD = std::sqrt(D);
G4double tmin = -pv - sqrtD;
// Avoid rounding errors due to precision issues seen on 64 bits systems.
// Split long distances and recompute
//
G4double Dmax = 32*fRmax;
if (tmin > Dmax)
{
if ( c > fRmaxTolerance*fRmax )
{
// If outside tolerant boundary of outer G4Orb in terms of c
// [ should be std::sqrt(rad2) - fRmax > fRmaxTolerance*0.5 ]
d2 = pDotV3d*pDotV3d - c;
if ( d2 >= 0 )
{
sd = -pDotV3d - std::sqrt(d2);
if ( sd >= 0 )
{
if ( sd > dRmax ) // Avoid rounding errors due to precision issues seen on
{ // 64 bits systems. Split long distances and recompute
G4double fTerm = sd - std::fmod(sd,dRmax);
sd = fTerm + DistanceToIn(p+fTerm*v,v);
}
return snxt = sd;
}
}
else // No intersection with G4Orb
{
return snxt = kInfinity;
}
}
else // not outside in terms of c
{
if ( c > -fRmaxTolerance*fRmax ) // on surface
{
d2 = pDotV3d*pDotV3d - c;
if ( (d2 < fRmaxTolerance*fRmax) || (pDotV3d >= 0) )
{
return snxt = kInfinity;
}
else
{
return snxt = 0.;
}
}
}
G4double tadd = tmin - Dmax + fRmax;
tadd += DistanceToIn(p + tadd*v, v);
return (tadd >= kInfinity) ? kInfinity : tadd;
}
#ifdef G4CSGDEBUG
else // inside ???
{
G4Exception("G4Orb::DistanceToIn(p,v)", "GeomSolids1002",
JustWarning, "Point p is inside !?");
}
#endif
return snxt;
if (sqrtD*2 <= halfRmaxTol) return kInfinity; // touch
return (tmin < halfRmaxTol) ? 0. : tmin;
}
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// Calculate distance (<= actual) to closest surface of shape from outside
// - Calculate distance to radial plane
// - Return 0 if point inside
// Calculate shortest distance to the boundary from outside
// - Return 0 if point is inside
G4double G4Orb::DistanceToIn( const G4ThreeVector& p ) const
{
G4double safe = 0.0,
radius = std::sqrt(p.x()*p.x()+p.y()*p.y()+p.z()*p.z());
safe = radius - fRmax;
if( safe < 0 ) { safe = 0.; }
return safe;
G4double dist = p.mag() - fRmax;
return (dist > 0) ? dist : 0.;
}
/////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// Calculate distance to surface of shape from `inside', allowing for tolerance
//
// Calculate distance to the surface of the orb from inside and
// find normal at exit point, if required
// - when leaving the surface, return 0
G4double G4Orb::DistanceToOut( const G4ThreeVector& p,
const G4ThreeVector& v,
@@ -427,157 +349,64 @@ G4double G4Orb::DistanceToOut( const G4ThreeVector& p,
G4bool *validNorm,
G4ThreeVector *n ) const
{
G4double snxt = kInfinity; // ??? snxt is default return value
ESide side = kNull;
G4double rad2,pDotV3d;
G4double xi,yi,zi; // Intersection point
G4double c,d2;
rad2 = p.x()*p.x() + p.y()*p.y() + p.z()*p.z();
pDotV3d = p.x()*v.x() + p.y()*v.y() + p.z()*v.z();
// Radial Intersection from G4Orb::DistanceToIn
// Check if point is on the surface and traveling away
//
// Outer spherical shell intersection
// - Only if outside tolerant fRmax
// - Check for if inside and outer G4Orb heading through solid (-> 0)
// - No intersect -> no intersection with G4Orb
//
// Shell eqn: x^2+y^2+z^2=RSPH^2
//
// => (px+svx)^2+(py+svy)^2+(pz+svz)^2=R^2
//
// => (px^2+py^2+pz^2) +2s(pxvx+pyvy+pzvz)+s^2(vx^2+vy^2+vz^2)=R^2
// => rad2 +2s(pDotV3d) +s^2 =R^2
//
// => s=-pDotV3d+-std::sqrt(pDotV3d^2-(rad2-R^2))
const G4double Rmax_plus = fRmax + fRmaxTolerance*0.5;
G4double radius = std::sqrt(rad2);
if ( radius <= Rmax_plus )
G4double rr = p.mag2();
G4double pv = p.dot(v);
if (rr >= sqrRmaxMinusTol && pv > 0)
{
c = (radius - fRmax)*(radius + fRmax);
if ( c < fRmaxTolerance*fRmax )
if (calcNorm)
{
// Within tolerant Outer radius
//
// The test is
// radius - fRmax < 0.5*fRmaxTolerance
// => radius < fRmax + 0.5*kRadTol
// => rad2 < (fRmax + 0.5*kRadTol)^2
// => rad2 < fRmax^2 + 2.*0.5*fRmax*kRadTol + 0.25*kRadTol*kRadTol
// => rad2 - fRmax^2 <~ fRmax*kRadTol
d2 = pDotV3d*pDotV3d - c;
if( ( c > -fRmaxTolerance*fRmax) && // on tolerant surface
( ( pDotV3d >= 0 ) || ( d2 < 0 )) ) // leaving outside from Rmax
// not re-entering
{
if(calcNorm)
{
*validNorm = true;
*n = G4ThreeVector(p.x()/fRmax,p.y()/fRmax,p.z()/fRmax);
}
return snxt = 0;
}
else
{
snxt = -pDotV3d + std::sqrt(d2); // second root since inside Rmax
side = kRMax;
}
*validNorm = true;
*n = p*(1./std::sqrt(rr));
}
return 0.;
}
else // p is outside ???
// Find intersection
//
// Sphere eqn: x^2 + y^2 + z^2 = R^2
//
// => (px + t*vx)^2 + (py + t*vy)^2 + (pz + t*vz)^2 = R^2
// => r^2 + 2t(p.v) + t^2 = R^2
// => tmax = -(p.v) + Sqrt((p.v)^2 - (r^2 - R^2))
//
G4double D = pv*pv - rr + fRmax*fRmax;
G4double tmax = (D <= 0) ? 0. : std::sqrt(D) - pv;
if (tmax < halfRmaxTol) tmax = 0.;
if (calcNorm)
{
G4cout << G4endl;
DumpInfo();
std::ostringstream message;
G4int oldprc = message.precision(16);
message << "Logic error: snxt = kInfinity ???" << G4endl
<< "Position:" << G4endl << G4endl
<< "p.x() = " << p.x()/mm << " mm" << G4endl
<< "p.y() = " << p.y()/mm << " mm" << G4endl
<< "p.z() = " << p.z()/mm << " mm" << G4endl << G4endl
<< "Rp = "<< std::sqrt( p.x()*p.x()+p.y()*p.y()+p.z()*p.z() )/mm
<< " mm" << G4endl << G4endl
<< "Direction:" << G4endl << G4endl
<< "v.x() = " << v.x() << G4endl
<< "v.y() = " << v.y() << G4endl
<< "v.z() = " << v.z() << G4endl << G4endl
<< "Proposed distance :" << G4endl << G4endl
<< "snxt = " << snxt/mm << " mm" << G4endl;
message.precision(oldprc);
G4Exception("G4Orb::DistanceToOut(p,v,..)", "GeomSolids1002",
JustWarning, message);
*validNorm = true;
G4ThreeVector ptmax = p + tmax*v;
*n = ptmax*(1./ptmax.mag());
}
if (calcNorm) // Output switch operator
{
switch( side )
{
case kRMax:
xi=p.x()+snxt*v.x();
yi=p.y()+snxt*v.y();
zi=p.z()+snxt*v.z();
*n=G4ThreeVector(xi/fRmax,yi/fRmax,zi/fRmax);
*validNorm=true;
break;
default:
G4cout << G4endl;
DumpInfo();
std::ostringstream message;
G4int oldprc = message.precision(16);
message << "Undefined side for valid surface normal to solid."
<< G4endl
<< "Position:" << G4endl << G4endl
<< "p.x() = " << p.x()/mm << " mm" << G4endl
<< "p.y() = " << p.y()/mm << " mm" << G4endl
<< "p.z() = " << p.z()/mm << " mm" << G4endl << G4endl
<< "Direction:" << G4endl << G4endl
<< "v.x() = " << v.x() << G4endl
<< "v.y() = " << v.y() << G4endl
<< "v.z() = " << v.z() << G4endl << G4endl
<< "Proposed distance :" << G4endl << G4endl
<< "snxt = " << snxt/mm << " mm" << G4endl;
message.precision(oldprc);
G4Exception("G4Orb::DistanceToOut(p,v,..)","GeomSolids1002",
JustWarning, message);
break;
}
}
return snxt;
return tmax;
}
/////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// Calculate distance (<=actual) to closest surface of shape from inside
G4double G4Orb::DistanceToOut( const G4ThreeVector& p ) const
{
G4double safe=0.0,radius = std::sqrt(p.x()*p.x()+p.y()*p.y()+p.z()*p.z());
#ifdef G4CSGDEBUG
if( Inside(p) == kOutside )
{
G4int oldprc = G4cout.precision(16);
G4cout << G4endl;
DumpInfo();
G4cout << "Position:" << G4endl << G4endl;
G4cout << "p.x() = " << p.x()/mm << " mm" << G4endl;
G4cout << "p.y() = " << p.y()/mm << " mm" << G4endl;
G4cout << "p.z() = " << p.z()/mm << " mm" << G4endl << G4endl;
G4cout.precision(oldprc);
G4Exception("G4Orb::DistanceToOut(p)", "GeomSolids1002",
JustWarning, "Point p is outside !?" );
std::ostringstream message;
G4int oldprc = message.precision(16);
message << "Point p is outside (!?) of solid: " << GetName() << "\n";
message << "Position:\n";
message << " p.x() = " << p.x()/mm << " mm\n";
message << " p.y() = " << p.y()/mm << " mm\n";
message << " p.z() = " << p.z()/mm << " mm";
G4cout.precision(oldprc);
G4Exception("G4Trap::DistanceToOut(p)", "GeomSolids1002",
JustWarning, message );
DumpInfo();
}
#endif
safe = fRmax - radius;
if ( safe < 0. ) safe = 0.;
return safe;
G4double dist = fRmax - p.mag();
return (dist > 0) ? dist : 0.;
}
//////////////////////////////////////////////////////////////////////////
@@ -592,7 +421,7 @@ G4GeometryType G4Orb::GetEntityType() const
//////////////////////////////////////////////////////////////////////////
//
// Make a clone of the object
//
G4VSolid* G4Orb::Clone() const
{
return new G4Orb(*this);
@@ -610,35 +439,22 @@ std::ostream& G4Orb::StreamInfo( std::ostream& os ) const
<< " ===================================================\n"
<< " Solid type: G4Orb\n"
<< " Parameters: \n"
<< " outer radius: " << fRmax/mm << " mm \n"
<< "-----------------------------------------------------------\n";
os.precision(oldprc);
return os;
}
/////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// GetPointOnSurface
G4ThreeVector G4Orb::GetPointOnSurface() const
{
// generate a random number from zero to 2pi...
//
G4double phi = G4RandFlat::shoot(0.,2.*pi);
G4double cosphi = std::cos(phi);
G4double sinphi = std::sin(phi);
// generate a random point uniform in area
G4double costheta = G4RandFlat::shoot(-1.,1.);
G4double sintheta = std::sqrt(1.-sqr(costheta));
return G4ThreeVector (fRmax*sintheta*cosphi,
fRmax*sintheta*sinphi, fRmax*costheta);
return fRmax * G4RandomDirection();
}
////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// Methods for visualisation
@@ -647,6 +463,11 @@ void G4Orb::DescribeYourselfTo ( G4VGraphicsScene& scene ) const
scene.AddSolid (*this);
}
G4VisExtent G4Orb::GetExtent() const
{
return G4VisExtent (-fRmax, fRmax, -fRmax, fRmax, -fRmax, fRmax);
}
G4Polyhedron* G4Orb::CreatePolyhedron () const
{
return new G4PolyhedronSphere (0., fRmax, 0., 2*pi, 0., pi);
+21 -9
View File
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4Para.cc 104452 2017-05-31 15:41:24Z gcosmo $
// $Id: G4Para.cc 107555 2017-11-22 15:26:59Z gcosmo $
//
// class G4Para
//
@@ -48,6 +48,8 @@
#include "G4Para.hh"
#if !defined(G4GEOM_USE_UPARA)
#include "G4VoxelLimits.hh"
#include "G4AffineTransform.hh"
#include "G4BoundingEnvelope.hh"
@@ -427,10 +429,10 @@ G4bool G4Para::CalculateExtent( const EAxis pAxis,
EInside G4Para::Inside( const G4ThreeVector& p ) const
{
G4double xx = fPlanes[2].a*p.x()+fPlanes[2].b*p.y()+fPlanes[2].c*p.z();
G4double dx = std::max(xx,-xx) + fPlanes[2].d;
G4double dx = std::abs(xx) + fPlanes[2].d;
G4double yy = fPlanes[0].b*p.y()+fPlanes[0].c*p.z();
G4double dy = std::max(yy,-yy) + fPlanes[0].d;
G4double dy = std::abs(yy) + fPlanes[0].d;
G4double dxy = std::max(dx,dy);
G4double dz = std::abs(p.z())-fDz;
@@ -446,11 +448,17 @@ EInside G4Para::Inside( const G4ThreeVector& p ) const
G4ThreeVector G4Para::SurfaceNormal( const G4ThreeVector& p ) const
{
G4int nsurf = 0; // number of surfaces where p is placed
// Check Z faces
//
G4double nz = 0;
G4double dz = std::abs(p.z()) - fDz;
if (std::abs(dz) <= halfCarTolerance) nz = (p.z() < 0) ? -1 : 1;
if (std::abs(dz) <= halfCarTolerance)
{
nz = (p.z() < 0) ? -1 : 1;
++nsurf;
}
// Check Y faces
//
@@ -460,11 +468,13 @@ G4ThreeVector G4Para::SurfaceNormal( const G4ThreeVector& p ) const
{
ny = fPlanes[0].b;
nz += fPlanes[0].c;
++nsurf;
}
else if (std::abs(fPlanes[1].d - yy) <= halfCarTolerance)
{
ny = fPlanes[1].b;
nz += fPlanes[1].c;
++nsurf;
}
// Check X faces
@@ -476,17 +486,18 @@ G4ThreeVector G4Para::SurfaceNormal( const G4ThreeVector& p ) const
nx = fPlanes[2].a;
ny += fPlanes[2].b;
nz += fPlanes[2].c;
++nsurf;
}
else if (std::abs(fPlanes[3].d - xx) <= halfCarTolerance)
{
nx = fPlanes[3].a;
ny += fPlanes[3].b;
nz += fPlanes[3].c;
++nsurf;
}
// Return normal
//
G4int nsurf = nx*nx + ny*ny + nz*nz + 0.5; // get magnitude
if (nsurf == 1) return G4ThreeVector(nx,ny,nz);
else if (nsurf != 0) return G4ThreeVector(nx,ny,nz).unit(); // edge or corner
else
@@ -633,10 +644,10 @@ G4double G4Para::DistanceToIn(const G4ThreeVector& p,
G4double G4Para::DistanceToIn( const G4ThreeVector& p ) const
{
G4double xx = fPlanes[2].a*p.x()+fPlanes[2].b*p.y()+fPlanes[2].c*p.z();
G4double dx = std::max(xx,-xx) + fPlanes[2].d;
G4double dx = std::abs(xx) + fPlanes[2].d;
G4double yy = fPlanes[0].b*p.y()+fPlanes[0].c*p.z();
G4double dy = std::max(yy,-yy) + fPlanes[0].d;
G4double dy = std::abs(yy) + fPlanes[0].d;
G4double dxy = std::max(dx,dy);
G4double dz = std::abs(p.z())-fDz;
@@ -779,10 +790,10 @@ G4double G4Para::DistanceToOut( const G4ThreeVector& p ) const
}
#endif
G4double xx = fPlanes[2].a*p.x()+fPlanes[2].b*p.y()+fPlanes[2].c*p.z();
G4double dx = std::max(xx,-xx) + fPlanes[2].d;
G4double dx = std::abs(xx) + fPlanes[2].d;
G4double yy = fPlanes[0].b*p.y()+fPlanes[0].c*p.z();
G4double dy = std::max(yy,-yy) + fPlanes[0].d;
G4double dy = std::abs(yy) + fPlanes[0].d;
G4double dxy = std::max(dx,dy);
G4double dz = std::abs(p.z())-fDz;
@@ -910,3 +921,4 @@ G4Polyhedron* G4Para::CreatePolyhedron () const
return new G4PolyhedronPara(fDx, fDy, fDz, alpha, theta, phi);
}
#endif
+218 -128
View File
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4Trap.cc 104561 2017-06-06 07:54:54Z gcosmo $
// $Id: G4Trap.cc 107555 2017-11-22 15:26:59Z gcosmo $
//
// class G4Trap
//
@@ -421,6 +421,15 @@ void G4Trap::MakePlanes(const G4ThreeVector pt[8])
fPlanes[2].a = -fPlanes[3].a;
fPlanes[2].c = fPlanes[3].c;
}
if (std::abs(fPlanes[2].a + fPlanes[3].a) < DBL_EPSILON &&
std::abs(fPlanes[2].b - fPlanes[3].b) < DBL_EPSILON &&
fPlanes[2].c == 0 &&
fPlanes[3].c == 0)
{
fTrapType = 3; // ... and XY section is a isosceles trapezoid
fPlanes[2].a = -fPlanes[3].a;
fPlanes[2].b = fPlanes[3].b;
}
}
}
@@ -612,43 +621,64 @@ G4bool G4Trap::CalculateExtent( const EAxis pAxis,
///////////////////////////////////////////////////////////////////////
//
// Return whether point inside/outside/on surface, using tolerance
// Return whether point is inside/outside/on_surface
EInside G4Trap::Inside( const G4ThreeVector& p ) const
{
if (fTrapType == 2) // YZ section is a rectangle and
{ // XZ section is an isosceles trapezoid
G4double dy = std::max(std::abs(p.z())-fDz,std::abs(p.y())+fPlanes[1].d);
G4double dx = fPlanes[3].a*std::abs(p.x())+fPlanes[3].c*p.z()+fPlanes[3].d;
G4double dist = std::max(dy,dx);
G4double dz = std::abs(p.z())-fDz;
if (dz > halfCarTolerance) return kOutside;
if (dist > halfCarTolerance) return kOutside;
return (dist > -halfCarTolerance) ? kSurface : kInside;
}
else if (fTrapType == 1) // YZ section is a rectangle
switch (fTrapType)
{
G4double dy = std::max(std::abs(p.z())-fDz,std::abs(p.y())+fPlanes[1].d);
G4double dx1 = fPlanes[2].a*p.x()+fPlanes[2].b*p.y()+fPlanes[2].c*p.z()+fPlanes[2].d;
G4double dx2 = fPlanes[3].a*p.x()+fPlanes[3].b*p.y()+fPlanes[3].c*p.z()+fPlanes[3].d;
G4double dist = std::max(dy,std::max(dx1,dx2));
case 0: // General case
{
G4double dy1 = fPlanes[0].b*p.y()+fPlanes[0].c*p.z()+fPlanes[0].d;
G4double dy2 = fPlanes[1].b*p.y()+fPlanes[1].c*p.z()+fPlanes[1].d;
G4double dy = std::max(dz,std::max(dy1,dy2));
if (dist > halfCarTolerance) return kOutside;
return (dist > -halfCarTolerance) ? kSurface : kInside;
}
else // General case
{
G4double dz = std::abs(p.z())-fDz;
G4double dy1 = fPlanes[0].b*p.y()+fPlanes[0].c*p.z()+fPlanes[0].d;
G4double dy2 = fPlanes[1].b*p.y()+fPlanes[1].c*p.z()+fPlanes[1].d;
G4double dy = std::max(dz,std::max(dy1,dy2));
G4double dx1 = fPlanes[2].a*p.x()+fPlanes[2].b*p.y()+fPlanes[2].c*p.z()+fPlanes[2].d;
G4double dx2 = fPlanes[3].a*p.x()+fPlanes[3].b*p.y()+fPlanes[3].c*p.z()+fPlanes[3].d;
G4double dist = std::max(dy,std::max(dx1,dx2));
if (dist > halfCarTolerance) return kOutside;
return (dist > -halfCarTolerance) ? kSurface : kInside;
G4double dx1 = fPlanes[2].a*p.x()+fPlanes[2].b*p.y()
+ fPlanes[2].c*p.z()+fPlanes[2].d;
G4double dx2 = fPlanes[3].a*p.x()+fPlanes[3].b*p.y()
+ fPlanes[3].c*p.z()+fPlanes[3].d;
G4double dist = std::max(dy,std::max(dx1,dx2));
if (dist > halfCarTolerance) return kOutside;
return (dist > -halfCarTolerance) ? kSurface : kInside;
}
case 1: // YZ section is a rectangle
{
G4double dy = std::max(dz,std::abs(p.y())+fPlanes[1].d);
G4double dx1 = fPlanes[2].a*p.x()+fPlanes[2].b*p.y()
+ fPlanes[2].c*p.z()+fPlanes[2].d;
G4double dx2 = fPlanes[3].a*p.x()+fPlanes[3].b*p.y()
+ fPlanes[3].c*p.z()+fPlanes[3].d;
G4double dist = std::max(dy,std::max(dx1,dx2));
if (dist > halfCarTolerance) return kOutside;
return (dist > -halfCarTolerance) ? kSurface : kInside;
}
case 2: // YZ section is a rectangle and
{ // XZ section is an isosceles trapezoid
G4double dy = std::max(dz,std::abs(p.y())+fPlanes[1].d);
G4double dx = fPlanes[3].a*std::abs(p.x())
+ fPlanes[3].c*p.z()+fPlanes[3].d;
G4double dist = std::max(dy,dx);
if (dist > halfCarTolerance) return kOutside;
return (dist > -halfCarTolerance) ? kSurface : kInside;
}
case 3: // YZ section is a rectangle and
{ // XY section is an isosceles trapezoid
G4double dy = std::max(dz,std::abs(p.y())+fPlanes[1].d);
G4double dx = fPlanes[3].a*std::abs(p.x())
+ fPlanes[3].b*p.y()+fPlanes[3].d;
G4double dist = std::max(dy,dx);
if (dist > halfCarTolerance) return kOutside;
return (dist > -halfCarTolerance) ? kSurface : kInside;
}
}
return kOutside;
}
///////////////////////////////////////////////////////////////////////
@@ -657,64 +687,90 @@ EInside G4Trap::Inside( const G4ThreeVector& p ) const
G4ThreeVector G4Trap::SurfaceNormal( const G4ThreeVector& p ) const
{
// Check Z faces
//
G4double nz = 0;
if (std::abs(std::abs(p.z()) - fDz) <= halfCarTolerance)
G4int nsurf = 0; // number of surfaces where p is placed
G4double nx = 0, ny = 0, nz = 0;
G4double dz = std::abs(p.z()) - fDz;
if (std::abs(dz) <= halfCarTolerance)
{
nz = (p.z() < 0) ? -1 : 1;
++nsurf;
}
// Check Y faces
//
G4double ny = 0;
if (fTrapType > 0) // YZ section is a rectangle
switch (fTrapType)
{
G4double dist = std::abs(p.y()) + fPlanes[1].d;
if (std::abs(dist) <= halfCarTolerance) ny = (p.y() < 0) ? -1 : 1;
}
else
{
for (G4int i=0; i<2; ++i)
case 0: // General case
{
G4double dist = fPlanes[i].b*p.y() + fPlanes[i].c*p.z() + fPlanes[i].d;
if (std::abs(dist) > halfCarTolerance) continue;
ny = fPlanes[i].b;
nz += fPlanes[i].c;
for (G4int i=0; i<2; ++i)
{
G4double dy = fPlanes[i].b*p.y() + fPlanes[i].c*p.z() + fPlanes[i].d;
if (std::abs(dy) > halfCarTolerance) continue;
ny = fPlanes[i].b;
nz += fPlanes[i].c;
++nsurf;
break;
}
for (G4int i=2; i<4; ++i)
{
G4double dx = fPlanes[i].a*p.x() +
fPlanes[i].b*p.y() + fPlanes[i].c*p.z() + fPlanes[i].d;
if (std::abs(dx) > halfCarTolerance) continue;
nx = fPlanes[i].a;
ny += fPlanes[i].b;
nz += fPlanes[i].c;
++nsurf;
break;
}
break;
}
}
// Check X faces
//
G4double nx = 0;
if (fTrapType == 2) // YZ section is a rectangle and
{ // XZ section is an isosceles trapezoid
G4double dist = fPlanes[3].a*std::abs(p.x())
+ fPlanes[3].c*p.z() + fPlanes[3].d;
if (std::abs(dist) <= halfCarTolerance)
case 1: // YZ section is a rectangle
{
nx = (p.x() < 0) ? -fPlanes[3].a : fPlanes[3].a;
nz += fPlanes[3].c;
}
}
else
{
for (G4int i=2; i<4; ++i)
{
G4double dist = fPlanes[i].a*p.x() +
G4double dy = std::abs(p.y()) + fPlanes[1].d;
if (std::abs(dy) <= halfCarTolerance) ny = (p.y() < 0) ? -1 : 1;
for (G4int i=2; i<4; ++i)
{
G4double dx = fPlanes[i].a*p.x() +
fPlanes[i].b*p.y() + fPlanes[i].c*p.z() + fPlanes[i].d;
if (std::abs(dist) > halfCarTolerance) continue;
nx = fPlanes[i].a;
ny += fPlanes[i].b;
nz += fPlanes[i].c;
if (std::abs(dx) > halfCarTolerance) continue;
nx = fPlanes[i].a;
ny += fPlanes[i].b;
nz += fPlanes[i].c;
++nsurf;
break;
}
break;
}
case 2: // YZ section is a rectangle and
{ // XZ section is an isosceles trapezoid
G4double dy = std::abs(p.y()) + fPlanes[1].d;
if (std::abs(dy) <= halfCarTolerance) ny = (p.y() < 0) ? -1 : 1;
G4double dx = fPlanes[3].a*std::abs(p.x()) +
fPlanes[3].c*p.z() + fPlanes[3].d;
if (std::abs(dx) <= halfCarTolerance)
{
nx = (p.x() < 0) ? -fPlanes[3].a : fPlanes[3].a;
nz += fPlanes[3].c;
++nsurf;
}
break;
}
case 3: // YZ section is a rectangle and
{ // XY section is an isosceles trapezoid
G4double dy = std::abs(p.y()) + fPlanes[1].d;
if (std::abs(dy) <= halfCarTolerance) ny = (p.y() < 0) ? -1 : 1;
G4double dx = fPlanes[3].a*std::abs(p.x()) +
fPlanes[3].b*p.y() + fPlanes[3].d;
if (std::abs(dx) <= halfCarTolerance)
{
nx = (p.x() < 0) ? -fPlanes[3].a : fPlanes[3].a;
ny += fPlanes[3].b;
++nsurf;
}
break;
}
}
// Return normal
//
G4int nsurf = nx*nx + ny*ny + nz*nz + 0.5; // get magnitude
if (nsurf == 1) return G4ThreeVector(nx,ny,nz);
else if (nsurf != 0) return G4ThreeVector(nx,ny,nz).unit(); // edge or corner
else
@@ -835,40 +891,57 @@ G4double G4Trap::DistanceToIn(const G4ThreeVector& p,
//
// Calculate exact shortest distance to any boundary from outside
// This is the best fast estimation of the shortest distance to trap
// - Returns 0 is ThreeVector inside
// - return 0 if point is inside
G4double G4Trap::DistanceToIn( const G4ThreeVector& p ) const
{
if (fTrapType == 2) // YZ section is a rectangle and
{ // XZ section is an isosceles trapezoid
G4double dy = std::max(std::abs(p.z())-fDz,std::abs(p.y())+fPlanes[1].d);
G4double dx = fPlanes[3].a*std::abs(p.x())+fPlanes[3].c*p.z()+fPlanes[3].d;
G4double dist = std::max(dy,dx);
return (dist > 0) ? dist : 0.;
}
else if (fTrapType == 1) // YZ section is a rectangle
switch (fTrapType)
{
G4double dy = std::max(std::abs(p.z())-fDz,std::abs(p.y())+fPlanes[1].d);
G4double dx1 = fPlanes[2].a*p.x()+fPlanes[2].b*p.y()+fPlanes[2].c*p.z()+fPlanes[2].d;
G4double dx2 = fPlanes[3].a*p.x()+fPlanes[3].b*p.y()+fPlanes[3].c*p.z()+fPlanes[3].d;
G4double dist = std::max(dy,std::max(dx1,dx2));
case 0: // General case
{
G4double dz = std::abs(p.z())-fDz;
G4double dy1 = fPlanes[0].b*p.y()+fPlanes[0].c*p.z()+fPlanes[0].d;
G4double dy2 = fPlanes[1].b*p.y()+fPlanes[1].c*p.z()+fPlanes[1].d;
G4double dy = std::max(dz,std::max(dy1,dy2));
return (dist > 0) ? dist : 0.;
}
else // General case
{
G4double dz = std::abs(p.z())-fDz;
G4double dy1 = fPlanes[0].b*p.y()+fPlanes[0].c*p.z()+fPlanes[0].d;
G4double dy2 = fPlanes[1].b*p.y()+fPlanes[1].c*p.z()+fPlanes[1].d;
G4double dy = std::max(dz,std::max(dy1,dy2));
G4double dx1 = fPlanes[2].a*p.x()+fPlanes[2].b*p.y()+fPlanes[2].c*p.z()+fPlanes[2].d;
G4double dx2 = fPlanes[3].a*p.x()+fPlanes[3].b*p.y()+fPlanes[3].c*p.z()+fPlanes[3].d;
G4double dist = std::max(dy,std::max(dx1,dx2));
return (dist > 0) ? dist : 0.;
G4double dx1 = fPlanes[2].a*p.x()+fPlanes[2].b*p.y()
+ fPlanes[2].c*p.z()+fPlanes[2].d;
G4double dx2 = fPlanes[3].a*p.x()+fPlanes[3].b*p.y()
+ fPlanes[3].c*p.z()+fPlanes[3].d;
G4double dist = std::max(dy,std::max(dx1,dx2));
return (dist > 0) ? dist : 0.;
}
case 1: // YZ section is a rectangle
{
G4double dz = std::abs(p.z())-fDz;
G4double dy = std::max(dz,std::abs(p.y())+fPlanes[1].d);
G4double dx1 = fPlanes[2].a*p.x()+fPlanes[2].b*p.y()
+ fPlanes[2].c*p.z()+fPlanes[2].d;
G4double dx2 = fPlanes[3].a*p.x()+fPlanes[3].b*p.y()
+ fPlanes[3].c*p.z()+fPlanes[3].d;
G4double dist = std::max(dy,std::max(dx1,dx2));
return (dist > 0) ? dist : 0.;
}
case 2: // YZ section is a rectangle and
{ // XZ section is an isosceles trapezoid
G4double dz = std::abs(p.z())-fDz;
G4double dy = std::max(dz,std::abs(p.y())+fPlanes[1].d);
G4double dx = fPlanes[3].a*std::abs(p.x())
+ fPlanes[3].c*p.z()+fPlanes[3].d;
G4double dist = std::max(dy,dx);
return (dist > 0) ? dist : 0.;
}
case 3: // YZ section is a rectangle and
{ // XY section is an isosceles trapezoid
G4double dz = std::abs(p.z())-fDz;
G4double dy = std::max(dz,std::abs(p.y())+fPlanes[1].d);
G4double dx = fPlanes[3].a*std::abs(p.x())
+ fPlanes[3].b*p.y()+fPlanes[3].d;
G4double dist = std::max(dy,dx);
return (dist > 0) ? dist : 0.;
}
}
return 0.;
}
////////////////////////////////////////////////////////////////////////////
@@ -978,36 +1051,53 @@ G4double G4Trap::DistanceToOut( const G4ThreeVector& p ) const
DumpInfo();
}
#endif
if (fTrapType == 2) // YZ section is a rectangle and
{ // XZ section is an isosceles trapezoid
G4double dy = std::max(std::abs(p.z())-fDz,std::abs(p.y())+fPlanes[1].d);
G4double dx = fPlanes[3].a*std::abs(p.x())+fPlanes[3].c*p.z()+fPlanes[3].d;
G4double dist = std::max(dy,dx);
return (dist < 0) ? -dist : 0.;
}
else if (fTrapType == 1) // YZ section is a rectangle
switch (fTrapType)
{
G4double dy = std::max(std::abs(p.z())-fDz,std::abs(p.y())+fPlanes[1].d);
G4double dx1 = fPlanes[2].a*p.x()+fPlanes[2].b*p.y()+fPlanes[2].c*p.z()+fPlanes[2].d;
G4double dx2 = fPlanes[3].a*p.x()+fPlanes[3].b*p.y()+fPlanes[3].c*p.z()+fPlanes[3].d;
G4double dist = std::max(dy,std::max(dx1,dx2));
case 0: // General case
{
G4double dz = std::abs(p.z())-fDz;
G4double dy1 = fPlanes[0].b*p.y()+fPlanes[0].c*p.z()+fPlanes[0].d;
G4double dy2 = fPlanes[1].b*p.y()+fPlanes[1].c*p.z()+fPlanes[1].d;
G4double dy = std::max(dz,std::max(dy1,dy2));
return (dist < 0) ? -dist : 0.;
}
else // General case
{
G4double dz = std::abs(p.z())-fDz;
G4double dy1 = fPlanes[0].b*p.y()+fPlanes[0].c*p.z()+fPlanes[0].d;
G4double dy2 = fPlanes[1].b*p.y()+fPlanes[1].c*p.z()+fPlanes[1].d;
G4double dy = std::max(dz,std::max(dy1,dy2));
G4double dx1 = fPlanes[2].a*p.x()+fPlanes[2].b*p.y()+fPlanes[2].c*p.z()+fPlanes[2].d;
G4double dx2 = fPlanes[3].a*p.x()+fPlanes[3].b*p.y()+fPlanes[3].c*p.z()+fPlanes[3].d;
G4double dist = std::max(dy,std::max(dx1,dx2));
return (dist < 0) ? -dist : 0.;
G4double dx1 = fPlanes[2].a*p.x()+fPlanes[2].b*p.y()
+ fPlanes[2].c*p.z()+fPlanes[2].d;
G4double dx2 = fPlanes[3].a*p.x()+fPlanes[3].b*p.y()
+ fPlanes[3].c*p.z()+fPlanes[3].d;
G4double dist = std::max(dy,std::max(dx1,dx2));
return (dist < 0) ? -dist : 0.;
}
case 1: // YZ section is a rectangle
{
G4double dz = std::abs(p.z())-fDz;
G4double dy = std::max(dz,std::abs(p.y())+fPlanes[1].d);
G4double dx1 = fPlanes[2].a*p.x()+fPlanes[2].b*p.y()
+ fPlanes[2].c*p.z()+fPlanes[2].d;
G4double dx2 = fPlanes[3].a*p.x()+fPlanes[3].b*p.y()
+ fPlanes[3].c*p.z()+fPlanes[3].d;
G4double dist = std::max(dy,std::max(dx1,dx2));
return (dist < 0) ? -dist : 0.;
}
case 2: // YZ section is a rectangle and
{ // XZ section is an isosceles trapezoid
G4double dz = std::abs(p.z())-fDz;
G4double dy = std::max(dz,std::abs(p.y())+fPlanes[1].d);
G4double dx = fPlanes[3].a*std::abs(p.x())
+ fPlanes[3].c*p.z()+fPlanes[3].d;
G4double dist = std::max(dy,dx);
return (dist < 0) ? -dist : 0.;
}
case 3: // YZ section is a rectangle and
{ // XY section is an isosceles trapezoid
G4double dz = std::abs(p.z())-fDz;
G4double dy = std::max(dz,std::abs(p.y())+fPlanes[1].d);
G4double dx = fPlanes[3].a*std::abs(p.x())
+ fPlanes[3].b*p.y()+fPlanes[3].d;
G4double dist = std::max(dy,dx);
return (dist < 0) ? -dist : 0.;
}
}
return 0.;
}
////////////////////////////////////////////////////////////////////////////
+12 -3
View File
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// $Id: G4Trd.cc 104894 2017-06-26 13:30:00Z gcosmo $
// $Id: G4Trd.cc 107555 2017-11-22 15:26:59Z gcosmo $
//
//
// Implementation for G4Trd class
@@ -358,11 +358,17 @@ EInside G4Trd::Inside( const G4ThreeVector& p ) const
G4ThreeVector G4Trd::SurfaceNormal( const G4ThreeVector& p ) const
{
G4int nsurf = 0; // number of surfaces where p is placed
// Check Z faces
//
G4double nz = 0;
G4double dz = std::abs(p.z()) - fDz;
if (std::abs(dz) <= halfCarTolerance) nz = (p.z() < 0) ? -1 : 1;
if (std::abs(dz) <= halfCarTolerance)
{
nz = (p.z() < 0) ? -1 : 1;
++nsurf;
}
// Check Y faces
//
@@ -373,11 +379,13 @@ G4ThreeVector G4Trd::SurfaceNormal( const G4ThreeVector& p ) const
{
ny += fPlanes[0].b;
nz += fPlanes[0].c;
++nsurf;
}
if (std::abs(dy2 - dy1) <= halfCarTolerance)
{
ny += fPlanes[1].b;
nz += fPlanes[1].c;
++nsurf;
}
// Check X faces
@@ -389,16 +397,17 @@ G4ThreeVector G4Trd::SurfaceNormal( const G4ThreeVector& p ) const
{
nx += fPlanes[2].a;
nz += fPlanes[2].c;
++nsurf;
}
if (std::abs(dx2 - dx1) <= halfCarTolerance)
{
nx += fPlanes[3].a;
nz += fPlanes[3].c;
++nsurf;
}
// Return normal
//
G4int nsurf = nx*nx + ny*ny + nz*nz + 0.5; // get magnitude
if (nsurf == 1) return G4ThreeVector(nx,ny,nz);
else if (nsurf != 0) return G4ThreeVector(nx,ny,nz).unit(); // edge or corner
else
-18
View File
@@ -152,24 +152,6 @@ G4VSolid* G4UBox::Clone() const
return new G4UBox(*this);
}
//////////////////////////////////////////////////////////////////////////
//
// StreamInfo
std::ostream& G4UBox::StreamInfo(std::ostream &os) const
{
G4int oldprc = os.precision(16);
os << "-----------------------------------------------------------\n"
<< " *** Dump for solid - " << GetEntityType() << " ***\n"
<< " ===================================================\n"
<< " Solid type: Box\n"
<< " Parameters: \n"
<< " half-dimensions in mm: x,y,z: " << dimensions() <<"\n"
<< "-----------------------------------------------------------\n";
os.precision(oldprc);
return os;
}
//////////////////////////////////////////////////////////////////////////
//
// Get bounding box
@@ -0,0 +1,538 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// $Id:$
//
//
// Implementation for G4UCutTubs wrapper class
// --------------------------------------------------------------------
#include "G4CutTubs.hh"
#include "G4UCutTubs.hh"
#if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
#include "G4GeomTools.hh"
#include "G4AffineTransform.hh"
#include "G4VPVParameterisation.hh"
#include "G4BoundingEnvelope.hh"
using namespace CLHEP;
/////////////////////////////////////////////////////////////////////////
//
// Constructor - check parameters, convert angles so 0<sphi+dpshi<=2_PI
// - note if pdphi>2PI then reset to 2PI
G4UCutTubs::G4UCutTubs( const G4String& pName,
G4double pRMin, G4double pRMax,
G4double pDz,
G4double pSPhi, G4double pDPhi,
G4ThreeVector pLowNorm,
G4ThreeVector pHighNorm )
: Base_t(pName, pRMin, pRMax, pDz, pSPhi, pDPhi,
pLowNorm.x(), pLowNorm.y(), pLowNorm.z(),
pHighNorm.x(), pHighNorm.y(), pHighNorm.z())
{
}
///////////////////////////////////////////////////////////////////////
//
// Fake default constructor - sets only member data and allocates memory
// for usage restricted to object persistency.
//
G4UCutTubs::G4UCutTubs( __void__& a )
: Base_t(a)
{
}
//////////////////////////////////////////////////////////////////////////
//
// Destructor
G4UCutTubs::~G4UCutTubs()
{
}
//////////////////////////////////////////////////////////////////////////
//
// Copy constructor
G4UCutTubs::G4UCutTubs(const G4UCutTubs& rhs)
: Base_t(rhs)
{
}
//////////////////////////////////////////////////////////////////////////
//
// Assignment operator
G4UCutTubs& G4UCutTubs::operator = (const G4UCutTubs& rhs)
{
// Check assignment to self
//
if (this == &rhs) { return *this; }
// Copy base class data
//
Base_t::operator=(rhs);
return *this;
}
/////////////////////////////////////////////////////////////////////////
//
// Accessors and modifiers
G4double G4UCutTubs::GetInnerRadius() const
{
return rmin();
}
G4double G4UCutTubs::GetOuterRadius() const
{
return rmax();
}
G4double G4UCutTubs::GetZHalfLength() const
{
return z();
}
G4double G4UCutTubs::GetStartPhiAngle() const
{
return sphi();
}
G4double G4UCutTubs::GetDeltaPhiAngle() const
{
return dphi();
}
G4double G4UCutTubs::GetSinStartPhi() const
{
return std::sin(GetStartPhiAngle());
}
G4double G4UCutTubs::GetCosStartPhi() const
{
return std::cos(GetStartPhiAngle());
}
G4double G4UCutTubs::GetSinEndPhi() const
{
return std::sin(GetStartPhiAngle()+GetDeltaPhiAngle());
}
G4double G4UCutTubs::GetCosEndPhi() const
{
return std::cos(GetStartPhiAngle()+GetDeltaPhiAngle());
}
G4ThreeVector G4UCutTubs::GetLowNorm () const
{
U3Vector lc = BottomNormal();
return G4ThreeVector(lc.x(), lc.y(), lc.z());
}
G4ThreeVector G4UCutTubs::GetHighNorm () const
{
U3Vector hc = TopNormal();
return G4ThreeVector(hc.x(), hc.y(), hc.z());
}
void G4UCutTubs::SetInnerRadius(G4double newRMin)
{
SetRMin(newRMin);
fRebuildPolyhedron = true;
}
void G4UCutTubs::SetOuterRadius(G4double newRMax)
{
SetRMax(newRMax);
fRebuildPolyhedron = true;
}
void G4UCutTubs::SetZHalfLength(G4double newDz)
{
SetDz(newDz);
fRebuildPolyhedron = true;
}
void G4UCutTubs::SetStartPhiAngle(G4double newSPhi, G4bool)
{
SetSPhi(newSPhi);
fRebuildPolyhedron = true;
}
void G4UCutTubs::SetDeltaPhiAngle(G4double newDPhi)
{
SetDPhi(newDPhi);
fRebuildPolyhedron = true;
}
/////////////////////////////////////////////////////////////////////////
//
// Make a clone of the object
G4VSolid* G4UCutTubs::Clone() const
{
return new G4UCutTubs(*this);
}
//////////////////////////////////////////////////////////////////////////
//
// Get bounding box
void G4UCutTubs::BoundingLimits(G4ThreeVector& pMin, G4ThreeVector& pMax) const
{
static G4bool checkBBox = true;
G4double rmin = GetInnerRadius();
G4double rmax = GetOuterRadius();
G4double dz = GetZHalfLength();
G4double dphi = GetDeltaPhiAngle();
G4double sinSphi = GetSinStartPhi();
G4double cosSphi = GetCosStartPhi();
G4double sinEphi = GetSinEndPhi();
G4double cosEphi = GetCosEndPhi();
G4ThreeVector norm;
G4double mag, topx, topy, dists, diste;
G4bool iftop;
// Find Zmin
//
G4double zmin;
norm = GetLowNorm();
mag = std::sqrt(norm.x()*norm.x() + norm.y()*norm.y());
topx = (mag == 0) ? 0 : -rmax*norm.x()/mag;
topy = (mag == 0) ? 0 : -rmax*norm.y()/mag;
dists = sinSphi*topx - cosSphi*topy;
diste = -sinEphi*topx + cosEphi*topy;
if (dphi > pi)
{
iftop = true;
if (dists > 0 && diste > 0)iftop = false;
}
else
{
iftop = false;
if (dists <= 0 && diste <= 0) iftop = true;
}
if (iftop)
{
zmin = -(norm.x()*topx + norm.y()*topy)/norm.z() - dz;
}
else
{
G4double z1 = -rmin*(norm.x()*cosSphi + norm.y()*sinSphi)/norm.z() - dz;
G4double z2 = -rmin*(norm.x()*cosEphi + norm.y()*sinEphi)/norm.z() - dz;
G4double z3 = -rmax*(norm.x()*cosSphi + norm.y()*sinSphi)/norm.z() - dz;
G4double z4 = -rmax*(norm.x()*cosEphi + norm.y()*sinEphi)/norm.z() - dz;
zmin = std::min(std::min(std::min(z1,z2),z3),z4);
}
// Find Zmax
//
G4double zmax;
norm = GetHighNorm();
mag = std::sqrt(norm.x()*norm.x() + norm.y()*norm.y());
topx = (mag == 0) ? 0 : -rmax*norm.x()/mag;
topy = (mag == 0) ? 0 : -rmax*norm.y()/mag;
dists = sinSphi*topx - cosSphi*topy;
diste = -sinEphi*topx + cosEphi*topy;
if (dphi > pi)
{
iftop = true;
if (dists > 0 && diste > 0) iftop = false;
}
else
{
iftop = false;
if (dists <= 0 && diste <= 0) iftop = true;
}
if (iftop)
{
zmax = -(norm.x()*topx + norm.y()*topy)/norm.z() + dz;
}
else
{
G4double z1 = -rmin*(norm.x()*cosSphi + norm.y()*sinSphi)/norm.z() + dz;
G4double z2 = -rmin*(norm.x()*cosEphi + norm.y()*sinEphi)/norm.z() + dz;
G4double z3 = -rmax*(norm.x()*cosSphi + norm.y()*sinSphi)/norm.z() + dz;
G4double z4 = -rmax*(norm.x()*cosEphi + norm.y()*sinEphi)/norm.z() + dz;
zmax = std::max(std::max(std::max(z1,z2),z3),z4);
}
// Find bounding box
//
if (GetDeltaPhiAngle() < twopi)
{
G4TwoVector vmin,vmax;
G4GeomTools::DiskExtent(rmin,rmax,
GetSinStartPhi(),GetCosStartPhi(),
GetSinEndPhi(),GetCosEndPhi(),
vmin,vmax);
pMin.set(vmin.x(),vmin.y(), zmin);
pMax.set(vmax.x(),vmax.y(), zmax);
}
else
{
pMin.set(-rmax,-rmax, zmin);
pMax.set( rmax, rmax, zmax);
}
// Check correctness of the bounding box
//
if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z())
{
std::ostringstream message;
message << "Bad bounding box (min >= max) for solid: "
<< GetName() << " !"
<< "\npMin = " << pMin
<< "\npMax = " << pMax;
G4Exception("G4CUutTubs::BoundingLimits()", "GeomMgt0001",
JustWarning, message);
StreamInfo(G4cout);
}
// Check consistency of bounding boxes
//
if (checkBBox)
{
U3Vector vmin, vmax;
Extent(vmin,vmax);
if (std::abs(pMin.x()-vmin.x()) > kCarTolerance ||
std::abs(pMin.y()-vmin.y()) > kCarTolerance ||
std::abs(pMin.z()-vmin.z()) > kCarTolerance ||
std::abs(pMax.x()-vmax.x()) > kCarTolerance ||
std::abs(pMax.y()-vmax.y()) > kCarTolerance ||
std::abs(pMax.z()-vmax.z()) > kCarTolerance)
{
std::ostringstream message;
message << "Inconsistency in bounding boxes for solid: "
<< GetName() << " !"
<< "\nBBox min: wrapper = " << pMin << " solid = " << vmin
<< "\nBBox max: wrapper = " << pMax << " solid = " << vmax;
G4Exception("G4UCutTubs::BoundingLimits()", "GeomMgt0001",
JustWarning, message);
checkBBox = false;
}
}
}
//////////////////////////////////////////////////////////////////////////
//
// Calculate extent under transform and specified limit
G4bool
G4UCutTubs::CalculateExtent(const EAxis pAxis,
const G4VoxelLimits& pVoxelLimit,
const G4AffineTransform& pTransform,
G4double& pMin, G4double& pMax) const
{
G4ThreeVector bmin, bmax;
G4bool exist;
// Get bounding box
BoundingLimits(bmin,bmax);
// Check bounding box
G4BoundingEnvelope bbox(bmin,bmax);
#ifdef G4BBOX_EXTENT
if (true) return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
#endif
if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
{
return exist = (pMin < pMax) ? true : false;
}
// Get parameters of the solid
G4double rmin = GetInnerRadius();
G4double rmax = GetOuterRadius();
G4double dphi = GetDeltaPhiAngle();
G4double zmin = bmin.z();
G4double zmax = bmax.z();
// Find bounding envelope and calculate extent
//
const G4int NSTEPS = 24; // number of steps for whole circle
G4double astep = twopi/NSTEPS; // max angle for one step
G4int ksteps = (dphi <= astep) ? 1 : (G4int)((dphi-deg)/astep) + 1;
G4double ang = dphi/ksteps;
G4double sinHalf = std::sin(0.5*ang);
G4double cosHalf = std::cos(0.5*ang);
G4double sinStep = 2.*sinHalf*cosHalf;
G4double cosStep = 1. - 2.*sinHalf*sinHalf;
G4double rext = rmax/cosHalf;
// bounding envelope for full cylinder consists of two polygons,
// in other cases it is a sequence of quadrilaterals
if (rmin == 0 && dphi == twopi)
{
G4double sinCur = sinHalf;
G4double cosCur = cosHalf;
G4ThreeVectorList baseA(NSTEPS),baseB(NSTEPS);
for (G4int k=0; k<NSTEPS; ++k)
{
baseA[k].set(rext*cosCur,rext*sinCur,zmin);
baseB[k].set(rext*cosCur,rext*sinCur,zmax);
G4double sinTmp = sinCur;
sinCur = sinCur*cosStep + cosCur*sinStep;
cosCur = cosCur*cosStep - sinTmp*sinStep;
}
std::vector<const G4ThreeVectorList *> polygons(2);
polygons[0] = &baseA;
polygons[1] = &baseB;
G4BoundingEnvelope benv(bmin,bmax,polygons);
exist = benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
}
else
{
G4double sinStart = GetSinStartPhi();
G4double cosStart = GetCosStartPhi();
G4double sinEnd = GetSinEndPhi();
G4double cosEnd = GetCosEndPhi();
G4double sinCur = sinStart*cosHalf + cosStart*sinHalf;
G4double cosCur = cosStart*cosHalf - sinStart*sinHalf;
// set quadrilaterals
G4ThreeVectorList pols[NSTEPS+2];
for (G4int k=0; k<ksteps+2; ++k) pols[k].resize(4);
pols[0][0].set(rmin*cosStart,rmin*sinStart,zmax);
pols[0][1].set(rmin*cosStart,rmin*sinStart,zmin);
pols[0][2].set(rmax*cosStart,rmax*sinStart,zmin);
pols[0][3].set(rmax*cosStart,rmax*sinStart,zmax);
for (G4int k=1; k<ksteps+1; ++k)
{
pols[k][0].set(rmin*cosCur,rmin*sinCur,zmax);
pols[k][1].set(rmin*cosCur,rmin*sinCur,zmin);
pols[k][2].set(rext*cosCur,rext*sinCur,zmin);
pols[k][3].set(rext*cosCur,rext*sinCur,zmax);
G4double sinTmp = sinCur;
sinCur = sinCur*cosStep + cosCur*sinStep;
cosCur = cosCur*cosStep - sinTmp*sinStep;
}
pols[ksteps+1][0].set(rmin*cosEnd,rmin*sinEnd,zmax);
pols[ksteps+1][1].set(rmin*cosEnd,rmin*sinEnd,zmin);
pols[ksteps+1][2].set(rmax*cosEnd,rmax*sinEnd,zmin);
pols[ksteps+1][3].set(rmax*cosEnd,rmax*sinEnd,zmax);
// set envelope and calculate extent
std::vector<const G4ThreeVectorList *> polygons;
polygons.resize(ksteps+2);
for (G4int k=0; k<ksteps+2; ++k) polygons[k] = &pols[k];
G4BoundingEnvelope benv(bmin,bmax,polygons);
exist = benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
}
return exist;
}
///////////////////////////////////////////////////////////////////////////
//
// Return real Z coordinate of point on Cutted +/- fDZ plane
G4double G4UCutTubs::GetCutZ(const G4ThreeVector& p) const
{
G4double newz = p.z(); // p.z() should be either +fDz or -fDz
G4ThreeVector fLowNorm = GetLowNorm();
G4ThreeVector fHighNorm = GetHighNorm();
if (p.z()<0)
{
if(fLowNorm.z()!=0.)
{
newz = -GetZHalfLength()
- (p.x()*fLowNorm.x()+p.y()*fLowNorm.y())/fLowNorm.z();
}
}
else
{
if(fHighNorm.z()!=0.)
{
newz = GetZHalfLength()
- (p.x()*fHighNorm.x()+p.y()*fHighNorm.y())/fHighNorm.z();
}
}
return newz;
}
//////////////////////////////////////////////////////////////////////////
//
// Create polyhedron for visualization
//
G4Polyhedron* G4UCutTubs::CreatePolyhedron() const
{
typedef G4double G4double3[3];
typedef G4int G4int4[4];
G4Polyhedron *ph = new G4Polyhedron;
G4Polyhedron *ph1 = new G4PolyhedronTubs(GetInnerRadius(),
GetOuterRadius(),
GetZHalfLength(),
GetStartPhiAngle(),
GetDeltaPhiAngle());
G4int nn=ph1->GetNoVertices();
G4int nf=ph1->GetNoFacets();
G4double3* xyz = new G4double3[nn]; // number of nodes
G4int4* faces = new G4int4[nf] ; // number of faces
G4double fDz = GetZHalfLength();
for(G4int i=0;i<nn;++i)
{
xyz[i][0]=ph1->GetVertex(i+1).x();
xyz[i][1]=ph1->GetVertex(i+1).y();
G4double tmpZ=ph1->GetVertex(i+1).z();
if(tmpZ>=fDz-kCarTolerance)
{
xyz[i][2]=GetCutZ(G4ThreeVector(xyz[i][0],xyz[i][1],fDz));
}
else if(tmpZ<=-fDz+kCarTolerance)
{
xyz[i][2]=GetCutZ(G4ThreeVector(xyz[i][0],xyz[i][1],-fDz));
}
else
{
xyz[i][2]=tmpZ;
}
}
G4int iNodes[4];
G4int *iEdge=0;
G4int n;
for(G4int i=0;i<nf;++i)
{
ph1->GetFacet(i+1,n,iNodes,iEdge);
for(G4int k=0;k<n;++k)
{
faces[i][k]=iNodes[k];
}
for(G4int k=n;k<4;++k)
{
faces[i][k]=0;
}
}
ph->createPolyhedron(nn,nf,xyz,faces);
delete [] xyz;
delete [] faces;
delete ph1;
return ph;
}
#endif // G4GEOM_USE_USOLIDS
+464
View File
@@ -0,0 +1,464 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// $Id:$
//
//
// Implementation for G4UPara wrapper class
// --------------------------------------------------------------------
#include "G4Para.hh"
#include "G4UPara.hh"
#if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
#include "G4AffineTransform.hh"
#include "G4VPVParameterisation.hh"
#include "G4BoundingEnvelope.hh"
using namespace CLHEP;
//////////////////////////////////////////////////////////////////////////
//
// Constructor - set & check half widths
G4UPara::G4UPara(const G4String& pName,
G4double pDx, G4double pDy, G4double pDz,
G4double pAlpha, G4double pTheta, G4double pPhi)
: Base_t(pName, pDx, pDy, pDz, pAlpha, pTheta, pPhi)
{
fTalpha = std::tan(pAlpha);
fTthetaCphi = std::tan(pTheta)*std::cos(pPhi);
fTthetaSphi = std::tan(pTheta)*std::sin(pPhi);
CheckParameters();
MakePlanes();
}
//////////////////////////////////////////////////////////////////////////
//
// Constructor - design of trapezoid based on 8 vertices
G4UPara::G4UPara( const G4String& pName,
const G4ThreeVector pt[8] )
: Base_t(pName)
{
// Find dimensions and trigonometric values
//
G4double fDx = (pt[3].x() - pt[2].x())*0.5;
G4double fDy = (pt[2].y() - pt[1].y())*0.5;
G4double fDz = pt[7].z();
SetDimensions(fDx, fDy, fDz);
CheckParameters(); // check dimensions
fTalpha = (pt[2].x() + pt[3].x() - pt[1].x() - pt[0].x())*0.25/fDy;
fTthetaCphi = (pt[4].x() + fDy*fTalpha + fDx)/fDz;
fTthetaSphi = (pt[4].y() + fDy)/fDz;
SetAlpha(std::atan(fTalpha));
SetTheta(std::atan(std::sqrt(fTthetaSphi*fTthetaSphi
+ fTthetaCphi*fTthetaCphi)));
SetPhi (std::atan2(fTthetaSphi, fTthetaCphi));
MakePlanes();
// Recompute vertices
//
G4ThreeVector v[8];
G4double DyTalpha = fDy*fTalpha;
G4double DzTthetaSphi = fDz*fTthetaSphi;
G4double DzTthetaCphi = fDz*fTthetaCphi;
v[0].set(-DzTthetaCphi-DyTalpha-fDx, -DzTthetaSphi-fDy, -fDz);
v[1].set(-DzTthetaCphi-DyTalpha+fDx, -DzTthetaSphi-fDy, -fDz);
v[2].set(-DzTthetaCphi+DyTalpha-fDx, -DzTthetaSphi+fDy, -fDz);
v[3].set(-DzTthetaCphi+DyTalpha+fDx, -DzTthetaSphi+fDy, -fDz);
v[4].set( DzTthetaCphi-DyTalpha-fDx, DzTthetaSphi-fDy, fDz);
v[5].set( DzTthetaCphi-DyTalpha+fDx, DzTthetaSphi-fDy, fDz);
v[6].set( DzTthetaCphi+DyTalpha-fDx, DzTthetaSphi+fDy, fDz);
v[7].set( DzTthetaCphi+DyTalpha+fDx, DzTthetaSphi+fDy, fDz);
// Compare with original vertices
//
for (G4int i=0; i<8; ++i)
{
G4double delx = std::abs(pt[i].x() - v[i].x());
G4double dely = std::abs(pt[i].y() - v[i].y());
G4double delz = std::abs(pt[i].z() - v[i].z());
G4double discrepancy = std::max(std::max(delx,dely),delz);
if (discrepancy > 0.1*kCarTolerance)
{
std::ostringstream message;
G4int oldprc = message.precision(16);
message << "Invalid vertice coordinates for Solid: " << GetName()
<< "\nVertix #" << i << ", discrepancy = " << discrepancy
<< "\n original : " << pt[i]
<< "\n recomputed : " << v[i];
G4cout.precision(oldprc);
G4Exception("G4UPara::G4UPara()", "GeomSolids0002",
FatalException, message);
}
}
}
//////////////////////////////////////////////////////////////////////////
//
// Fake default constructor - sets only member data and allocates memory
// for usage restricted to object persistency
G4UPara::G4UPara( __void__& a )
: Base_t(a)
{
SetAllParameters(1., 1., 1., 0., 0., 0.);
fRebuildPolyhedron = false;
}
//////////////////////////////////////////////////////////////////////////
//
// Destructor
G4UPara::~G4UPara()
{
}
//////////////////////////////////////////////////////////////////////////
//
// Copy constructor
G4UPara::G4UPara(const G4UPara& rhs)
: Base_t(rhs), fTalpha(rhs.fTalpha),
fTthetaCphi(rhs.fTthetaCphi),fTthetaSphi(rhs.fTthetaSphi)
{
for (G4int i=0; i<4; ++i) { fPlanes[i] = rhs.fPlanes[i]; }
}
//////////////////////////////////////////////////////////////////////////
//
// Assignment operator
G4UPara& G4UPara::operator = (const G4UPara& rhs)
{
// Check assignment to self
//
if (this == &rhs) { return *this; }
// Copy base class data
//
Base_t::operator=(rhs);
// Copy data
//
fTalpha = rhs.fTalpha;
fTthetaCphi = rhs.fTthetaCphi;
fTthetaSphi = rhs.fTthetaSphi;
for (G4int i=0; i<4; ++i) { fPlanes[i] = rhs.fPlanes[i]; }
return *this;
}
//////////////////////////////////////////////////////////////////////////
//
// Accessors & modifiers
G4double G4UPara::GetZHalfLength() const
{
return GetZ();
}
G4double G4UPara::GetYHalfLength() const
{
return GetY();
}
G4double G4UPara::GetXHalfLength() const
{
return GetZ();
}
G4ThreeVector G4UPara::GetSymAxis() const
{
return G4ThreeVector(fTthetaCphi,fTthetaSphi,1.).unit();
}
G4double G4UPara::GetTanAlpha() const
{
return fTalpha;
}
void G4UPara::SetXHalfLength(G4double val)
{
SetDimensions(val, GetY(), GetZ());
fRebuildPolyhedron = true;
CheckParameters();
MakePlanes();
}
void G4UPara::SetYHalfLength(G4double val)
{
SetDimensions(GetX(), val, GetZ());
fRebuildPolyhedron = true;
CheckParameters();
MakePlanes();
}
void G4UPara::SetZHalfLength(G4double val)
{
SetDimensions(GetX(), GetY(), val);
fRebuildPolyhedron = true;
CheckParameters();
MakePlanes();
}
void G4UPara::SetAlpha(G4double alpha)
{
Base_t::SetAlpha(alpha);
fTalpha = std::tan(alpha);
fRebuildPolyhedron = true;
MakePlanes();
}
void G4UPara::SetTanAlpha(G4double val)
{
fTalpha = val;
fRebuildPolyhedron = true;
MakePlanes();
}
void G4UPara::SetThetaAndPhi(double pTheta, double pPhi)
{
Base_t::SetThetaAndPhi(pTheta, pPhi);
G4double tanTheta = std::tan(pTheta);
fTthetaCphi = tanTheta*std::cos(pPhi);
fTthetaSphi = tanTheta*std::sin(pPhi);
fRebuildPolyhedron = true;
MakePlanes();
}
//////////////////////////////////////////////////////////////////////////
//
// Set all parameters, as for constructor - set and check half-widths
void G4UPara::SetAllParameters(G4double pDx, G4double pDy, G4double pDz,
G4double pAlpha, G4double pTheta, G4double pPhi)
{
// Reset data of the base class
fRebuildPolyhedron = true;
// Set parameters
SetDimensions(pDx, pDy, pDz);
Base_t::SetAlpha(pAlpha);
Base_t::SetThetaAndPhi(pTheta, pPhi);
fTalpha = std::tan(pAlpha);
fTthetaCphi = std::tan(pTheta)*std::cos(pPhi);
fTthetaSphi = std::tan(pTheta)*std::sin(pPhi);
CheckParameters();
MakePlanes();
}
//////////////////////////////////////////////////////////////////////////
//
// Check dimensions
void G4UPara::CheckParameters()
{
if (GetX() < 2*kCarTolerance ||
GetY() < 2*kCarTolerance ||
GetZ() < 2*kCarTolerance)
{
std::ostringstream message;
message << "Invalid (too small or negative) dimensions for Solid: "
<< GetName()
<< "\n X - " << GetX()
<< "\n Y - " << GetY()
<< "\n Z - " << GetZ();
G4Exception("G4UPara::CheckParameters()", "GeomSolids0002",
FatalException, message);
}
}
//////////////////////////////////////////////////////////////////////////
//
// Set side planes
void G4UPara::MakePlanes()
{
G4ThreeVector vx(1, 0, 0);
G4ThreeVector vy(fTalpha, 1, 0);
G4ThreeVector vz(fTthetaCphi, fTthetaSphi, 1);
// Set -Y & +Y planes
//
G4ThreeVector ynorm = (vx.cross(vz)).unit();
fPlanes[0].a = 0.;
fPlanes[0].b = ynorm.y();
fPlanes[0].c = ynorm.z();
fPlanes[0].d = fPlanes[0].b*GetY(); // point (0,fDy,0) is on plane
fPlanes[1].a = 0.;
fPlanes[1].b = -fPlanes[0].b;
fPlanes[1].c = -fPlanes[0].c;
fPlanes[1].d = fPlanes[0].d;
// Set -X & +X planes
//
G4ThreeVector xnorm = (vz.cross(vy)).unit();
fPlanes[2].a = xnorm.x();
fPlanes[2].b = xnorm.y();
fPlanes[2].c = xnorm.z();
fPlanes[2].d = fPlanes[2].a*GetZ(); // point (fDx,0,0) is on plane
fPlanes[3].a = -fPlanes[2].a;
fPlanes[3].b = -fPlanes[2].b;
fPlanes[3].c = -fPlanes[2].c;
fPlanes[3].d = fPlanes[2].d;
}
//////////////////////////////////////////////////////////////////////////
//
// Dispatch to parameterisation for replication mechanism dimension
// computation & modification
void G4UPara::ComputeDimensions( G4VPVParameterisation* p,
const G4int n,
const G4VPhysicalVolume* pRep )
{
p->ComputeDimensions(*this,n,pRep);
}
//////////////////////////////////////////////////////////////////////////
//
// Get bounding box
void G4UPara::BoundingLimits(G4ThreeVector& pMin, G4ThreeVector& pMax) const
{
G4double dz = GetZHalfLength();
G4double dx = GetXHalfLength();
G4double dy = GetYHalfLength();
G4double x0 = dz*fTthetaCphi;
G4double x1 = dy*GetTanAlpha();
G4double xmin =
std::min(
std::min(
std::min(-x0-x1-dx,-x0+x1-dx),x0-x1-dx),x0+x1-dx);
G4double xmax =
std::max(
std::max(
std::max(-x0-x1+dx,-x0+x1+dx),x0-x1+dx),x0+x1+dx);
G4double y0 = dz*fTthetaSphi;
G4double ymin = std::min(-y0-dy,y0-dy);
G4double ymax = std::max(-y0+dy,y0+dy);
pMin.set(xmin,ymin,-dz);
pMax.set(xmax,ymax, dz);
// Check correctness of the bounding box
//
if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z())
{
std::ostringstream message;
message << "Bad bounding box (min >= max) for solid: "
<< GetName() << " !"
<< "\npMin = " << pMin
<< "\npMax = " << pMax;
G4Exception("G4UPara::BoundingLimits()", "GeomMgt0001",
JustWarning, message);
StreamInfo(G4cout);
}
}
//////////////////////////////////////////////////////////////////////////
//
// Calculate extent under transform and specified limit
G4bool G4UPara::CalculateExtent( const EAxis pAxis,
const G4VoxelLimits& pVoxelLimit,
const G4AffineTransform& pTransform,
G4double& pMin, G4double& pMax ) const
{
G4ThreeVector bmin, bmax;
G4bool exist;
// Check bounding box (bbox)
//
BoundingLimits(bmin,bmax);
G4BoundingEnvelope bbox(bmin,bmax);
#ifdef G4BBOX_EXTENT
if (true) return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
#endif
if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
{
return exist = (pMin < pMax) ? true : false;
}
// Set bounding envelope (benv) and calculate extent
//
G4double dz = GetZHalfLength();
G4double dx = GetXHalfLength();
G4double dy = GetYHalfLength();
G4double x0 = dz*fTthetaCphi;
G4double x1 = dy*GetTanAlpha();
G4double y0 = dz*fTthetaSphi;
G4ThreeVectorList baseA(4), baseB(4);
baseA[0].set(-x0-x1-dx,-y0-dy,-dz);
baseA[1].set(-x0-x1+dx,-y0-dy,-dz);
baseA[2].set(-x0+x1+dx,-y0+dy,-dz);
baseA[3].set(-x0+x1-dx,-y0+dy,-dz);
baseB[0].set(+x0-x1-dx, y0-dy, dz);
baseB[1].set(+x0-x1+dx, y0-dy, dz);
baseB[2].set(+x0+x1+dx, y0+dy, dz);
baseB[3].set(+x0+x1-dx, y0+dy, dz);
std::vector<const G4ThreeVectorList *> polygons(2);
polygons[0] = &baseA;
polygons[1] = &baseB;
G4BoundingEnvelope benv(bmin,bmax,polygons);
exist = benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
return exist;
}
//////////////////////////////////////////////////////////////////////////
//
// Make a clone of the object
//
G4VSolid* G4UPara::Clone() const
{
return new G4UPara(*this);
}
//////////////////////////////////////////////////////////////////////////
//
// Methods for visualisation
G4Polyhedron* G4UPara::CreatePolyhedron () const
{
return new G4PolyhedronPara(GetX(), GetY(), GetZ(),
GetAlpha(), GetTheta(), GetPhi());
}
#endif // G4GEOM_USE_USOLIDS
+29 -42
View File
@@ -48,11 +48,10 @@ using namespace CLHEP;
// - note if pDPhi>2PI then reset to 2PI
G4USphere::G4USphere( const G4String& pName,
G4double pRmin, G4double pRmax,
G4double pSPhi, G4double pDPhi,
G4double pSTheta, G4double pDTheta )
: G4USolid(pName, new USphere(pName, pRmin, pRmax, pSPhi, pDPhi,
pSTheta, pDTheta))
G4double pRmin, G4double pRmax,
G4double pSPhi, G4double pDPhi,
G4double pSTheta, G4double pDTheta )
: Base_t(pName, pRmin, pRmax, pSPhi, pDPhi, pSTheta, pDTheta)
{
}
@@ -62,7 +61,7 @@ G4USphere::G4USphere( const G4String& pName,
// for usage restricted to object persistency.
//
G4USphere::G4USphere( __void__& a )
: G4USolid(a)
: Base_t(a)
{
}
@@ -79,7 +78,7 @@ G4USphere::~G4USphere()
// Copy constructor
G4USphere::G4USphere(const G4USphere& rhs)
: G4USolid(rhs)
: Base_t(rhs)
{
}
@@ -95,7 +94,7 @@ G4USphere& G4USphere::operator = (const G4USphere& rhs)
// Copy base class data
//
G4USolid::operator=(rhs);
Base_t::operator=(rhs);
return *this;
}
@@ -106,101 +105,89 @@ G4USphere& G4USphere::operator = (const G4USphere& rhs)
G4double G4USphere::GetInnerRadius() const
{
return GetShape()->GetInnerRadius();
return Base_t::GetInnerRadius();
}
G4double G4USphere::GetOuterRadius() const
{
return GetShape()->GetOuterRadius();
return Base_t::GetOuterRadius();
}
G4double G4USphere::GetStartPhiAngle() const
{
return GetShape()->GetStartPhiAngle();
return Base_t::GetStartPhiAngle();
}
G4double G4USphere::GetDeltaPhiAngle() const
{
return GetShape()->GetDeltaPhiAngle();
return Base_t::GetDeltaPhiAngle();
}
G4double G4USphere::GetStartThetaAngle() const
{
return GetShape()->GetStartThetaAngle();
return Base_t::GetStartThetaAngle();
}
G4double G4USphere::GetDeltaThetaAngle() const
{
return GetShape()->GetDeltaThetaAngle();
return Base_t::GetDeltaThetaAngle();
}
G4double G4USphere::GetSinStartPhi() const
{
G4double phi = GetShape()->GetStartPhiAngle();
return std::sin(phi);
return Base_t::GetSinSPhi();
}
G4double G4USphere::GetCosStartPhi() const
{
G4double phi = GetShape()->GetStartPhiAngle();
return std::cos(phi);
return Base_t::GetCosSPhi();
}
G4double G4USphere::GetSinEndPhi() const
{
G4double phi = GetShape()->GetStartPhiAngle() +
GetShape()->GetDeltaPhiAngle();
return std::sin(phi);
return Base_t::GetSinEPhi();
}
G4double G4USphere::GetCosEndPhi() const
{
G4double phi = GetShape()->GetStartPhiAngle() +
GetShape()->GetDeltaPhiAngle();
return std::cos(phi);
return Base_t::GetCosEPhi();
}
G4double G4USphere::GetSinStartTheta() const
{
G4double theta = GetShape()->GetStartThetaAngle();
return std::sin(theta);
return Base_t::GetSinSTheta();
}
G4double G4USphere::GetCosStartTheta() const
{
G4double theta = GetShape()->GetStartThetaAngle();
return std::cos(theta);
return Base_t::GetCosSTheta();
}
G4double G4USphere::GetSinEndTheta() const
{
G4double theta = GetShape()->GetStartThetaAngle() +
GetShape()->GetDeltaThetaAngle();
return std::sin(theta);
return Base_t::GetSinETheta();
}
G4double G4USphere::GetCosEndTheta() const
{
G4double theta = GetShape()->GetStartThetaAngle() +
GetShape()->GetDeltaThetaAngle();
return std::cos(theta);
return Base_t::GetCosETheta();
}
void G4USphere::SetInnerRadius(G4double newRMin)
{
GetShape()->SetInnerRadius(newRMin);
Base_t::SetInnerRadius(newRMin);
fRebuildPolyhedron = true;
}
void G4USphere::SetOuterRadius(G4double newRmax)
{
GetShape()->SetOuterRadius(newRmax);
Base_t::SetOuterRadius(newRmax);
fRebuildPolyhedron = true;
}
void G4USphere::SetStartPhiAngle(G4double newSphi, G4bool trig)
{
GetShape()->SetStartPhiAngle(newSphi, trig);
Base_t::SetStartPhiAngle(newSphi, trig);
fRebuildPolyhedron = true;
}
void G4USphere::SetDeltaPhiAngle(G4double newDphi)
{
GetShape()->SetDeltaPhiAngle(newDphi);
Base_t::SetDeltaPhiAngle(newDphi);
fRebuildPolyhedron = true;
}
void G4USphere::SetStartThetaAngle(G4double newSTheta)
{
GetShape()->SetStartThetaAngle(newSTheta);
Base_t::SetStartThetaAngle(newSTheta);
fRebuildPolyhedron = true;
}
void G4USphere::SetDeltaThetaAngle(G4double newDTheta)
{
GetShape()->SetDeltaThetaAngle(newDTheta);
Base_t::SetDeltaThetaAngle(newDTheta);
fRebuildPolyhedron = true;
}
@@ -287,8 +274,8 @@ void G4USphere::BoundingLimits(G4ThreeVector& pMin, G4ThreeVector& pMax) const
//
if (checkBBox)
{
UVector3 vmin, vmax;
GetShape()->Extent(vmin,vmax);
U3Vector vmin, vmax;
Extent(vmin,vmax);
if (std::abs(pMin.x()-vmin.x()) > kCarTolerance ||
std::abs(pMin.y()-vmin.y()) > kCarTolerance ||
std::abs(pMin.z()-vmin.z()) > kCarTolerance ||
+25 -31
View File
@@ -54,7 +54,7 @@ using namespace CLHEP;
G4UTorus::G4UTorus(const G4String& pName,
G4double rmin, G4double rmax, G4double rtor,
G4double sphi, G4double dphi)
: G4USolid(pName, new UTorus(pName, rmin, rmax, rtor, sphi, dphi))
: Base_t(pName, rmin, rmax, rtor, sphi, dphi)
{ }
//////////////////////////////////////////////////////////////////////////
@@ -63,7 +63,7 @@ G4UTorus::G4UTorus(const G4String& pName,
// for usage restricted to object persistency.
G4UTorus::G4UTorus( __void__& a )
: G4USolid(a)
: Base_t(a)
{ }
//////////////////////////////////////////////////////////////////////////
@@ -77,7 +77,7 @@ G4UTorus::~G4UTorus() { }
// Copy constructor
G4UTorus::G4UTorus(const G4UTorus& rhs)
: G4USolid(rhs)
: Base_t(rhs)
{ }
//////////////////////////////////////////////////////////////////////////
@@ -92,7 +92,7 @@ G4UTorus& G4UTorus::operator = (const G4UTorus& rhs)
// Copy base class data
//
G4USolid::operator=(rhs);
Base_t::operator=(rhs);
return *this;
}
@@ -103,93 +103,87 @@ G4UTorus& G4UTorus::operator = (const G4UTorus& rhs)
G4double G4UTorus::GetRmin() const
{
return GetShape()->GetRmin();
return rmin();
}
G4double G4UTorus::GetRmax() const
{
return GetShape()->GetRmax();
return rmax();
}
G4double G4UTorus::GetRtor() const
{
return GetShape()->GetRtor();
return rtor();
}
G4double G4UTorus::GetSPhi() const
{
return GetShape()->GetSPhi();
return sphi();
}
G4double G4UTorus::GetDPhi() const
{
return GetShape()->GetDPhi();
return dphi();
}
G4double G4UTorus::GetSinStartPhi() const
{
G4double phi = GetShape()->GetSPhi();
return std::sin(phi);
return std::sin(sphi());
}
G4double G4UTorus::GetCosStartPhi() const
{
G4double phi = GetShape()->GetSPhi();
return std::cos(phi);
return std::cos(sphi());
}
G4double G4UTorus::GetSinEndPhi() const
{
G4double phi = GetShape()->GetSPhi() +
GetShape()->GetDPhi();
return std::sin(phi);
return std::sin(sphi()+dphi());
}
G4double G4UTorus::GetCosEndPhi() const
{
G4double phi = GetShape()->GetSPhi() +
GetShape()->GetDPhi();
return std::cos(phi);
return std::cos(sphi()+dphi());
}
void G4UTorus::SetRmin(G4double arg)
{
GetShape()->SetRmin(arg);
Base_t::SetRMin(arg);
fRebuildPolyhedron = true;
}
void G4UTorus::SetRmax(G4double arg)
{
GetShape()->SetRmax(arg);
Base_t::SetRMax(arg);
fRebuildPolyhedron = true;
}
void G4UTorus::SetRtor(G4double arg)
{
GetShape()->SetRtor(arg);
Base_t::SetRTor(arg);
fRebuildPolyhedron = true;
}
void G4UTorus::SetSPhi(G4double arg)
{
GetShape()->SetSPhi(arg);
Base_t::SetSPhi(arg);
fRebuildPolyhedron = true;
}
void G4UTorus::SetDPhi(G4double arg)
{
GetShape()->SetDPhi(arg);
Base_t::SetDPhi(arg);
fRebuildPolyhedron = true;
}
void G4UTorus::SetAllParameters(G4double arg1, G4double arg2,
G4double arg3, G4double arg4, G4double arg5)
G4double arg3, G4double arg4, G4double arg5)
{
GetShape()->SetRmin(arg1);
GetShape()->SetRmax(arg2);
GetShape()->SetRtor(arg3);
GetShape()->SetSPhi(arg4);
GetShape()->SetDPhi(arg5);
SetRmin(arg1);
SetRmax(arg2);
SetRtor(arg3);
SetSPhi(arg4);
SetDPhi(arg5);
fRebuildPolyhedron = true;
}
@@ -265,7 +259,7 @@ void G4UTorus::BoundingLimits(G4ThreeVector& pMin, G4ThreeVector& pMax) const
if (checkBBox)
{
UVector3 vmin, vmax;
GetShape()->Extent(vmin,vmax);
Base_t::Extent(vmin,vmax);
if (std::abs(pMin.x()-vmin.x()) > kCarTolerance ||
std::abs(pMin.y()-vmin.y()) > kCarTolerance ||
std::abs(pMin.z()-vmin.z()) > kCarTolerance ||