297 lines
9.5 KiB
C++
297 lines
9.5 KiB
C++
//
|
|
// ********************************************************************
|
|
// * This Software is part of the AIDA Unified Solids Library package *
|
|
// * See: https://aidasoft.web.cern.ch/USolids *
|
|
// ********************************************************************
|
|
//
|
|
// $Id:$
|
|
//
|
|
// --------------------------------------------------------------------
|
|
//
|
|
// UPolycone
|
|
//
|
|
// Class description:
|
|
//
|
|
// Class implementing a CSG-like type "PCON".
|
|
//
|
|
// UPolycone( const G4String& name,
|
|
// G4double phiStart, // initial phi starting angle
|
|
// G4double phiTotal, // total phi angle
|
|
// G4int numZPlanes, // number of z planes
|
|
// const G4double zPlane[], // position of z planes
|
|
// const G4double rInner[], // tangent distance to inner surface
|
|
// const G4double rOuter[]) // tangent distance to outer surface
|
|
//
|
|
// Alternative constructor, but limited to increasing-only Z sections:
|
|
//
|
|
// UPolycone( const G4String& name,
|
|
// G4double phiStart, // initial phi starting angle
|
|
// G4double phiTotal, // total phi angle
|
|
// G4int numRZ, // number corners in r,z space
|
|
// const G4double r[], // r coordinate of these corners
|
|
// const G4double z[]) // z coordinate of these corners
|
|
//
|
|
// 19.04.13 Marek Gayer
|
|
// Created from original implementation in Geant4
|
|
// --------------------------------------------------------------------
|
|
|
|
#ifndef UPolycone_hh
|
|
#define UPolycone_hh
|
|
|
|
#include "VUSolid.hh"
|
|
|
|
#include "UPolyconeSide.hh"
|
|
#include "UVCSGfaceted.hh"
|
|
#include "UVoxelizer.hh"
|
|
|
|
#include "UCons.hh"
|
|
#include "UTubs.hh"
|
|
|
|
class UEnclosingCylinder;
|
|
class UReduciblePolygon;
|
|
class UPolyconeHistorical
|
|
{
|
|
public:
|
|
UPolyconeHistorical();
|
|
~UPolyconeHistorical();
|
|
UPolyconeHistorical(const UPolyconeHistorical& source);
|
|
UPolyconeHistorical& operator=(const UPolyconeHistorical& right);
|
|
|
|
double fStartAngle;
|
|
double fOpeningAngle;
|
|
int fNumZPlanes;
|
|
std::vector<double> fZValues;
|
|
std::vector<double> Rmin;
|
|
std::vector<double> Rmax;
|
|
};
|
|
|
|
class UPolycone : public VUSolid
|
|
{
|
|
|
|
public: // with description
|
|
|
|
void Init(
|
|
double phiStart, // initial phi starting angle
|
|
double phiTotal, // total phi angle
|
|
int numZPlanes, // number of z planes
|
|
const double zPlane[], // position of z planes
|
|
const double rInner[], // tangent distance to inner surface
|
|
const double rOuter[]);
|
|
|
|
UPolycone(const std::string& name) : VUSolid(name)
|
|
{
|
|
}
|
|
|
|
UPolycone(const std::string& name,
|
|
double phiStart, // initial phi starting angle
|
|
double phiTotal, // total phi angle
|
|
int numZPlanes, // number of z planes
|
|
const double zPlane[], // position of z planes
|
|
const double rInner[], // tangent distance to inner surface
|
|
const double rOuter[]); // tangent distance to outer surface
|
|
|
|
|
|
UPolycone(const std::string& name,
|
|
double phiStart, // initial phi starting angle
|
|
double phiTotal, // total phi angle
|
|
int numRZ, // number corners in r,z space
|
|
const double r[], // r coordinate of these corners
|
|
const double z[]); // z coordinate of these corners
|
|
|
|
|
|
virtual ~UPolycone();
|
|
|
|
void Reset();
|
|
|
|
// inline void SetOriginalParameters(UPolyconeHistorical* pars);
|
|
|
|
// inline void SetOriginalParameters();
|
|
|
|
std::ostream& StreamInfo(std::ostream& os) const;
|
|
|
|
VUSolid::EnumInside Inside(const UVector3& p) const;
|
|
|
|
double DistanceToIn(const UVector3& p, const UVector3& v, double aPstep = UUtils::kInfinity) const;
|
|
|
|
double SafetyFromInside(const UVector3& aPoint,
|
|
bool aAccurate = false) const;
|
|
double SafetyFromOutside(const UVector3& aPoint,
|
|
bool aAccurate = false) const;
|
|
|
|
double DistanceToOut(const UVector3& aPoint,
|
|
const UVector3& aDirection,
|
|
UVector3& aNormalVector,
|
|
bool& aConvex,
|
|
double aPstep = UUtils::kInfinity) const;
|
|
|
|
bool Normal(const UVector3& aPoint, UVector3& aNormal) const;
|
|
// virtual void Extent ( EAxisType aAxis, double &aMin, double &aMax ) const;
|
|
void Extent(UVector3& aMin, UVector3& aMax) const;
|
|
double Capacity();
|
|
double SurfaceArea();
|
|
UGeometryType GetEntityType() const;
|
|
|
|
void ComputeBBox(UBBox* /*aBox*/, bool /*aStore = false*/) {}
|
|
|
|
//G4Visualisation
|
|
void GetParametersList(int /*aNumber*/, double* /*aArray*/) const {}
|
|
VUSolid* Clone() const;
|
|
|
|
UPolycone(const UPolycone& source);
|
|
UPolycone& operator=(const UPolycone& source);
|
|
// Copy constructor and assignment operator.
|
|
void CopyStuff(const UPolycone& source);
|
|
UVector3 GetPointOnSurface() const;
|
|
|
|
// Methods for random point generation
|
|
|
|
UVector3 GetPointOnCone(double fRmin1, double fRmax1,
|
|
double fRmin2, double fRmax2,
|
|
double zOne, double zTwo,
|
|
double& totArea) const;
|
|
|
|
UVector3 GetPointOnTubs(double fRMin, double fRMax,
|
|
double zOne, double zTwo,
|
|
double& totArea) const;
|
|
|
|
UVector3 GetPointOnCut(double fRMin1, double fRMax1,
|
|
double fRMin2, double fRMax2,
|
|
double zOne, double zTwo,
|
|
double& totArea) const;
|
|
|
|
UVector3 GetPointOnRing(double fRMin, double fRMax,
|
|
double fRMin2, double fRMax2,
|
|
double zOne) const;
|
|
|
|
inline double GetStartPhi() const
|
|
{
|
|
return startPhi;
|
|
}
|
|
|
|
inline double GetEndPhi() const
|
|
{
|
|
return endPhi;
|
|
}
|
|
|
|
inline bool IsOpen() const
|
|
{
|
|
return phiIsOpen;
|
|
}
|
|
|
|
inline bool IsGeneric() const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
inline int GetNumRZCorner() const
|
|
{
|
|
return numCorner;
|
|
}
|
|
|
|
inline UPolyconeSideRZ GetCorner(int index) const
|
|
{
|
|
return corners[index];
|
|
}
|
|
|
|
inline UPolyconeHistorical* GetOriginalParameters() const
|
|
{
|
|
return fOriginalParameters;
|
|
}
|
|
|
|
inline void SetOriginalParameters(UPolyconeHistorical* pars)
|
|
{
|
|
if (!pars)
|
|
// UException("UPolycone3::SetOriginalParameters()", "GeomSolids0002",
|
|
// FatalException, "NULL pointer to parameters!");
|
|
*fOriginalParameters = *pars;
|
|
}
|
|
|
|
protected: // without description
|
|
|
|
// int fNumSides;
|
|
bool SetOriginalParameters(UReduciblePolygon* rz);
|
|
// Here are our parameters
|
|
|
|
double startPhi; // Starting phi value (0 < phiStart < 2pi)
|
|
double endPhi; // end phi value (0 < endPhi-phiStart < 2pi)
|
|
bool phiIsOpen; // true if there is a phi segment
|
|
int numCorner; // number RZ points
|
|
UPolyconeSideRZ* corners; // corner r,z points
|
|
UPolyconeHistorical* fOriginalParameters; // original input parameters
|
|
double fCubicVolume; // Cubic Volume
|
|
double fSurfaceArea; // Surface Area
|
|
|
|
inline void SetOriginalParameters()
|
|
{
|
|
int numPlanes = (int)numCorner / 2;
|
|
|
|
fOriginalParameters = new UPolyconeHistorical;
|
|
|
|
fOriginalParameters->fZValues.resize(numPlanes);
|
|
fOriginalParameters->Rmin.resize(numPlanes);
|
|
fOriginalParameters->Rmax.resize(numPlanes);
|
|
|
|
for (int j = 0; j < numPlanes; j++)
|
|
{
|
|
fOriginalParameters->fZValues[j] = corners[numPlanes + j].z;
|
|
fOriginalParameters->Rmax[j] = corners[numPlanes + j].r;
|
|
fOriginalParameters->Rmin[j] = corners[numPlanes - 1 - j].r;
|
|
}
|
|
|
|
fOriginalParameters->fStartAngle = startPhi;
|
|
fOriginalParameters->fOpeningAngle = endPhi - startPhi;
|
|
fOriginalParameters->fNumZPlanes = numPlanes;
|
|
}
|
|
|
|
UEnclosingCylinder* enclosingCylinder;
|
|
|
|
struct UPolyconeSection
|
|
{
|
|
VUSolid* solid;// true if all points in section are concave in regards to whole polycone, will be determined
|
|
double shift;
|
|
bool tubular;
|
|
// double left, right;
|
|
bool convex; // TURE if all points in section are concave in regards to whole polycone, will be determined, currently not implemented
|
|
};
|
|
|
|
std::vector<double> fZs; // z coordinates of given sections
|
|
std::vector<UPolyconeSection> fSections;
|
|
int fMaxSection;
|
|
|
|
inline VUSolid::EnumInside InsideSection(int index, const UVector3& p) const;
|
|
|
|
inline double SafetyFromInsideSection(int index, const UVector3& p) const
|
|
{
|
|
const UPolyconeSection& section = fSections[index];
|
|
UVector3 ps(p.x, p.y, p.z - section.shift);
|
|
double res = section.solid->SafetyFromInside(ps, true);
|
|
return res;
|
|
}
|
|
|
|
inline double SafetyFromOutsideSection(int index, const UVector3& p) const
|
|
{
|
|
const UPolyconeSection& section = fSections[index];
|
|
UVector3 ps(p.x, p.y, p.z - section.shift);
|
|
double res = section.solid->SafetyFromOutside(ps, true);
|
|
return res;
|
|
}
|
|
|
|
bool NormalSection(int index, const UVector3& p, UVector3& n) const
|
|
{
|
|
const UPolyconeSection& section = fSections[index];
|
|
UVector3 ps(p.x, p.y, p.z - section.shift);
|
|
bool res = section.solid->Normal(ps, n);
|
|
return res;
|
|
}
|
|
|
|
inline int GetSection(double z) const
|
|
{
|
|
int section = UVoxelizer::BinarySearch(fZs, z);
|
|
if (section < 0) section = 0;
|
|
else if (section > fMaxSection) section = fMaxSection;
|
|
return section;
|
|
}
|
|
};
|
|
|
|
#endif
|