Import Geant4 10.1.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-10 12:08:39 +02:00
parent 286caacf06
commit c9b32a6c0a
5770 changed files with 1050949 additions and 367105 deletions
+222
View File
@@ -0,0 +1,222 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UBits
//
// Class description:
//
// Container of bits
//
// This class provides a simple container of bits.
// Each bit can be set and tested via the functions SetBitNumber and
// TestBitNumber.
// The default value of all bits is false.
// The size of the container is automatically extended when a bit
// number is either set or tested. To reduce the memory size of the
// container use the Compact function, this will discard the memory
// occupied by the upper bits that are 0.
//
// Created for UTessellatedSolid
//
// 19.10.12 Marek Gayer
// Created from original implementation in ROOT (TBits)
// --------------------------------------------------------------------
#ifndef UBits_HH
#define UBits_HH
#include <cstring>
#include <ostream>
class UBits
{
public:
unsigned char* fAllBits; //[fNBytes] array of UChars
protected:
unsigned int fNBits; // Highest bit set + 1
unsigned int fNBytes; // Number of UChars in fAllBits
void ReserveBytes(unsigned int nbytes);
/*
void DoAndEqual(const UBits& rhs);
void DoOrEqual (const UBits& rhs);
void DoXorEqual(const UBits& rhs);
void DoLeftShift(unsigned int shift);
void DoRightShift(unsigned int shift);
void DoFlip();
*/
public:
UBits(unsigned int nbits = 0);
UBits(const UBits&);
UBits& operator=(const UBits& rhs);
virtual ~UBits();
//----- bit manipulation
//----- (note the difference with TObject's bit manipulations)
void ResetAllBits(bool value = false); // if value=1 set all bits to 1
void ResetBitNumber(unsigned int bitnumber);
void SetBitNumber(unsigned int bitnumber, bool value = true);
bool TestBitNumber(unsigned int bitnumber) const;
//----- Accessors and operator
bool operator[](unsigned int bitnumber) const;
/*
UBits& operator&=(const UBits& rhs) { DoAndEqual(rhs); return *this; }
UBits& operator|=(const UBits& rhs) { DoOrEqual(rhs); return *this; }
UBits& operator^=(const UBits& rhs) { DoXorEqual(rhs); return *this; }
UBits& operator<<=(unsigned int rhs) { DoLeftShift(rhs); return *this; }
UBits& operator>>=(unsigned int rhs) { DoRightShift(rhs); return *this; }
UBits operator<<(unsigned int rhs) { return UBits(*this)<<= rhs; }
UBits operator>>(unsigned int rhs) { return UBits(*this)>>= rhs; }
UBits operator~() { UBits res(*this); res.DoFlip(); return res; }
*/
//----- Optimized setters
// Each of these will replace the contents of the receiver with the bitvector
// in the parameter array. The number of bits is changed to nbits. If nbits
// is smaller than fNBits, the receiver will NOT be compacted.
void Set(unsigned int nbits, const char* array);
// void Set(unsigned int nbits, const unsigned char *array) { Set(nbits, (const char*)array); }
// void Set(unsigned int nbits, const short *array);
//void Set(unsigned int nbits, const unsigned short *array) { Set(nbits, (const short*)array); }
void Set(unsigned int nbits, const int* array);
// void Set(unsigned int nbits, const unsigned int *array) { Set(nbits, (const int*)array); }
//----- Optimized getters
// Each of these will replace the contents of the parameter array with the
// bits in the receiver. The parameter array must be large enough to hold
// all of the bits in the receiver.
// Note on semantics: any bits in the parameter array that go beyond the
// number of the bits in the receiver will have an unspecified value. For
// example, if you call Get(Int*) with an array of one integer and the UBits
// object has less than 32 bits, then the remaining bits in the integer will
// have an unspecified value.
void Get(char* array) const;
// void Get(unsigned char *array) const { Get((char*)array); }
// void Get(short *array) const;
// void Get(unsigned short *array) const { Get((short*)array); }
void Get(int* array) const;
// void Get(unsigned int *array) const { Get((int*)array); }
//----- Utilities
void Clear();
void Compact(); // Reduce the space used.
unsigned int GetNbits() const
{
return fNBits;
}
unsigned int GetNbytes() const
{
return fNBytes;
}
/*
unsigned int CounUBits(unsigned int startBit=0) const ; // return number of bits set to 1
unsigned int FirstNullBit(unsigned int startBit=0) const;
unsigned int FirstSetBit(unsigned int startBit=0) const;
*/
// bool operator==(const UBits &other) const;
// bool operator!=(const UBits &other) const { return !(*this==other); }
void Print() const; // to show the list of active bits
void Output(std::ostream&) const;
};
/*
inline UBits operator&(const UBits& lhs, const UBits& rhs)
{
UBits result(lhs);
result &= rhs;
return result;
}
inline UBits operator|(const UBits& lhs, const UBits& rhs)
{
UBits result(lhs);
result |= rhs;
return result;
}
inline UBits operator^(const UBits& lhs, const UBits& rhs)
{
UBits result(lhs);
result ^= rhs;
return result;
}
inline std::ostream &operator<<(std::ostream& os, const UBits& rhs)
{
rhs.Output(os); return os;
}
*/
// inline functions...
inline void UBits::SetBitNumber(unsigned int bitnumber, bool value)
{
// Set bit number 'bitnumber' to be value
if (bitnumber >= fNBits)
{
unsigned int new_size = (bitnumber / 8) + 1;
if (new_size > fNBytes)
{
if (new_size < 100 * 1024 * 1024)
new_size *= 2;
unsigned char* old_location = fAllBits;
fAllBits = new unsigned char[new_size];
std::memcpy(fAllBits, old_location, fNBytes);
std::memset(fAllBits + fNBytes , 0, new_size - fNBytes);
fNBytes = new_size;
delete [] old_location;
}
fNBits = bitnumber + 1;
}
unsigned int loc = bitnumber / 8;
unsigned char bit = bitnumber % 8;
if (value)
fAllBits[loc] |= (1 << bit);
else
fAllBits[loc] &= (0xFF ^ (1 << bit));
}
inline bool UBits::TestBitNumber(unsigned int bitnumber) const
{
// Return the current value of the bit
if (bitnumber >= fNBits) return false;
unsigned int loc = bitnumber / 8;
unsigned char value = fAllBits[loc];
unsigned char bit = bitnumber % 8;
bool result = (value & (1 << bit)) != 0;
return result;
// short: return 0 != (fAllBits[bitnumber/8] & (1<< (bitnumber%8)));
}
inline void UBits::ResetBitNumber(unsigned int bitnumber)
{
SetBitNumber(bitnumber, false);
}
inline bool UBits::operator[](unsigned int bitnumber) const
{
return TestBitNumber(bitnumber);
}
#endif
+153
View File
@@ -0,0 +1,153 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UBox
//
// Class description:
//
// A simple box defined by half-lengths on the three axis.
// The center of the box matches the origin of the local reference frame.
//
// 10.06.11 J.Apostolakis, G.Cosmo, A.Gheata
// Created from original implementation in Geant4 and ROOT
// --------------------------------------------------------------------
#ifndef USOLIDS_UBox
#define USOLIDS_UBox
#ifndef USOLIDS_VUSolid
#include "VUSolid.hh"
#endif
#ifndef USOLIDS_UUtils
#include "UUtils.hh"
#endif
class UBox : public VUSolid
{
public:
UBox() : VUSolid(), fDx(0), fDy(0), fDz(0),fCubicVolume(0.), fSurfaceArea(0.) {}
UBox(const std::string& name, double dx, double dy, double dz);
virtual ~UBox();
UBox(const UBox& rhs);
UBox& operator=(const UBox& rhs);
// Copy constructor and assignment operator
void Set(double dx, double dy, double dz);
void Set(const UVector3& vec);
// Accessors and modifiers
inline double GetXHalfLength() const;
inline double GetYHalfLength() const;
inline double GetZHalfLength() const;
void SetXHalfLength(double dx);
void SetYHalfLength(double dy);
void SetZHalfLength(double dz);
// Navigation methods
EnumInside Inside(const UVector3& aPoint) const;
double SafetyFromInside(const UVector3& aPoint,
bool aAccurate = false) const;
double SafetyFromOutside(const UVector3& aPoint,
bool aAccurate = false) const;
double DistanceToIn(const UVector3& aPoint,
const UVector3& aDirection,
// UVector3 &aNormalVector,
double aPstep = UUtils::kInfinity) 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;
// void Extent ( EAxisType aAxis, double &aMin, double &aMax ) const;
void Extent(UVector3& aMin, UVector3& aMax) const;
inline double Capacity();
inline double SurfaceArea();
VUSolid* Clone() const;
UGeometryType GetEntityType() const;
void ComputeBBox(UBBox* /*aBox*/, bool /*aStore = false*/) {}
// Visualisation
void GetParametersList(int, double* aArray) const
{
aArray[0] = GetXHalfLength();
aArray[1] = GetYHalfLength();
aArray[2] = GetZHalfLength();
}
UVector3 GetPointOnSurface() const;
std::ostream& StreamInfo(std::ostream& os) const;
private:
double fDx; // Half-length on X
double fDy; // Half-length on Y
double fDz; // Half-length on Z
double fCubicVolume; // Cubic Volume
double fSurfaceArea; // Surface Area
};
inline double UBox::GetXHalfLength() const
{
return fDx;
}
inline double UBox::GetYHalfLength() const
{
return fDy;
}
inline double UBox::GetZHalfLength() const
{
return fDz;
}
inline double UBox::Capacity()
{
if (fCubicVolume != 0.)
{
;
}
else
{
fCubicVolume = 8 * fDx * fDy * fDz;
}
return fCubicVolume;
}
inline double UBox::SurfaceArea()
{
if (fSurfaceArea != 0.)
{
;
}
else
{
fSurfaceArea = 8 * (fDx * fDy + fDx * fDz + fDy * fDz);
}
return fSurfaceArea;
}
#endif
+211
View File
@@ -0,0 +1,211 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UCons
//
// Class description:
//
// A UCons is, in the general case, a Phi segment of a cone, with
// half-length fDz, inner and outer radii specified at -fDz and +fDz.
// The Phi segment is described by a starting fSPhi angle, and the
// +fDPhi delta angle for the shape.
// If the delta angle is >=2*UUtils::kPi, the shape is treated as
// continuous in Phi
//
// Member Data:
//
// fRmin1 inside radius at -fDz
// fRmin2 inside radius at +fDz
// fRmax1 outside radius at -fDz
// fRmax2 outside radius at +fDz
// fDz half length in z
//
// fSPhi starting angle of the segment in radians
// fDPhi delta angle of the segment in radians
//
// fPhiFullCone Boolean variable used for indicate the Phi Section
//
// Note:
// Internally fSPhi & fDPhi are adjusted so that fDPhi<=2PI,
// and fDPhi+fSPhi<=2PI. This enables simpler comparisons to be
// made with (say) Phi of a point.
//
// 19.10.12 Marek Gayer
// Created from original implementation in Geant4
// --------------------------------------------------------------------
#ifndef UCons_HH
#define UCons_HH
#include "VUSolid.hh"
class UCons : public VUSolid
{
public: // with description
UCons(const std::string& pName,
double pRmin1, double pRmax1,
double pRmin2, double pRmax2,
double pDz,
double pSPhi, double pDPhi);
//
// Constructs a cone with the given name and dimensions
~UCons() ;
//
// Destructor
// Accessors
inline double GetInnerRadiusMinusZ() const;
inline double GetOuterRadiusMinusZ() const;
inline double GetInnerRadiusPlusZ() const;
inline double GetOuterRadiusPlusZ() const;
inline double GetZHalfLength() const;
inline double GetStartPhiAngle() const;
inline double GetDeltaPhiAngle() const;
// Modifiers
inline void SetInnerRadiusMinusZ(double Rmin1);
inline void SetOuterRadiusMinusZ(double Rmax1);
inline void SetInnerRadiusPlusZ(double Rmin2);
inline void SetOuterRadiusPlusZ(double Rmax2);
inline void SetZHalfLength(double newDz);
inline void SetStartPhiAngle(double newSPhi, bool trig = true);
inline void SetDeltaPhiAngle(double newDPhi);
// Other methods for solid
inline double Capacity();
inline double SurfaceArea();
// inline VUSolid::EnumInside Inside( const UVector3& p ) const;
bool Normal(const UVector3& p, UVector3& n) const;
double DistanceToIn(const UVector3& p, const UVector3& v, double aPstep = UUtils::kInfinity) const;
double SafetyFromOutside(const UVector3& p, bool precise = false) const;
double DistanceToOut(const UVector3& aPoint,
const UVector3& aDirection,
UVector3& aNormalVector,
bool& aConvex,
double aPstep = UUtils::kInfinity) const;
double SafetyFromInside(const UVector3& p, bool precise = false) const;
UGeometryType GetEntityType() const;
UVector3 GetPointOnSurface() const;
VUSolid* Clone() const;
std::ostream& StreamInfo(std::ostream& os) const;
// void Extent (EAxisType aAxis, double &aMin, double &aMax) const;
void Extent(UVector3& aMin, UVector3& aMax) const;
virtual void GetParametersList(int /*aNumber*/, double* /*aArray*/) const;
virtual void ComputeBBox(UBBox* /*aBox*/, bool /*aStore = false*/) {}
// Safety used for UPolycone
inline double SafetyToPhi(const UVector3& p,
const double rho, bool& outside) const;
inline double SafetyFromInsideR(const UVector3& p,
const double rho,bool) const;
inline double SafetyFromOutsideR(const UVector3& p,
const double rho,bool) const;
inline VUSolid::EnumInside Inside(const UVector3& p) const;
public: // without description
UCons();
//
// Fake default constructor for usage restricted to direct object
// persistency for clients requiring preallocation of memory for
// persistifiable objects.
UCons(const UCons& rhs);
UCons& operator=(const UCons& rhs);
// Copy constructor and assignment operator.
// Old access functions
inline double GetRmin1() const;
inline double GetRmax1() const;
inline double GetRmin2() const;
inline double GetRmax2() const;
inline double GetDz() const;
inline double GetSPhi() const;
inline double GetDPhi() const;
private:
double fCubicVolume, fSurfaceArea;
inline void Initialize();
//
// Reset relevant values to zero
inline void CheckSPhiAngle(double sPhi);
inline void CheckDPhiAngle(double dPhi);
inline void CheckPhiAngles(double sPhi, double dPhi);
//
// Reset relevant flags and angle values
inline void InitializeTrigonometry();
//
// Recompute relevant trigonometric values and cache them
UVector3 ApproxSurfaceNormal(const UVector3& p) const;
//
// Algorithm for SurfaceNormal() following the original
// specification for points not on the surface
private:
// Used by distanceToOut
//
enum ESide {kNull, kRMin, kRMax, kSPhi, kEPhi, kPZ, kMZ};
// used by normal
//
enum ENorm {kNRMin, kNRMax, kNSPhi, kNEPhi, kNZ};
double kRadTolerance, kAngTolerance;
//
// Radial and angular tolerances
double fRmin1, fRmin2, fRmax1, fRmax2, fDz, fSPhi, fDPhi;
//
// Radial and angular dimensions
double sinCPhi, cosCPhi, cosHDPhiOT, cosHDPhiIT,
sinSPhi, cosSPhi, sinEPhi, cosEPhi;
//
// Cached trigonometric values
bool fPhiFullCone;
//
// Flag for identification of section or full cone
double secRMin, tanRMin, tanRMax, secRMax;
};
#include "UCons.icc"
#endif
+509
View File
@@ -0,0 +1,509 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UCons.icc
//
// Implementation of inline methods of UCons
//
// 19.10.12 Marek Gayer
// Created from original implementation in Geant4
// --------------------------------------------------------------------
inline
double UCons::GetInnerRadiusMinusZ() const
{
return fRmin1 ;
}
inline
double UCons::GetOuterRadiusMinusZ() const
{
return fRmax1 ;
}
inline
double UCons::GetInnerRadiusPlusZ() const
{
return fRmin2 ;
}
inline
double UCons::GetOuterRadiusPlusZ() const
{
return fRmax2 ;
}
inline
double UCons::GetZHalfLength() const
{
return fDz ;
}
inline
double UCons::GetStartPhiAngle() const
{
return fSPhi ;
}
inline
double UCons::GetDeltaPhiAngle() const
{
return fDPhi;
}
inline
void UCons::Initialize()
{
fCubicVolume = 0.;
fSurfaceArea = 0.;
tanRMin = (fRmin2 - fRmin1) * 0.5 / fDz;
secRMin = std::sqrt(1.0 + tanRMin * tanRMin);
tanRMax = (fRmax2 - fRmax1) * 0.5 / fDz;
secRMax = std::sqrt(1.0 + tanRMax * tanRMax);
}
inline
void UCons::InitializeTrigonometry()
{
double hDPhi = 0.5 * fDPhi; // half delta phi
double cPhi = fSPhi + hDPhi;
double 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 UCons::CheckSPhiAngle(double sPhi)
{
// Ensure fSphi in 0-2PI or -2PI-0 range if shape crosses 0
if (sPhi < 0)
{
fSPhi = 2 * UUtils::kPi - std::fmod(std::fabs(sPhi), 2 * UUtils::kPi);
}
else
{
fSPhi = std::fmod(sPhi, 2 * UUtils::kPi) ;
}
if (fSPhi + fDPhi > 2 * UUtils::kPi)
{
fSPhi -= 2 * UUtils::kPi ;
}
}
inline void UCons::CheckDPhiAngle(double dPhi)
{
fPhiFullCone = true;
if (dPhi >= 2 * UUtils::kPi - kAngTolerance * 0.5)
{
fDPhi = 2 * UUtils::kPi;
fSPhi = 0;
}
else
{
fPhiFullCone = false;
if (dPhi > 0)
{
fDPhi = dPhi;
}
else
{
std::ostringstream message;
message << "Invalid dphi." << std::endl
<< "Negative or zero delta-Phi (" << dPhi << ") in solid: "
<< GetName();
UUtils::Exception("UCons::CheckDPhiAngle()", "GeomSolids0002",
FatalErrorInArguments, 1, message.str().c_str());
}
}
}
inline void UCons::CheckPhiAngles(double sPhi, double dPhi)
{
CheckDPhiAngle(dPhi);
if ((fDPhi < 2 * UUtils::kPi) && (sPhi))
{
CheckSPhiAngle(sPhi);
}
InitializeTrigonometry();
}
inline
void UCons::SetInnerRadiusMinusZ(double Rmin1)
{
fRmin1 = Rmin1 ;
Initialize();
}
inline
void UCons::SetOuterRadiusMinusZ(double Rmax1)
{
fRmax1 = Rmax1 ;
Initialize();
}
inline
void UCons::SetInnerRadiusPlusZ(double Rmin2)
{
fRmin2 = Rmin2 ;
Initialize();
}
inline
void UCons::SetOuterRadiusPlusZ(double Rmax2)
{
fRmax2 = Rmax2 ;
Initialize();
}
inline
void UCons::SetZHalfLength(double newDz)
{
fDz = newDz ;
Initialize();
}
inline
void UCons::SetStartPhiAngle(double newSPhi, bool compute)
{
// Flag 'compute' can be used to explicitely avoid recomputation of
// trigonometry in case SetDeltaPhiAngle() is invoked afterwards
CheckSPhiAngle(newSPhi);
fPhiFullCone = false;
if (compute)
{
InitializeTrigonometry();
}
Initialize();
}
void UCons::SetDeltaPhiAngle(double newDPhi)
{
CheckPhiAngles(fSPhi, newDPhi);
Initialize();
}
// Old access methods ...
inline
double UCons::GetRmin1() const
{
return GetInnerRadiusMinusZ();
}
inline
double UCons::GetRmax1() const
{
return GetOuterRadiusMinusZ();
}
inline
double UCons::GetRmin2() const
{
return GetInnerRadiusPlusZ();
}
inline
double UCons::GetRmax2() const
{
return GetOuterRadiusPlusZ();
}
inline
double UCons::GetDz() const
{
return GetZHalfLength();
}
inline
double UCons::GetSPhi() const
{
return GetStartPhiAngle();
}
inline
double UCons::GetDPhi() const
{
return GetDeltaPhiAngle();
}
inline
double UCons::Capacity()
{
if (fCubicVolume != 0.)
{
;
}
else
{
double Rmean, rMean, deltaR, deltar;
Rmean = 0.5 * (fRmax1 + fRmax2);
deltaR = fRmax1 - fRmax2;
rMean = 0.5 * (fRmin1 + fRmin2);
deltar = fRmin1 - fRmin2;
fCubicVolume = fDPhi * fDz * (Rmean * Rmean - rMean * rMean
+ (deltaR * deltaR - deltar * deltar) / 12);
}
return fCubicVolume;
}
inline
double UCons::SurfaceArea()
{
if (fSurfaceArea != 0.)
{
;
}
else
{
double mmin, mmax, dmin, dmax;
mmin = (fRmin1 + fRmin2) * 0.5;
mmax = (fRmax1 + fRmax2) * 0.5;
dmin = (fRmin2 - fRmin1);
dmax = (fRmax2 - fRmax1);
fSurfaceArea = fDPhi * (mmin * std::sqrt(dmin * dmin + 4 * fDz * fDz)
+ mmax * std::sqrt(dmax * dmax + 4 * fDz * fDz)
+ 0.5 * (fRmax1 * fRmax1 - fRmin1 * fRmin1
+ fRmax2 * fRmax2 - fRmin2 * fRmin2));
if (!fPhiFullCone)
{
fSurfaceArea = fSurfaceArea + 4 * fDz * (mmax - mmin);
}
}
return fSurfaceArea;
}
inline
double UCons::SafetyToPhi(const UVector3& p,
const double rho, bool& outside) const
{
double cosPsi, safePhi = 0.0;
outside = false;
cosPsi = (p.x * cosCPhi + p.y * sinCPhi) / rho;
if (cosPsi < std::cos(fDPhi * 0.5)) // Point lies outside phi range
{
outside = true;
if ((p.y * cosCPhi - p.x * sinCPhi) <= 0.0)
{
safePhi = std::fabs(p.x * std::sin(fSPhi) - p.y * std::cos(fSPhi));
}
else
{
safePhi = std::fabs(p.x * sinEPhi - p.y * cosEPhi);
}
}
return safePhi;
}
inline
double UCons::SafetyFromInsideR(const UVector3& p,
const double rho, bool) const
{
double safe = 0.0, safeR1, safeR2, safePhi;
double pRMin;
double pRMax;
if (fRmin1 || fRmin2)
{
pRMin = tanRMin * p.z + (fRmin1 + fRmin2) * 0.5;
safeR1 = (rho - pRMin) / secRMin;
}
else
{
safeR1 = UUtils::kInfinity;
}
pRMax = tanRMax * p.z + (fRmax1 + fRmax2) * 0.5;
safeR2 = (pRMax - rho) / secRMax;
if (safeR1 < safeR2)
{
safe = safeR1;
}
else
{
safe = safeR2;
}
// Check if phi divided, Calc distances closest phi plane
//
if (!fPhiFullCone)
{
// Above/below central phi of UCons?
if ((p.y * cosCPhi - p.x * sinCPhi) <= 0)
{
safePhi = -(p.x * sinSPhi - p.y * cosSPhi);
}
else
{
safePhi = (p.x * sinEPhi - p.y * cosEPhi);
}
if (safePhi < safe)
{
safe = safePhi;
}
}
if (safe < 0)
{
safe = 0;
}
return safe;
}
inline
double UCons::SafetyFromOutsideR(const UVector3& p,
const double rho, bool) const
{
double safe = 0.0, safeR1, safeR2;
double safePhi;
double pRMin, pRMax;
bool outside;
if (fRmin1 || fRmin2)
{
pRMin = tanRMin * p.z + (fRmin1 + fRmin2) * 0.5;
safeR1 = (rho-pRMin ) / secRMin;
pRMax = tanRMax * p.z + (fRmax1 + fRmax2) * 0.5;
safeR2 = (rho - pRMax) / secRMax;
if (safeR1 > safeR2)
{
safe = safeR1;
}
else
{
safe = safeR2;
}
}
else
{
pRMax = tanRMax * p.z + (fRmax1 + fRmax2) * 0.5;
safe = (rho - pRMax) / secRMax;
}
if (!fPhiFullCone)
{
safePhi=SafetyToPhi(p,rho,outside);
if ((outside) && (safePhi > safe))
{
safe = safePhi;
}
}
if (safe < 0.0)
{
safe = 0.0;
}
return safe; // not accurate safety
}
inline
VUSolid::EnumInside UCons::Inside(const UVector3& p) const
{
double r2, rl, rh, pPhi, tolRMin, tolRMax; // rh2, rl2;
VUSolid::EnumInside in;
static const double halfCarTolerance = VUSolid::Tolerance() * 0.5;
static const double halfRadTolerance = kRadTolerance * 0.5;
static const double halfAngTolerance = kAngTolerance * 0.5;
if (std::fabs(p.z) > fDz + halfCarTolerance)
{
return in = eOutside;
}
else if (std::fabs(p.z) >= fDz - halfCarTolerance)
{
in = eSurface;
}
else
{
in = eInside;
}
r2 = p.x * p.x + p.y * p.y;
rl = 0.5 * (fRmin2 * (p.z + fDz) + fRmin1 * (fDz - p.z)) / fDz;
rh = 0.5 * (fRmax2 * (p.z + fDz) + fRmax1 * (fDz - p.z)) / fDz;
tolRMin = rl - halfRadTolerance;
if (tolRMin < 0)
{
tolRMin = 0;
}
tolRMax = rh + halfRadTolerance;
if ((r2 < tolRMin * tolRMin) || (r2 > tolRMax * tolRMax))
{
return in = eOutside;
}
if (rl)
{
tolRMin = rl + halfRadTolerance;
}
else
{
tolRMin = 0.0;
}
tolRMax = rh - halfRadTolerance;
if (in == eInside) // else it's eSurface already
{
if ((r2 < tolRMin * tolRMin) || (r2 >= tolRMax * tolRMax))
{
in = eSurface;
}
}
if (!fPhiFullCone && ((p.x != 0.0) || (p.y != 0.0)))
{
pPhi = std::atan2(p.y, p.x);
if (pPhi < fSPhi - halfAngTolerance)
{
pPhi += 2 * UUtils::kPi;
}
else if (pPhi > fSPhi + fDPhi + halfAngTolerance)
{
pPhi -= 2 * UUtils::kPi;
}
if ((pPhi < fSPhi - halfAngTolerance) ||
(pPhi > fSPhi + fDPhi + halfAngTolerance))
{
return in = eOutside;
}
else if (in == eInside) // else it's eSurface anyway already
{
if ((pPhi < fSPhi + halfAngTolerance) ||
(pPhi > fSPhi + fDPhi - halfAngTolerance))
{
in = eSurface;
}
}
}
else if (!fPhiFullCone)
{
in = eSurface;
}
return in;
}
+76
View File
@@ -0,0 +1,76 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UEnclosingCylinder
//
// Class description:
//
// Definition of a utility class for quickly deciding if a point
// is clearly outside a polyhedra or polycone or deciding if
// a trajectory is clearly going to miss those shapes.
//
// 19.10.12 Marek Gayer
// Created from original implementation in Geant4
// --------------------------------------------------------------------
#ifndef UEnclosingCylinder_hh
#define UEnclosingCylinder_hh
#include "UTypes.hh"
#include "UTubs.hh"
class UReduciblePolygon;
class UEnclosingCylinder
{
public: // with description
UEnclosingCylinder(/*const UReduciblePolygon *rz*/ double r, double lo, double hi,
bool phiIsOpen,
double startPhi, double totalPhi);
~UEnclosingCylinder();
bool MustBeOutside(const UVector3& p) const;
// Decide very rapidly if the point is outside the cylinder.
// If one is not certain, return false.
bool ShouldMiss(const UVector3& p, const UVector3& v) const;
// Decide very rapidly if the trajectory is going to miss the cylinder.
// If one is not sure, return false.
double DistanceTo(const UVector3& p, const UVector3& v) const;
double SafetyFromOutside(const UVector3& p) const;
public: // without description
void Extent(UVector3& aMin, UVector3& aMax) const;
double radius; // radius of our cylinder
protected:
double zLo, zHi; // z extent
bool phiIsOpen; // true if there is a phi segment
double startPhi, // for isPhiOpen==true, starting of phi segment
totalPhi; // for isPhiOpen==true, size of phi segment
double rx1, ry1,
dx1, dy1;
double rx2, ry2,
dx2, dy2;
bool concave; // true, if x/y Cross section is concave
UTubs* tube;
};
#endif
+173
View File
@@ -0,0 +1,173 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UExtrudedSolid
//
// Class description:
//
// UExtrudedSolid is a solid which represents the extrusion of an arbitrary
// polygon with fixed outline in the defined Z sections.
// The z-sides of the solid are the scaled versions of the same polygon.
// The solid is implemented as a specification of UTessellatedSolid.
//
// Parameters in the constructor:
// const std::tring& pName - solid name
// std::vector<UVector2> polygon - the vertices of the outlined polygon
// defined in clockwise or anti-clockwise
// order
// std::vector<ZSection> - the z-sections defined by
// z position, offset and scale
// in increasing z-position order
//
// Parameters in the special constructor (for solid with 2 z-sections:
// double halfZ - the solid half length in Z
// UVector2 off1 - offset of the side in -halfZ
// double scale1 - scale of the side in -halfZ
// UVector2 off2 - offset of the side in +halfZ
// double scale2 - scale of the side in -halfZ
//
// 13.08.13 Tatiana Nikitina
// Created from original implementation in Geant4
// --------------------------------------------------------------------
#ifndef USOLIDS_UExtrudedSolid_HH
#define USOLIDS_UExtrudedSolid_HH
//#include <vector>
//#include "VUSolid.hh"
//#include "UUtils.hh"
#include "UTessellatedSolid.hh"
#include "UVector2.hh"
class VUFacet;
class UExtrudedSolid : public UTessellatedSolid
{
public:
struct ZSection
{
ZSection(double z, UVector2 offset, double scale)
: fZ(z), fOffset(offset), fScale(scale) {}
double fZ;
UVector2 fOffset;
double fScale;
};
public:
UExtrudedSolid(const std::string& pName,
std::vector<UVector2> polygon,
std::vector<ZSection> zsections);
// General constructor
UExtrudedSolid(const std::string& pName,
std::vector<UVector2> polygon,
double halfZ,
UVector2 off1, double scale1,
UVector2 off2, double scale2);
// Special constructor for solid with 2 z-sections
virtual ~UExtrudedSolid();
// Destructor
// Accessors
inline int GetNofVertices() const;
inline UVector2 GetVertex(int index) const;
inline std::vector<UVector2> GetPolygon() const;
inline int GetNofZSections() const;
inline ZSection GetZSection(int index) const;
inline std::vector<ZSection> GetZSections() const;
// Solid methods
EnumInside Inside(const UVector3& aPoint) const;
double DistanceToOut(const UVector3& aPoint,
const UVector3& aDirection,
UVector3& aNormalVector,
bool& aConvex,
double aPstep = UUtils::kInfinity) const;
double SafetyFromInside(const UVector3& aPoint,
bool aAccurate = false) const;
UGeometryType GetEntityType() const
{
return "ExtrudedSolid";
}
VUSolid* Clone() const;
std::ostream& StreamInfo(std::ostream& os) const;
public:
UExtrudedSolid();
// Fake default constructor for usage restricted to direct object
// persistency for clients requiring preallocation of memory for
// persistifiable objects.
UExtrudedSolid(const UExtrudedSolid& rhs);
UExtrudedSolid& operator=(const UExtrudedSolid& rhs);
// Copy constructor and assignment operator.
void Initialise(std::vector<UVector2>& polygon,
std::vector<ZSection>& zsections);
void Initialise(std::vector<UVector2>& polygon, double dz,
UVector2 off1, double scale1,
UVector2 off2, double scale2);
// Initialisation methods for constructors.
private:
void ComputeProjectionParameters();
UVector3 GetVertex(int iz, int ind) const;
UVector2 ProjectPoint(const UVector3& point) const;
bool IsSameLine(UVector2 p,
UVector2 l1, UVector2 l2) const;
bool IsSameLineSegment(UVector2 p,
UVector2 l1, UVector2 l2) const;
bool IsSameSide(UVector2 p1, UVector2 p2,
UVector2 l1, UVector2 l2) const;
bool IsPointInside(UVector2 a, UVector2 b, UVector2 c,
UVector2 p) const;
double GetAngle(UVector2 p0, UVector2 pa, UVector2 pb) const;
VUFacet* MakeDownFacet(int ind1, int ind2, int ind3) const;
VUFacet* MakeUpFacet(int ind1, int ind2, int ind3) const;
bool AddGeneralPolygonFacets();
bool MakeFacets();
bool IsConvex() const;
private:
int fNv;
int fNz;
std::vector<UVector2> fPolygon;
std::vector<ZSection> fZSections;
std::vector< std::vector<int> > fTriangles;
bool fIsConvex;
UGeometryType fGeometryType;
std::vector<double> fKScales;
std::vector<double> fScale0s;
std::vector<UVector2> fKOffsets;
std::vector<UVector2> fOffset0s;
};
#include "UExtrudedSolid.icc"
#endif
+64
View File
@@ -0,0 +1,64 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UExtrudedSolid.icc
//
// Implementation of inline methods of UExtrudedSolid
//
// 13.08.13 Tatiana Nikitina
// Created from original implementation in Geant4
// --------------------------------------------------------------------
inline
int UExtrudedSolid::GetNofVertices() const
{
return fNv;
}
inline UVector2 UExtrudedSolid::GetVertex(int index) const
{
if (index < 0 || index >= fNv)
{
UUtils::Exception ("UExtrudedSolid::GetVertex()", "GeomSolids0003",
FatalError, 1, "Index outside range.");
return UVector2();
}
return fPolygon[index];
}
inline
std::vector<UVector2> UExtrudedSolid::GetPolygon() const
{
return fPolygon;
}
inline
int UExtrudedSolid::GetNofZSections() const
{
return fNz;
}
inline
UExtrudedSolid::ZSection UExtrudedSolid::GetZSection(int index) const
{
if (index < 0 || index >= fNz)
{
UUtils::Exception ("UExtrudedSolid::GetZSection()", "GeomSolids0003",
FatalError, 1, "Index outside range.");
return ZSection(0.0, UVector2(), 0.0);
}
return fZSections[index];
}
inline
std::vector<UExtrudedSolid::ZSection> UExtrudedSolid::GetZSections() const
{
return fZSections;
}
+147
View File
@@ -0,0 +1,147 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UGenericPolycone
//
// Class description:
//
// Implementing a CSG-like type "PCON" volume with possibility of
// specifying also 'decreasing' Z sections:
//
// UGenericPolycone( 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
//
// 19.10.13 Tatiana Nikitina
// Created from original implementation in Geant4
// --------------------------------------------------------------------
#ifndef UGenericPolycone_hh
#define UGenericPolycone_hh
#include "UVCSGfaceted.hh"
#include "UPolyconeSide.hh"
class UEnclosingCylinder;
class UReduciblePolygon;
class UVCSGface;
class UGenericPolycone: public UVCSGfaceted
{
public: // with description
UGenericPolycone(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
UGenericPolycone(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 ~UGenericPolycone();
// Methods for solid
VUSolid::EnumInside Inside(const UVector3& p) const;
double DistanceToIn(const UVector3& p, const UVector3& v, double aPstep = UUtils::kInfinity) const;
// double SafetyFromOutside( const UVector3 &p, bool aAccurate=false) const;
UVector3 GetPointOnSurface() const;
/*
void ComputeDimensions( UVPVParameterisation* p,
const int n,
const UVPhysicalVolume* pRep );
*/
UGeometryType GetEntityType() const;
VUSolid* Clone() const;
std::ostream& StreamInfo(std::ostream& os) const;
bool Reset();
// Accessors
inline double GetStartPhi() const;
inline double GetEndPhi() const;
inline bool IsOpen() const;
inline int GetNumRZCorner() const;
inline UPolyconeSideRZ GetCorner(int index) const;
public: // without description
//UPolycone(__void__&);
// Fake default constructor for usage restricted to direct object
// persistency for clients requiring preallocation of memory for
// persistifiable objects.
UGenericPolycone(const UGenericPolycone& source);
UGenericPolycone& operator=(const UGenericPolycone& source);
// Copy constructor and assignment operator.
protected: // without description
// Generic initializer, called by all constructors
void Create(double phiStart, // initial phi starting angle
double phiTotal, // total phi angle
UReduciblePolygon* rz); // r/z coordinate of these corners
void CopyStuff(const UGenericPolycone& source);
// Methods for random point generation
void GetParametersList(int /*aNumber*/, double* /*aArray*/) const {}
void ComputeBBox(UBBox* /*aBox*/, bool /*aStore*/)
{
// Computes bounding box.
std::cout << "ComputeBBox - Not implemented" << std::endl;
}
void Extent(UVector3& aMin, UVector3& aMax) const;
protected: // without description
// 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
// Our quick test
UEnclosingCylinder* enclosingCylinder;
};
#include "UGenericPolycone.icc"
#endif
+49
View File
@@ -0,0 +1,49 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UGenericPolycone.icc
//
// Implementation of inline methods of UGenericPolycone
//
// 19.10.13 Tatiana Nikitina
// Created from original implementation in Geant4
// --------------------------------------------------------------------
inline
double UGenericPolycone::GetStartPhi() const
{
return startPhi;
}
inline
double UGenericPolycone::GetEndPhi() const
{
return endPhi;
}
inline
bool UGenericPolycone::IsOpen() const
{
return phiIsOpen;
}
inline
int UGenericPolycone::GetNumRZCorner() const
{
return numCorner;
}
inline
UPolyconeSideRZ UGenericPolycone::GetCorner(int index) const
{
return corners[index];
}
+201
View File
@@ -0,0 +1,201 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UGenericTrap
//
// Class description:
//
// UGenericTrap is a solid which represents an arbitrary trapezoid with
// up to 8 vertices standing on two parallel planes perpendicular to Z axis.
//
// Parameters in the constructor:
// - name - solid name
// - halfZ - the solid half length in Z
// - vertices - the (x,y) coordinates of vertices:
// o first four points: vertices[i], i<4
// are the vertices sitting on the -halfZ plane;
// o last four points: vertices[i], i>=4
// are the vertices sitting on the +halfZ plane.
//
// The order of defining the vertices of the solid is the following:
// - point 0 is connected with points 1,3,4
// - point 1 is connected with points 0,2,5
// - point 2 is connected with points 1,3,6
// - point 3 is connected with points 0,2,7
// - point 4 is connected with points 0,5,7
// - point 5 is connected with points 1,4,6
// - point 6 is connected with points 2,5,7
// - point 7 is connected with points 3,4,6
// Points can be identical in order to create shapes with less than
// 8 vertices.
//
// 21.10.13 Tatiana Nikitina, CERN; Ivana Hrivnacova, IPN Orsay
// Adapted from Root Arb8 implementation
// --------------------------------------------------------------------
#ifndef USOLIDS_UGenericTrap_HH
#define USOLIDS_UGenericTrap_HH
#ifndef USOLIDS_VUSolid
#include "VUSolid.hh"
#endif
#ifndef USOLIDS_UUtils
#include "UUtils.hh"
#endif
#include <vector>
#include "UVector2.hh"
class VUFacet;
class UTessellatedSolid;
class UBox;
class UGenericTrap : public VUSolid
{
public: // with description
UGenericTrap(const std::string& name, double halfZ,
const std::vector<UVector2>& vertices);
// Constructor
~UGenericTrap();
// Destructor
// Accessors
inline double GetZHalfLength() const;
inline void SetZHalfLength(double);
inline int GetNofVertices() const;
inline UVector2 GetVertex(int index) const;
inline const std::vector<UVector2>& GetVertices() const;
inline double GetTwistAngle(int index) const;
inline bool IsTwisted() const;
inline int GetVisSubdivisions() const;
inline void SetVisSubdivisions(int subdiv);
// Solid methods
EnumInside Inside(const UVector3& aPoint) const;
bool Normal(const UVector3& aPoint, UVector3& aNormal) const;
double SafetyFromInside(const UVector3& aPoint,
bool aAccurate = false) const;
double SafetyFromOutside(const UVector3& aPoint,
bool aAccurate = false) const;
double DistanceToIn(const UVector3& aPoint,
const UVector3& aDirection,
double aPstep = UUtils::kInfinity) const;
double DistanceToOut(const UVector3& aPoint,
const UVector3& aDirection,
UVector3& aNormalVector,
bool& aConvex,
double aPstep = UUtils::kInfinity) const;
void Extent(UVector3& aMin, UVector3& aMax) const;
double Capacity() ;
double SurfaceArea() ;
VUSolid* Clone() const ;
inline UGeometryType GetEntityType() const { return "GenericTrap"; }
inline void ComputeBBox(UBBox* /*aBox*/, bool /*aStore = false*/) {}
inline void GetParametersList(int /*aNumber*/, double* /*aArray*/) const {}
UVector3 GetPointOnSurface() const;
std::ostream& StreamInfo(std::ostream& os) const;
public:
UGenericTrap();
// Fake default constructor for usage restricted to direct object
// persistency for clients requiring preallocation of memory for
// persistifiable objects.
UGenericTrap(const UGenericTrap& rhs);
UGenericTrap& operator=(const UGenericTrap& rhs);
// Copy constructor and assignment operator.
void Initialise(const std::vector<UVector2>& vertices);
inline UVector3 GetMinimumBBox() const;
inline UVector3 GetMaximumBBox() const;
private:
// Internal methods
inline void SetTwistAngle(int index, double twist);
bool ComputeIsTwisted() ;
bool CheckOrder(const std::vector<UVector2>& vertices) const;
bool IsSegCrossing(const UVector2& a, const UVector2& b,
const UVector2& c, const UVector2& d) const;
bool IsSegCrossingZ(const UVector2& a, const UVector2& b,
const UVector2& c, const UVector2& d) const;
bool IsSameLineSegment(const UVector2& p,
const UVector2& l1, const UVector2& l2) const;
bool IsSameLine(const UVector2& p,
const UVector2& l1, const UVector2& l2) const;
void ReorderVertices(std::vector<UVector3>& vertices) const;
void ComputeBBox();
VUFacet* MakeDownFacet(const std::vector<UVector3>& fromVertices,
int ind1, int ind2, int ind3) const;
VUFacet* MakeUpFacet(const std::vector<UVector3>& fromVertices,
int ind1, int ind2, int ind3) const;
VUFacet* MakeSideFacet(const UVector3& downVertex0,
const UVector3& downVertex1,
const UVector3& upVertex1,
const UVector3& upVertex0) const;
UTessellatedSolid* CreateTessellatedSolid() const;
EnumInside InsidePolygone(const UVector3& p,
const UVector2* poly)const;
double DistToPlane(const UVector3& p,
const UVector3& v, const int ipl) const ;
double DistToTriangle(const UVector3& p,
const UVector3& v, const int ipl) const;
UVector3 NormalToPlane(const UVector3& p,
const int ipl) const;
double SafetyToFace(const UVector3& p, const int iseg) const;
double GetFaceSurfaceArea(const UVector3& p0,
const UVector3& p1,
const UVector3& p2,
const UVector3& p3) const;
private:
// static data members
static const int fgkNofVertices;
static const double fgkTolerance;
// data members
double fDz;
std::vector<UVector2> fVertices;
bool fIsTwisted;
double fTwist[4];
UTessellatedSolid* fTessellatedSolid;
UVector3 fMinBBoxVector;
UVector3 fMaxBBoxVector;
int fVisSubdivisions;
UBox* fBoundBox;
enum ESide {kUndefined, kXY0, kXY1, kXY2, kXY3, kMZ, kPZ};
// Codes for faces (kXY[num]=num of lateral face,kMZ= minus z face etc)
double fSurfaceArea;
double fCubicVolume;
// Surface and Volume
};
#include "UGenericTrap.icc"
#endif
+126
View File
@@ -0,0 +1,126 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UGenericTrap.icc
//
// 21.10.13 Tatiana Nikitina, CERN; Ivana Hrivnacova, IPN Orsay
// Adapted from Root Arb8 implementation
// --------------------------------------------------------------------
inline
double UGenericTrap::GetZHalfLength() const
{
return fDz;
}
inline
void UGenericTrap::SetZHalfLength(double halfZ)
{
fDz = halfZ;
}
// --------------------------------------------------------------------
inline
int UGenericTrap::GetNofVertices() const
{
return fVertices.size();
}
// --------------------------------------------------------------------
inline
UVector2 UGenericTrap::GetVertex(int index) const
{
if (index < 0 || index >= int(fVertices.size()))
{
UUtils::Exception("UGenericTrap::GetVertex()", "GeomSolids0003",
FatalError, 1, "Index outside range.");
}
return fVertices[index];
}
// --------------------------------------------------------------------
inline
const std::vector<UVector2>& UGenericTrap::GetVertices() const
{
return fVertices;
}
// --------------------------------------------------------------------
inline
double UGenericTrap::GetTwistAngle(int index) const
{
if ((index < 0) || (index >= int(fVertices.size())))
{
UUtils::Exception ("UGenericTrap::GetTwistAngle()", "GeomSolids0003",
FatalError, 1, "Index outside range.");
}
return fTwist[index];
}
// --------------------------------------------------------------------
inline
bool UGenericTrap::IsTwisted() const
{
return fIsTwisted;
}
// --------------------------------------------------------------------
inline
void UGenericTrap::SetTwistAngle(int index, double twist)
{
if ((index < 0) || (index >= int(fVertices.size())))
{
UUtils::Exception ("UGenericTrap::SetTwistAngle()", "GeomSolids0003",
FatalError, 1, "Index outside range.");
}
fTwist[index] = twist;
}
// --------------------------------------------------------------------
inline
int UGenericTrap::GetVisSubdivisions()const
{
return fVisSubdivisions;
}
// --------------------------------------------------------------------
inline
void UGenericTrap::SetVisSubdivisions(int subdiv)
{
fVisSubdivisions = subdiv;
}
// --------------------------------------------------------------------
inline
UVector3 UGenericTrap::GetMinimumBBox() const
{
return fMinBBoxVector;
}
// --------------------------------------------------------------------
inline
UVector3 UGenericTrap::GetMaximumBBox() const
{
return fMaxBBoxVector;
}
// --------------------------------------------------------------------
+91
View File
@@ -0,0 +1,91 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UIntersectingCone
//
// Class description:
//
// Utility class which calculates the intersection
// of an arbitrary line with a fixed cone
//
// 19.02.13 Marek Gayer
// Created from original implementation in Geant4
// --------------------------------------------------------------------
#ifndef UIntersectingCone_hh
#define UIntersectingCone_hh
#include "UTypes.hh"
class UIntersectingCone
{
public:
UIntersectingCone(const double r[2], const double z[2]);
virtual ~UIntersectingCone();
int LineHitsCone(const UVector3& p, const UVector3& v, double& s1, double& s2);
bool HitOn(const double r, const double z);
inline double RLo() const
{
return rLo;
}
inline double RHi() const
{
return rHi;
}
inline double ZLo() const
{
return zLo;
}
inline double ZHi() const
{
return zHi;
}
public: // without description
/*
UIntersectingCone(__void__&);
// Fake default constructor for usage restricted to direct object
// persistency for clients requiring preallocation of memory for
// persistifiable objects.
*/
protected:
double zLo, zHi, // Z bounds of side
rLo, rHi; // R bounds of side
bool type1; // True if cone is type 1
// (std::fabs(z1-z2)>std::fabs(r1-r2))
double A, B; // Cone radius parameter:
// type 1: r = A + B*z
// type 2: z = A + B*r
// int Solution (const UVector3 &p, const UVector3 &v, double a, double b, double c, double &s1, double &s2);
int LineHitsCone1(const UVector3& p, const UVector3& v,
double& s1, double& s2);
int LineHitsCone1Optimized(const UVector3& p, const UVector3& v,
double& s1, double& s2);
int LineHitsCone2(const UVector3& p, const UVector3& v,
double& s1, double& s2);
// const double kInfinity;
const static double EpsilonQuad;
};
#endif
+155
View File
@@ -0,0 +1,155 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UMultiUnion
//
// Class description:
//
// An instance of "UMultiUnion" constitutes a grouping of several solids
// deriving from the "VUSolid" mother class. The subsolids are stored with
// their respective location in an instance of "UNode". An instance of
// "UMultiUnion" is subsequently composed of one or several nodes.
//
// 19.10.12 Marek Gayer
// --------------------------------------------------------------------
#ifndef USOLIDS_UMultiUnion
#define USOLIDS_UMultiUnion
#include <vector>
#include "VUSolid.hh"
#include "UUtils.hh"
#include "UTransform3D.hh"
#include "UBits.hh"
#include "UVoxelizer.hh"
class UMultiUnion : public VUSolid
{
friend class UVoxelizer;
public:
UMultiUnion() : VUSolid() {}
UMultiUnion(const std::string& name);
~UMultiUnion();
// Build the multiple union by adding nodes
void AddNode(VUSolid& solid, UTransform3D& trans);
UMultiUnion(const UMultiUnion& rhs);
UMultiUnion& operator=(const UMultiUnion& rhs);
// Accessors
inline const UTransform3D& GetTransformation(int index) const;
inline VUSolid* GetSolid(int index) const;
inline int GetNumberOfSolids()const;
// Navigation methods
EnumInside Inside(const UVector3& aPoint) const;
EnumInside InsideIterator(const UVector3& aPoint) const;
double SafetyFromInside(const UVector3& aPoint,
bool aAccurate = false) const;
double SafetyFromOutside(const UVector3& aPoint,
bool aAccurate = false) const;
double DistanceToInNoVoxels(const UVector3& aPoint,
const UVector3& aDirection,
double aPstep = UUtils::kInfinity) const;
double DistanceToIn(const UVector3& aPoint,
const UVector3& aDirection,
double aPstep) const;
double DistanceToOut(const UVector3& aPoint,
const UVector3& aDirection,
UVector3& aNormalVector,
bool& aConvex,
double aPstep = UUtils::kInfinity) const;
double DistanceToOutVoxels(const UVector3& aPoint,
const UVector3& aDirection,
UVector3& aNormalVector,
bool& aConvex,
double aPstep = UUtils::kInfinity) const;
double DistanceToOutVoxelsCore(const UVector3& aPoint,
const UVector3& aDirection,
UVector3& aNormalVector,
bool& aConvex,
std::vector<int>& candidates) const;
double DistanceToOutNoVoxels(const UVector3& aPoint,
const UVector3& aDirection,
UVector3& aNormalVector,
bool& aConvex,
double aPstep = UUtils::kInfinity) const;
bool Normal(const UVector3& aPoint, UVector3& aNormal) const;
void Extent(EAxisType aAxis, double& aMin, double& aMax) const;
void Extent(UVector3& aMin, UVector3& aMax) const;
double Capacity();
double SurfaceArea();
VUSolid* Clone() const ;
UGeometryType GetEntityType() const { return "MultipleUnion"; }
void ComputeBBox(UBBox* aBox, bool aStore = false);
virtual void GetParametersList(int /*aNumber*/, double* /*aArray*/) const {}
// Finalize and prepare for use. User MUST call it once before
// navigation use.
void Voxelize();
EnumInside InsideNoVoxels(const UVector3& aPoint) const;
inline UVoxelizer& GetVoxels() const;
std::ostream& StreamInfo(std::ostream& os) const;
UVector3 GetPointOnSurface() const;
private:
void SetVoxelFinder(const UVoxelizer& finder);
EnumInside InsideWithExclusion(const UVector3& aPoint, UBits* bits = NULL) const;
int SafetyFromOutsideNumberNode(const UVector3& aPoint, bool aAccurate, double& safety) const;
double DistanceToInCandidates(const UVector3& aPoint, const UVector3& aDirection, double aPstep, std::vector<int>& candidates, UBits& bits) const;
std::vector<VUSolid*> fSolids;
std::vector<UTransform3D> fTransformObjs;
UVoxelizer fVoxels; // Pointer to the vozelized solid
double fCubicVolume; // Cubic Volume
double fSurfaceArea; // Surface Area
};
inline UVoxelizer& UMultiUnion:: GetVoxels() const
{
return (UVoxelizer&)fVoxels;
}
inline const UTransform3D& UMultiUnion::GetTransformation(int index) const
{
return fTransformObjs[index];
}
inline VUSolid* UMultiUnion::GetSolid(int index) const
{
return fSolids[index];
}
inline int UMultiUnion::GetNumberOfSolids()const
{
return fSolids.size();
}
#endif
+128
View File
@@ -0,0 +1,128 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UOrb
//
// Class description:
//
// A simple Orb defined by half-lengths on the three axis.
// The center of the Orb matches the origin of the local reference frame.
//
// 19.10.12 Marek Gayer
// Created from original implementation in Geant4
// --------------------------------------------------------------------
#ifndef USOLIDS_UOrb
#define USOLIDS_UOrb
#include "VUSolid.hh"
#include "UUtils.hh"
class UOrb : public VUSolid
{
public:
UOrb() : VUSolid(), fR(0), fRTolerance(0) {}
UOrb(const std::string& name, double pRmax);
~UOrb() {}
UOrb(const UOrb& rhs);
UOrb& operator=(const UOrb& rhs);
// Accessors
inline double GetRadius() const;
// Modifiers
inline void SetRadius(double newRmax);
// Navigation methods
EnumInside Inside(const UVector3& aPo6int) const;
double SafetyFromInside(const UVector3& aPoint,
bool aAccurate = false) const;
double SafetyFromOutside(const UVector3& aPoint,
bool aAccurate = false) const;
double DistanceToIn(const UVector3& aPoint,
const UVector3& aDirection,
double aPstep = UUtils::kInfinity) 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;
void Extent(UVector3& aMin, UVector3& aMax) const;
inline double Capacity();
inline double SurfaceArea();
UGeometryType GetEntityType() const;
void ComputeBBox(UBBox* /*aBox*/, bool /*aStore = false*/) {}
// Visualisation
void GetParametersList(int /*aNumber*/, double* /*aArray*/) const;
VUSolid* Clone() const;
double GetRadialTolerance()
{
return fRTolerance;
}
UVector3 GetPointOnSurface() const;
std::ostream& StreamInfo(std::ostream& os) const;
private:
double fR;
double fRTolerance;
double fCubicVolume; // Cubic Volume
double fSurfaceArea; // Surface Area
double DistanceToOutForOutsidePoints(const UVector3& p, const UVector3& v, UVector3& n) const;
};
inline double UOrb::GetRadius() const
{
return fR;
}
inline void UOrb::SetRadius(double newRmax)
{
fR = newRmax;
}
inline double UOrb::Capacity()
{
if (fCubicVolume != 0.)
{
;
}
else
{
fCubicVolume = (4 * UUtils::kPi / 3) * fR * fR * fR;
}
return fCubicVolume;
}
inline double UOrb::SurfaceArea()
{
if (fSurfaceArea != 0.)
{
;
}
else
{
fSurfaceArea = (4 * UUtils::kPi) * fR * fR;
}
return fSurfaceArea;
}
#endif
+221
View File
@@ -0,0 +1,221 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UPolyPhiFace
//
// Class description:
//
// Definition of a face that bounds a polycone or polyhedra when
// it has a phi opening:
//
// UPolyPhiFace( const UReduciblePolygon *rz,
// double phi,
// double deltaPhi,
// double phiOther )
//
// Specifically: a face that lies on a plane that passes through
// the z axis. It has boundaries that are straight lines of arbitrary
// length and direction, but with corners aways on the same side of
// the z axis.
//
// 19.10.12 Marek Gayer
// Created from original implementation in Geant4
// --------------------------------------------------------------------
#ifndef UPolyPhiFace_hh
#define UPolyPhiFace_hh
#include "UVCSGface.hh"
#include "UVector2.hh"
class UReduciblePolygon;
struct UPolyPhiFaceVertex
{
double x, y, r, z; // position
double rNorm,
zNorm; // r/z normal
UVector3 norm3D; // 3D normal
// Needed for Triangulation Algorithm
//
bool ear;
UPolyPhiFaceVertex* next, *prev;
};
struct UPolyPhiFaceEdge
{
UPolyPhiFaceEdge(): v0(0), v1(0), tr(.0), tz(0.), length(0.) {}
UPolyPhiFaceVertex* v0, *v1; // Corners
double tr, tz, // Unit vector along edge
length; // Length of edge
UVector3 norm3D; // 3D edge normal vector
};
class UPolyPhiFace : public UVCSGface
{
public: // with description
UPolyPhiFace(const UReduciblePolygon* rz,
double phi, double deltaPhi, double phiOther);
// Constructor.
// Points r,z should be supplied in clockwise order in r,z.
// For example:
// [1]---------[2] ^ R
// | | |
// | | +--> z
// [0]---------[3]
virtual ~UPolyPhiFace();
// Destructor. Removes edges and corners.
UPolyPhiFace(const UPolyPhiFace& source);
UPolyPhiFace& operator=(const UPolyPhiFace& source);
// Copy constructor and assgnment operator.
bool Distance(const UVector3& p, const UVector3& v,
bool outgoing, double surfTolerance,
double& distance, double& distFromSurface,
UVector3& normal, bool& allBehind);
double Safety(const UVector3& p, bool outgoing);
VUSolid::EnumInside Inside(const UVector3& p, double tolerance,
double* bestDistance);
UVector3 Normal(const UVector3& p, double* bestDistance);
double Extent(const UVector3 axis);
/*
void CalculateExtent( const EAxisType axis,
const UVoxelLimits &voxelLimit,
const UAffineTransform &tranform,
USolidExtentList &extentList );
*/
inline UVCSGface* Clone();
// Allocates on the heap a clone of this face.
double SurfaceArea();
double SurfaceTriangle(UVector3 p1, UVector3 p2,
UVector3 p3, UVector3* p4);
UVector3 GetPointOnFace();
// Auxiliary methods for determination of points on surface.
public: // without description
UPolyPhiFace(__void__&);
// Fake default constructor for usage restricted to direct object
// persistency for clients requiring preallocation of memory for
// persistifiable objects.
void Diagnose(VUSolid* solid);
// Throw an exception if something is found inconsistent with
// the solid. For debugging purposes only
protected:
bool InsideEdgesExact(double r, double z, double normSign,
const UVector3& p, const UVector3& v);
// Decide if the point in r,z is inside the edges of our face,
// **but** do so consistently with other faces.
bool InsideEdges(double r, double z);
bool InsideEdges(double r, double z, double* distRZ2,
UPolyPhiFaceVertex** base3Dnorm = 0,
UVector3** head3Dnorm = 0);
// Decide if the point in r,z is inside the edges of our face.
inline double ExactZOrder(double z,
double qx, double qy, double qz,
const UVector3& v,
double normSign,
const UPolyPhiFaceVertex* vert) const;
// Decide precisely whether a trajectory passes to the left, right,
// or exactly passes through the z position of a vertex point in face.
void CopyStuff(const UPolyPhiFace& source);
protected:
// Functions used for Triangulation in Case of generic Polygone.
// The triangulation is used for GetPointOnFace()
double Area2(UVector2 a, UVector2 b, UVector2 c);
// Calculation of 2*Area of Triangle with Sign
bool Left(UVector2 a, UVector2 b, UVector2 c);
bool LeftOn(UVector2 a, UVector2 b, UVector2 c);
bool Collinear(UVector2 a, UVector2 b, UVector2 c);
// Boolean functions for sign of Surface
bool IntersectProp(UVector2 a, UVector2 b,
UVector2 c, UVector2 d);
// Boolean function for finding proper intersection of two
// line segments (a,b) and (c,d).
bool Between(UVector2 a, UVector2 b, UVector2 c);
// Boolean function for determining if point c is between a and b
// where the three points (a,b,c) are on the same line.
bool Intersect(UVector2 a, UVector2 b,
UVector2 c, UVector2 d);
// Boolean function for finding proper intersection or not
// of two line segments (a,b) and (c,d).
bool Diagonalie(UPolyPhiFaceVertex* a, UPolyPhiFaceVertex* b);
// Boolean Diagonalie help to determine if diagonal s
// of segment (a,b) is convex or reflex.
bool InCone(UPolyPhiFaceVertex* a, UPolyPhiFaceVertex* b);
// Boolean function for determining if b is inside the cone (a0,a,a1)
// where a is the center of the cone.
bool Diagonal(UPolyPhiFaceVertex* a, UPolyPhiFaceVertex* b);
// Boolean function for determining if Diagonal is possible
// inside Polycone or PolyHedra.
void EarInit();
// Initialisation for Triangulisation by ear tips.
// For details see "Computational Geometry in C" by Joseph O'Rourke.
void Triangulate();
// Triangularisation by ear tips for Polycone or Polyhedra.
// For details see "Computational Geometry in C" by Joseph O'Rourke.
// NOTE: a copy of the shape is made and this copy is reordered in
// order to have a list of triangles. This list is used by the
// method GetPointOnFace().
protected:
int numEdges; // Number of edges
UPolyPhiFaceEdge* edges; // The edges of the face
UPolyPhiFaceVertex* corners; // And the corners
UVector3 normal; // Normal Unit vector
UVector3 radial; // Unit vector along radial direction
UVector3 surface; // Point on surface
UVector3 surface_point; // Auxiliary point on surface used for
// method GetPointOnFace()
double rMin, rMax, // Extent in r
zMin, zMax; // Extent in z
bool allBehind; // True if the polycone/polyhedra
// is behind the place of this face
double fTolerance;// Surface thickness
double fSurfaceArea; // Surface Area of PolyPhiFace
UPolyPhiFaceVertex* triangles; // Auxiliary pointer to 'corners' used for
// triangulation. Copy structure, changing
// the structure of 'corners' (ear removal)
};
#include "UPolyPhiFace.icc"
#endif
+54
View File
@@ -0,0 +1,54 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UPolyPhiFace.icc
//
// 19.10.12 Marek Gayer
// Created from original implementation in Geant4
// --------------------------------------------------------------------
inline
UVCSGface* UPolyPhiFace::Clone()
{
return new UPolyPhiFace(*this);
}
// ExactZOrder
//
// Decide precisely whether a trajectory passes to the left, right, or exactly
// passes through the z position of a vertex point in our face.
//
// Result is only determined within an arbitrary (positive) factor.
// > 0 to the right
// < 0 to the left
// = 0 exactly on top of
// In 99.9999% of the cases, a trivial calculation is used. In difficult
// cases, a precise, compliant calculation is relied on.
//
inline
double UPolyPhiFace::ExactZOrder(double z,
double qx, double qy, double qz,
const UVector3& v,
double normSign,
const UPolyPhiFaceVertex* vert) const
{
double answer = vert->z - z;
if (std::fabs(answer) < VUSolid::Tolerance())
{
UVector3 qa(qx - vert->x + radial.x,
qy - vert->y + radial.y, qz - vert->z),
qb(qx - vert->x, qy - vert->y, qz - vert->z);
UVector3 qacb = qa.Cross(qb);
answer = normSign * qacb.Dot(v) * (normal.y * radial.x - normal.x * radial.y);
}
return answer;
}
+336
View File
@@ -0,0 +1,336 @@
//
// ********************************************************************
// * 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 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
//
// Alternative constructor, but limited to increasing-only Z sections:
//
// 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
//
// 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"
#include "UBox.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*/) {}
// Visualisation
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
mutable UBox fBox; // Bounding box for Polycone
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 double rho,
const UVector3& p) const
{
const UPolyconeSection& section = fSections[index];
UVector3 ps(p.x, p.y, p.z - section.shift);
double res=0;
if (section.tubular)
{
UTubs* tubs = (UTubs*) section.solid;
res = tubs->SafetyFromInsideR(ps,rho, true);
}
else
{
UCons* cons = (UCons*) section.solid;
res = cons->SafetyFromInsideR(ps,rho, true);
}
return res;
}
// Auxiliary method used in SafetyFromInside for finding safety
// from section in R and Phi
//
inline double SafetyFromOutsideSection(int index, const double rho,
const UVector3& p) const
{
const UPolyconeSection& section = fSections[index];
UVector3 ps(p.x, p.y, p.z);
double res=0;
if (section.tubular)
{
UTubs* tubs = (UTubs*) section.solid;
res = tubs->SafetyFromOutsideR(ps,rho, true);
}
else
{
UCons* cons = (UCons*) section.solid;
res = cons->SafetyFromOutsideR(ps,rho, true);
}
return res;
}
// Auxiliary method used in SafetyFromOutside for finding safety
// from section
//
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=0;
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
+93
View File
@@ -0,0 +1,93 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UPolycone.icc
//
// Implementation of inline methods of UPolycone
//
// 19.04.13 Marek Gayer
// Created from original implementation in Geant4
// --------------------------------------------------------------------
inline
double UPolycone::GetStartPhi() const
{
return startPhi;
}
inline
double UPolycone::GetEndPhi() const
{
return endPhi;
}
inline
bool UPolycone::IsOpen() const
{
return phiIsOpen;
}
inline
bool UPolycone::IsGeneric() const
{
return false;
}
inline
int UPolycone::GetNumRZCorner() const
{
return numCorner;
}
inline
UPolyconeSideRZ UPolycone::GetCorner(int index) const
{
return corners[index];
}
inline
UPolyconeHistorical* UPolycone::GetOriginalParameters() const
{
return fOriginalParameters;
}
inline
void UPolycone::SetOriginalParameters(UPolyconeHistorical* pars)
{
if (!pars)
// UException("UPolycone::SetOriginalParameters()", "GeomSolids0002",
// FatalException, "NULL pointer to parameters!");
*fOriginalParameters = *pars;
fCubicVolume = 0.;
fpPolyhedron = 0;
}
inline
void UPolycone::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;
}
+155
View File
@@ -0,0 +1,155 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UPolyconeSide
//
// Class description:
//
// Class implmenting a face that represents one conical side
// of a polycone:
//
// UPolyconeSide( const UPolyconeSideRZ *prevRZ,
// const UPolyconeSideRZ *tail,
// const UPolyconeSideRZ *head,
// const UPolyconeSideRZ *nextRZ,
// double phiStart, double deltaPhi,
// bool phiIsOpen, bool isAllBehind=false )
//
// Values for r1,z1 and r2,z2 should be specified in clockwise
// order in (r,z).
//
// 19.04.13 Marek Gayer
// Created from original implementation in Geant4
// --------------------------------------------------------------------
#ifndef UPolyconeSide_hh
#define UPolyconeSide_hh
#include "UVCSGface.hh"
class UIntersectingCone;
struct UPolyconeSideRZ
{
double r, z; // start of vector
};
class UPolyconeSidePrivateSubclass
{
public:
std::pair<UVector3, double> fPhi; // Cached value for phi
void initialize()
{
fPhi.first = UVector3(0, 0, 0);
fPhi.second = 0.0;
};
};
class UPolyconeSide : public UVCSGface
{
public:
UPolyconeSide(const UPolyconeSideRZ* prevRZ,
const UPolyconeSideRZ* tail,
const UPolyconeSideRZ* head,
const UPolyconeSideRZ* nextRZ,
double phiStart, double deltaPhi,
bool phiIsOpen, bool isAllBehind = false);
virtual ~UPolyconeSide();
UPolyconeSide(const UPolyconeSide& source);
UPolyconeSide& operator=(const UPolyconeSide& source);
bool Distance(const UVector3& p, const UVector3& v,
bool outgoing, double surfTolerance,
double& distance, double& distFromSurface,
UVector3& normal, bool& isAllBehind);
double Safety(const UVector3& p, bool outgoing);
VUSolid::EnumInside Inside(const UVector3& p, double tolerance,
double* bestDistance);
UVector3 Normal(const UVector3& p, double* bestDistance);
double Extent(const UVector3 axis);
/*
void CalculateExtent( const EAxisType axis,
const UVoxelLimits &voxelLimit,
const UAffineTransform &tranform,
USolidExtentList &extentList );
*/
UVCSGface* Clone()
{
return new UPolyconeSide(*this);
}
double SurfaceArea();
UVector3 GetPointOnFace();
public: // without description
UPolyconeSide(__void__&);
// Fake default constructor for usage restricted to direct object
// persistency for clients requiring preallocation of memory for
// persistifiable objects.
protected:
double DistanceAway(const UVector3& p, bool opposite,
double& distOutside2, double* rzNorm = 0);
bool PointOnCone(const UVector3& hit, double normSign,
const UVector3& p,
const UVector3& v, UVector3& normal);
void CopyStuff(const UPolyconeSide& source);
static void FindLineIntersect(double x1, double y1,
double tx1, double ty1,
double x2, double y2,
double tx2, double ty2,
double& x, double& y);
double GetPhi(const UVector3& p);
protected:
double r[2], z[2]; // r, z parameters, in specified order
double startPhi, // Start phi (0 to 2pi), if phiIsOpen
deltaPhi; // Delta phi (0 to 2pi), if phiIsOpen
bool phiIsOpen; // True if there is a phi slice
bool allBehind; // True if the entire solid is "behind" this face
UIntersectingCone* cone; // Our intersecting utility class
double rNorm, zNorm; // Normal to surface in r,z space
double rS, zS; // Unit vector along surface in r,z space
double length; // Length of face in r,z space
double prevRS,
prevZS; // Unit vector along previous polyconeSide
double nextRS,
nextZS; // Unit vector along next polyconeSide
double rNormEdge[2],
zNormEdge[2]; // Normal to edges
int ncorners;
UVector3* corners; // The coordinates of the corners (if phiIsOpen)
private:
double tolerance; // Geometrical surface thickness
double fSurfaceArea; // Used for surface calculation
};
#endif
+195
View File
@@ -0,0 +1,195 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UPolyhedra
//
// Class description:
//
// Class implementing a CSG-like type "PGON":
//
// UPolyhedra( const std::string& name,
// double phiStart, - initial phi starting angle
// double phiTotal, - total phi angle
// int numSide, - number sides
// 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
//
// UPolyhedra( const std::string& name,
// double phiStart, - initial phi starting angle
// double phiTotal, - total phi angle
// int numSide, - number sides
// int numRZ, - number corners in r,z space
// const double r[], - r coordinate of these corners
// const double z[] ) - z coordinate of these corners
//
// 19.09.13 Marek Gayer
// Created from original implementation in Geant4
// --------------------------------------------------------------------
#ifndef UPolyhedra_hh
#define UPolyhedra_hh
#include "UVCSGfaceted.hh"
#include "UPolyhedraSide.hh"
class UEnclosingCylinder;
class UReduciblePolygon;
class UPolyhedraHistorical
{
public:
UPolyhedraHistorical();
~UPolyhedraHistorical();
UPolyhedraHistorical(const UPolyhedraHistorical& source);
UPolyhedraHistorical& operator=(const UPolyhedraHistorical& right);
double fStartAngle;
double fOpeningAngle;
int fNumSide;
int fNumZPlanes;
std::vector<double> fZValues;
std::vector<double> Rmin;
std::vector<double> Rmax;
};
class UPolyhedra : public UVCSGfaceted
{
protected:
inline UPolyhedra(const std::string& name) : UVCSGfaceted(name) {}
public: // with description
void Init(
double phiStart, // initial phi starting angle
double phiTotal, // total phi angle
int numSide, // number sides
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
UPolyhedra(const std::string& name,
double phiStart, // initial phi starting angle
double phiTotal, // total phi angle
int numSide, // number sides
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
UPolyhedra(const std::string& name,
double phiStart, // initial phi starting angle
double phiTotal, // total phi angle
int numSide, // number sides
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 ~UPolyhedra();
// Methods for solid
void GetParametersList(int /*aNumber*/, double* /*aArray*/) const {}
void ComputeBBox(UBBox* /*aBox*/, bool /*aStore*/)
{
// Computes bounding box.
std::cout << "ComputeBBox - Not implemented" << std::endl;
}
VUSolid::EnumInside Inside(const UVector3& p) const;
// double DistanceToInDelete( const UVector3 &p,
// const UVector3 &v ) const;
double SafetyFromOutside(const UVector3& aPoint, bool aAccurate = false) const;
UGeometryType GetEntityType() const;
VUSolid* Clone() const;
UVector3 GetPointOnSurface() const;
std::ostream& StreamInfo(std::ostream& os) const;
bool Reset();
// Accessors
inline int GetNumSide() const;
inline double GetStartPhi() const;
inline double GetEndPhi() const;
inline bool IsOpen() const;
inline bool IsGeneric() const;
inline int GetNumRZCorner() const;
inline UPolyhedraSideRZ GetCorner(const int index) const;
inline UPolyhedraHistorical* GetOriginalParameters();
// Returns internal scaled parameters.
inline void SetOriginalParameters(UPolyhedraHistorical& pars);
// Sets internal parameters. Parameters 'Rmin' and 'Rmax' in input must
// be scaled first by a factor computed as 'cos(0.5*phiTotal/theNumSide)',
// if not already scaled.
public: // without description
double DistanceToIn(const UVector3& p,
const UVector3& v, double aPstep = UUtils::kInfinity) const;
UPolyhedra(const UPolyhedra& source);
UPolyhedra& operator=(const UPolyhedra& source);
// Copy constructor and assignment operator.
void Extent(UVector3& aMin, UVector3& aMax) const;
protected: // without description
inline void SetOriginalParameters();
// Sets internal parameters for the generic constructor.
void Create(double phiStart, // initial phi starting angle
double phiTotal, // total phi angle
int numSide, // number sides
UReduciblePolygon* rz); // rz coordinates
// Generates the shape and is called by each constructor, after the
// conversion of the arguments
void CopyStuff(const UPolyhedra& source);
void DeleteStuff();
// Methods for generation of random points on surface
UVector3 GetPointOnPlane(UVector3 p0, UVector3 p1,
UVector3 p2, UVector3 p3) const;
UVector3 GetPointOnTriangle(UVector3 p0, UVector3 p1,
UVector3 p2) const;
UVector3 GetPointOnSurfaceCorners() const;
protected: // without description
int fNumSides; // Number of sides
double fStartPhi; // Starting phi value (0 < phiStart < 2pi)
double fEndPhi; // end phi value (0 < endPhi-phiStart < 2pi)
bool fPhiIsOpen; // true if there is a phi segment
bool fGenericPgon; // true if created through the 2nd generic constructor
int fNumCorner; // number RZ points
UPolyhedraSideRZ* fCorners; // our corners
UPolyhedraHistorical fOriginalParameters; // original input parameters
UEnclosingCylinder* fEnclosingCylinder;
};
#include "UPolyhedra.icc"
#endif
+95
View File
@@ -0,0 +1,95 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UPolyhedra.icc
//
// Implementation of inline methods of UPolyhedra
//
// 19.09.13 Marek Gayer
// Created from original implementation in Geant4
// --------------------------------------------------------------------
inline
int UPolyhedra::GetNumSide() const
{
return fNumSides;
}
inline
double UPolyhedra::GetStartPhi() const
{
return fStartPhi;
}
inline
double UPolyhedra::GetEndPhi() const
{
return fEndPhi;
}
inline
bool UPolyhedra::IsOpen() const
{
return fPhiIsOpen;
}
inline
bool UPolyhedra::IsGeneric() const
{
return fGenericPgon;
}
inline
int UPolyhedra::GetNumRZCorner() const
{
return fNumCorner;
}
inline
UPolyhedraSideRZ UPolyhedra::GetCorner(const int index) const
{
return fCorners[index];
}
inline
UPolyhedraHistorical* UPolyhedra::GetOriginalParameters()
{
return &fOriginalParameters;
}
inline
void UPolyhedra::SetOriginalParameters(UPolyhedraHistorical& pars)
{
fOriginalParameters = pars;
fCubicVolume = 0.;
}
inline
void UPolyhedra::SetOriginalParameters()
{
int fNumPlanes = (int) fNumCorner / 2;
fOriginalParameters.fZValues.resize(fNumPlanes);
fOriginalParameters.Rmin.resize(fNumPlanes);
fOriginalParameters.Rmax.resize(fNumPlanes);
for (int j = 0; j < fNumPlanes; j++)
{
fOriginalParameters.fZValues[j] = fCorners[fNumPlanes + j].z;
fOriginalParameters.Rmax[j] = fCorners[fNumPlanes + j].r;
fOriginalParameters.Rmin[j] = fCorners[fNumPlanes - 1 - j].r;
}
fOriginalParameters.fStartAngle = fStartPhi;
fOriginalParameters.fOpeningAngle = fEndPhi - fStartPhi;
fOriginalParameters.fNumZPlanes = fNumPlanes;
fOriginalParameters.fNumSide = fNumSides;
}
+180
View File
@@ -0,0 +1,180 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UPolyhedraSide
//
// Class description:
//
// Class implementing a face that represents one segmented side
// of a polyhedra:
//
// UPolyhedraSide( const UPolyhedraSideRZ *prevRZ,
// const UPolyhedraSideRZ *tail,
// const UPolyhedraSideRZ *head,
// const UPolyhedraSideRZ *nextRZ,
// int numSide,
// double phiStart, double phiTotal,
// bool phiIsOpen, bool isAllBehind=false )
//
// Values for r1,z1 and r2,z2 should be specified in clockwise
// order in (r,z).
//
// 19.09.13 Marek Gayer
// Created from original implementation in Geant4
// --------------------------------------------------------------------
#ifndef UPolyhedraSide_hh
#define UPolyhedraSide_hh
#include "UVCSGface.hh"
class UIntersectingCone;
struct UPolyhedraSideRZ
{
double r, z; // start of vector
};
class UPolyhedraSide : public UVCSGface
{
public: // with description
UPolyhedraSide(const UPolyhedraSideRZ* prevRZ,
const UPolyhedraSideRZ* tail,
const UPolyhedraSideRZ* head,
const UPolyhedraSideRZ* nextRZ,
int numSide,
double phiStart, double phiTotal,
bool phiIsOpen, bool isAllBehind = false);
virtual ~UPolyhedraSide();
UPolyhedraSide(const UPolyhedraSide& source);
UPolyhedraSide& operator=(const UPolyhedraSide& source);
bool Distance(const UVector3& p, const UVector3& v,
bool outgoing, double surfTolerance,
double& distance, double& distFromSurface,
UVector3& normal, bool& allBehind);
double Safety(const UVector3& p, bool outgoing);
VUSolid::EnumInside Inside(const UVector3& p, double tolerance,
double* bestDistance);
UVector3 Normal(const UVector3& p, double* bestDistance);
double Extent(const UVector3 axis);
UVCSGface* Clone()
{
return new UPolyhedraSide(*this);
}
public: // without description
// Methods used for GetPointOnSurface()
double SurfaceTriangle(UVector3 p1,
UVector3 p2,
UVector3 p3,
UVector3* p4);
UVector3 GetPointOnPlane(UVector3 p0, UVector3 p1,
UVector3 p2, UVector3 p3,
double* Area);
double SurfaceArea();
UVector3 GetPointOnFace();
public: // without description
UPolyhedraSide(__void__&);
// Fake default constructor for usage restricted to direct object
// persistency for clients requiring preallocation of memory for
// persistifiable objects.
protected:
//
// A couple internal data structures
//
struct sUPolyhedraSideVec; // Secret recipe for allowing
friend struct sUPolyhedraSideVec; // protected nested structures
typedef struct sUPolyhedraSideEdge
{
UVector3 normal; // Unit normal to this edge
UVector3 corner[2]; // The two corners of this phi edge
UVector3 cornNorm[2]; // The normals of these corners
} UPolyhedraSideEdge;
typedef struct sUPolyhedraSideVec
{
UVector3 normal, // Normal (point out of the shape)
center, // Point in center of side
surfPhi, // Unit vector on surface pointing along phi
surfRZ; // Unit vector on surface pointing along R/Z
UPolyhedraSideEdge* edges[2]; // The phi boundary edges to this side
// [0]=low phi [1]=high phi
UVector3 edgeNorm[2]; // RZ edge normals [i] at {r[i],z[i]}
} UPolyhedraSideVec;
bool IntersectSidePlane(const UVector3& p, const UVector3& v,
const UPolyhedraSideVec& vec,
double normSign,
double surfTolerance,
double& distance,
double& distFromSurface);
int LineHitsSegments(const UVector3& p,
const UVector3& v,
int* i1, int* i2);
int ClosestPhiSegment(double phi);
int PhiSegment(double phi);
double GetPhi(const UVector3& p);
double DistanceToOneSide(const UVector3& p,
const UPolyhedraSideVec& vec,
double* normDist);
double DistanceAway(const UVector3& p,
const UPolyhedraSideVec& vec,
double* normDist);
void CopyStuff(const UPolyhedraSide& source);
protected:
int numSide; // Number sides
double r[2], z[2]; // r, z parameters, in specified order
double startPhi, // Start phi (0 to 2pi), if phiIsOpen
deltaPhi, // Delta phi (0 to 2pi), if phiIsOpen
endPhi; // End phi (>startPhi), if phiIsOpen
bool phiIsOpen; // True if there is a phi slice
bool allBehind; // True if the entire solid is "behind" this face
UIntersectingCone* cone; // Our intersecting cone
UPolyhedraSideVec* vecs; // Vector Set for each facet of our face
UPolyhedraSideEdge* edges; // The edges belong to vecs
double lenRZ, // RZ length of each side
lenPhi[2]; // Phi dimensions of each side
double edgeNorm; // Normal in RZ/Phi space to each side
private:
std::pair<UVector3, double> fPhi; // Cached value for phi
double kCarTolerance; // Geometrical surface thickness
double fSurfaceArea; // Surface Area
};
#endif
+168
View File
@@ -0,0 +1,168 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UQuadrangularFacet
//
// Class description:
//
// The UQuadrangularFacet class is used for the contruction of
// UTessellatedSolid.
// It is defined by four fVertices, which shall be in the same plane and be
// supplied in anti-clockwise order looking from the outsider of the solid
// where it belongs. Its constructor
//
// UQuadrangularFacet (const UVector3 Pt0, const UVector3 vt1,
// const UVector3 vt2, const UVector3 vt3,
// UFacetVertexType);
//
// takes 5 parameters to define the four fVertices:
// 1) UFacetvertexType = "ABSOLUTE": in this case Pt0, vt1, vt2 and vt3
// are the four fVertices required in anti-clockwise order when looking
// from the outsider.
// 2) UFacetvertexType = "RELATIVE": in this case the first vertex is Pt0,
// the second vertex is Pt0+vt, the third vertex is Pt0+vt2 and
// the fourth vertex is Pt0+vt3, in anti-clockwise order when looking
// from the outsider.
//
// 17.10.12 Marek Gayer
// Created from original implementation in Geant4
// --------------------------------------------------------------------
#ifndef UQuadrangularFacet_HH
#define UQuadrangularFacet_HH 1
#include "VUFacet.hh"
#include "UTriangularFacet.hh"
#include "UVector3.hh"
class UQuadrangularFacet : public VUFacet
{
public: // with description
UQuadrangularFacet(const UVector3& Pt0, const UVector3& vt1,
const UVector3& vt2, const UVector3& vt3,
UFacetVertexType);
virtual ~UQuadrangularFacet();
UQuadrangularFacet(const UQuadrangularFacet& right);
UQuadrangularFacet& operator=(const UQuadrangularFacet& right);
VUFacet* GetClone();
UVector3 Distance(const UVector3& p);
double Distance(const UVector3& p, const double minDist);
double Distance(const UVector3& p, const double minDist,
const bool outgoing);
double Extent(const UVector3 axis);
bool Intersect(const UVector3& p, const UVector3& v,
const bool outgoing, double& distance,
double& distFromSurface, UVector3& normal);
double GetArea();
UVector3 GetPointOnFace() const;
virtual UGeometryType GetEntityType() const;
inline int GetNumberOfVertices() const
{
return 4;
}
UVector3 GetVertex(int i) const
{
return i == 3 ? fFacet2.GetVertex(2) : fFacet1.GetVertex(i);
}
UVector3 GetSurfaceNormal() const;
inline double GetRadius() const
{
return fRadius;
}
inline UVector3 GetCircumcentre() const
{
return fCircumcentre;
}
inline void SetVertex(int i, const UVector3& val)
{
switch (i)
{
case 0:
fFacet1.SetVertex(0, val);
fFacet2.SetVertex(0, val);
break;
case 1:
fFacet1.SetVertex(1, val);
break;
case 2:
fFacet1.SetVertex(2, val);
fFacet2.SetVertex(1, val);
break;
case 3:
fFacet2.SetVertex(2, val);
break;
}
}
inline void SetVertices(std::vector<UVector3>* v)
{
fFacet1.SetVertices(v);
fFacet2.SetVertices(v);
}
inline bool IsDefined() const
{
return fFacet1.IsDefined();
}
protected:
private:
inline int GetVertexIndex(int i) const
{
return i == 3 ? fFacet2.GetVertexIndex(2) : fFacet1.GetVertexIndex(i);
}
inline void SetVertexIndex(int i, int val)
{
switch (i)
{
case 0:
fFacet1.SetVertexIndex(0, val);
fFacet2.SetVertexIndex(0, val);
break;
case 1:
fFacet1.SetVertexIndex(1, val);
break;
case 2:
fFacet1.SetVertexIndex(2, val);
fFacet2.SetVertexIndex(1, val);
break;
case 3:
fFacet2.SetVertexIndex(2, val);
break;
}
}
double fRadius;
UVector3 fCircumcentre;
int AllocatedMemory()
{
return sizeof(*this) + fFacet1.AllocatedMemory() + fFacet2.AllocatedMemory();
}
UTriangularFacet fFacet1, fFacet2;
};
#endif
+190
View File
@@ -0,0 +1,190 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UReduciblePolygon
//
// Class description:
//
// Utility class used to specify, test, reduce, and/or otherwise
// manipulate a 2D polygon.
//
// For this class, a polygon consists of n > 2 points in 2D
// space (a,b). The polygon is always closed by connecting the
// last point to the first. A UReduciblePolygon is guaranteed
// to fulfill this definition in all instances.
//
// Illegal manipulations (such that a valid polygon would be
// produced) result in an error return if possible and
// otherwise a // UException.
//
// The Set of manipulations is limited currently to what
// is needed for UPolycone and UPolyhedra.
//
// 19.09.13 Marek Gayer
// Created from original implementation in Geant4
// --------------------------------------------------------------------
#ifndef UReduciblePolygon_hh
#define UReduciblePolygon_hh
#include "UTypes.hh"
class UReduciblePolygon
{
friend class UReduciblePolygonIterator;
public:
//
// Creator: via simple a/b arrays
//
UReduciblePolygon(const double a[], const double b[], int n);
//
// Creator: a special version for UPolygon and UPolycone
// that takes two a points at planes of b
// (where a==r and b==z for the GEANT3 classic PCON and PGON)
//
UReduciblePolygon(const double rmin[], const double rmax[],
const double z[], int n);
virtual ~UReduciblePolygon();
//
// Queries
//
inline int NumVertices() const
{
return numVertices;
}
inline double Amin() const
{
return aMin;
}
inline double Amax() const
{
return aMax;
}
inline double Bmin() const
{
return bMin;
}
inline double Bmax() const
{
return bMax;
}
void CopyVertices(double a[], double b[]) const;
//
// Manipulations
//
void ScaleA(double scale);
void ScaleB(double scale);
bool RemoveDuplicateVertices(double tolerance);
bool RemoveRedundantVertices(double tolerance);
void ReverseOrder();
void StartWithZMin();
//
// Tests
//
double Area();
bool CrossesItself(double tolerance);
bool BisectedBy(double a1, double b1,
double a2, double b2, double tolerance);
void Print(); // Debugging only
public: // without description
protected:
void Create(const double a[], const double b[], int n);
void CalculateMaxMin();
//
// Below are member values that are *always* kept up to date (please!)
//
double aMin, aMax, bMin, bMax;
int numVertices;
//
// A subclass which holds the vertices in a single-linked list
//
// Yeah, call me an old-fashioned c hacker, but I cannot make
// myself use the rogue tools for this trivial list.
//
struct ABVertex; // Secret recipe for allowing
friend struct ABVertex; // protected nested structures
struct ABVertex
{
ABVertex() : a(0.), b(0.), next(0) {}
double a, b;
ABVertex* next;
};
ABVertex* vertexHead;
private:
UReduciblePolygon(const UReduciblePolygon&);
UReduciblePolygon& operator=(const UReduciblePolygon&);
// Private copy constructor and assignment operator.
};
//
// A companion class for iterating over the vertices of our polygon.
// It is simple enough that all routines are declared inline here.
//
class UReduciblePolygonIterator
{
public:
UReduciblePolygonIterator(const UReduciblePolygon* theSubject)
{
subject = theSubject;
current = 0;
}
void Begin()
{
current = subject->vertexHead;
}
bool Next()
{
if (current) current = current->next;
return Valid();
}
bool Valid() const
{
return current != 0;
}
double GetA() const
{
return current->a;
}
double GetB() const
{
return current->b;
}
protected:
const UReduciblePolygon* subject; // Who are we iterating over
UReduciblePolygon::ABVertex* current; // Current vertex
};
#endif
+503
View File
@@ -0,0 +1,503 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// USphere
//
// Class description:
//
// A USphere is, in the general case, a section of a spherical shell,
// between specified phi and theta angles
//
// The phi and theta segments are described by a starting angle,
// and the +ve delta angle for the shape.
// If the delta angle is >=2*UUtils::kPi, or >=UUtils::kPi the shape is treated as
// continuous in phi or theta respectively.
//
// Theta must lie between 0-UUtils::kPi (incl).
//
// Member Data:
//
// fRmin inner radius
// fRmax outer radius
//
// fSPhi starting angle of the segment in radians
// fDPhi delta angle of the segment in radians
//
// fSTheta starting angle of the segment in radians
// fDTheta delta angle of the segment in radians
//
//
// Note:
// Internally fSPhi & fDPhi are adjusted so that fDPhi<=2PI,
// and fDPhi+fSPhi<=2PI. This enables simpler comparisons to be
// made with (say) Phi of a point.
//
// 19.10.12 Marek Gayer
// Created from original implementation in Geant4
// --------------------------------------------------------------------
#ifndef USphere_HH
#define USphere_HH
#include <sstream>
#include "VUSolid.hh"
class UVisExtent;
class USphere : public VUSolid
{
public: // with description
USphere(const std::string& pName,
double pRmin, double pRmax,
double pSPhi, double pDPhi,
double pSTheta, double pDTheta);
//
// Constructs a sphere or sphere shell section
// with the given name and dimensions
~USphere();
//
// Destructor
// Accessors
inline double GetInnerRadius() const;
inline double GetOuterRadius() const;
inline double GetStartPhiAngle() const;
inline double GetDeltaPhiAngle() const;
inline double GetStartThetaAngle() const;
inline double GetDeltaThetaAngle() const;
// Modifiers
inline void SetInnerRadius(double newRMin);
inline void SetOuterRadius(double newRmax);
inline void SetStartPhiAngle(double newSphi, bool trig = true);
inline void SetDeltaPhiAngle(double newDphi);
inline void SetStartThetaAngle(double newSTheta);
inline void SetDeltaThetaAngle(double newDTheta);
// Methods for solid
inline double Capacity();
double SurfaceArea();
VUSolid::EnumInside Inside(const UVector3& p) const;
bool Normal(const UVector3& p, UVector3& n) const;
double DistanceToIn(const UVector3& p, const UVector3& v, double aPstep = UUtils::kInfinity) const;
double SafetyFromOutside(const UVector3& p, bool aAccurate = false) const;
double DistanceToOut(const UVector3& p, const UVector3& v, UVector3& n, bool& validNorm, double aPstep = UUtils::kInfinity) const;
double SafetyFromInside(const UVector3& p, bool aAccurate = false) const;
UGeometryType GetEntityType() const;
UVector3 GetPointOnSurface() const;
VUSolid* Clone() const;
std::ostream& StreamInfo(std::ostream& os) const;
// Visualisation functions
UVisExtent GetExtent() const;
public: // without description
void Extent(UVector3& aMin, UVector3& aMax) const;
void GetParametersList(int /*aNumber*/, double* /*aArray*/) const;
virtual void ComputeBBox(UBBox* /*aBox*/, bool /*aStore = false*/) {}
USphere(const USphere& rhs);
USphere& operator=(const USphere& rhs);
// Copy constructor and assignment operator.
// Old access functions
inline double GetRmin() const;
inline double GetRmax() const;
inline double GetSPhi() const;
inline double GetDPhi() const;
inline double GetSTheta() const;
inline double GetDTheta() const;
inline double GetInsideRadius() const;
inline void SetInsideRadius(double newRmin);
private:
double fCubicVolume;
double fSurfaceArea;
inline void Initialize();
//
// Reset relevant values to zero
inline void CheckThetaAngles(double sTheta, double dTheta);
inline void CheckSPhiAngle(double sPhi);
inline void CheckDPhiAngle(double dPhi);
inline void CheckPhiAngles(double sPhi, double dPhi);
//
// Reset relevant flags and angle values
inline void InitializePhiTrigonometry();
inline void InitializeThetaTrigonometry();
//
// Recompute relevant trigonometric values and cache them
UVector3 ApproxSurfaceNormal(const UVector3& p) const;
//
// Algorithm for SurfaceNormal() following the original
// specification for points not on the surface
private:
// Used by distanceToOut
//
enum ESide {kNull, kRMin, kRMax, kSPhi, kEPhi, kSTheta, kETheta};
// used by normal
//
enum ENorm {kNRMin, kNRMax, kNSPhi, kNEPhi, kNSTheta, kNETheta};
double fRminTolerance, kTolerance, kAngTolerance,
kRadTolerance, fEpsilon;
//
// Radial and angular tolerances
double fRmin, fRmax, fSPhi, fDPhi, fSTheta, fDTheta;
//
// Radial and angular dimensions
double sinCPhi, cosCPhi, cosHDPhiOT, cosHDPhiIT,
sinSPhi, cosSPhi, sinEPhi, cosEPhi, hDPhi, cPhi, ePhi;
//
// Cached trigonometric values for Phi angle
double sinSTheta, cosSTheta, sinETheta, cosETheta,
tanSTheta, tanSTheta2, tanETheta, tanETheta2, eTheta;
//
// Cached trigonometric values for Theta angle
bool fFullPhiSphere, fFullThetaSphere, fFullSphere;
//
// Flags for identification of section, shell or full sphere
};
inline
double USphere::GetInsideRadius() const
{
return fRmin;
}
inline
double USphere::GetInnerRadius() const
{
return fRmin;
}
inline
double USphere::GetOuterRadius() const
{
return fRmax;
}
inline
double USphere::GetStartPhiAngle() const
{
return fSPhi;
}
inline
double USphere::GetDeltaPhiAngle() const
{
return fDPhi;
}
inline
double USphere::GetStartThetaAngle() const
{
return fSTheta;
}
double USphere::GetDeltaThetaAngle() const
{
return fDTheta;
}
inline
void USphere::Initialize()
{
fCubicVolume = 0.;
fSurfaceArea = 0.;
}
inline
void USphere::InitializePhiTrigonometry()
{
hDPhi = 0.5 * fDPhi; // half delta phi
cPhi = fSPhi + hDPhi;
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 USphere::InitializeThetaTrigonometry()
{
eTheta = fSTheta + fDTheta;
sinSTheta = std::sin(fSTheta);
cosSTheta = std::cos(fSTheta);
sinETheta = std::sin(eTheta);
cosETheta = std::cos(eTheta);
tanSTheta = std::tan(fSTheta);
tanSTheta2 = tanSTheta * tanSTheta;
tanETheta = std::tan(eTheta);
tanETheta2 = tanETheta * tanETheta;
}
inline
void USphere::CheckThetaAngles(double sTheta, double dTheta)
{
if ((sTheta < 0) || (sTheta > UUtils::kPi))
{
std::ostringstream message;
message << "sTheta outside 0-PI range." << std::endl
<< "Invalid starting Theta angle for solid: " << GetName();
UUtils::Exception("USphere::CheckThetaAngles()", "GeomSolids0002",
FatalError, 1, message.str().c_str());
}
else
{
fSTheta = sTheta;
}
if (dTheta + sTheta >= UUtils::kPi)
{
fDTheta = UUtils::kPi - sTheta;
}
else if (dTheta > 0)
{
fDTheta = dTheta;
}
else
{
std::ostringstream message;
message << "Invalid dTheta." << std::endl
<< "Negative delta-Theta (" << dTheta << "), for solid: "
<< GetName();
UUtils::Exception("USphere::CheckThetaAngles()", "GeomSolids0002",
FatalError, 1, message.str().c_str());
}
if (fDTheta - fSTheta < UUtils::kPi)
{
fFullThetaSphere = false;
}
else
{
fFullThetaSphere = true ;
}
fFullSphere = fFullPhiSphere && fFullThetaSphere;
InitializeThetaTrigonometry();
}
inline
void USphere::CheckSPhiAngle(double sPhi)
{
// Ensure fSphi in 0-2PI or -2PI-0 range if shape crosses 0
if (sPhi < 0)
{
fSPhi = 2 * UUtils::kPi - std::fmod(std::fabs(sPhi), 2 * UUtils::kPi);
}
else
{
fSPhi = std::fmod(sPhi, 2 * UUtils::kPi) ;
}
if (fSPhi + fDPhi > 2 * UUtils::kPi)
{
fSPhi -= 2 * UUtils::kPi ;
}
}
inline
void USphere::CheckDPhiAngle(double dPhi)
{
fFullPhiSphere = true;
if (dPhi >= 2 * UUtils::kPi - kAngTolerance * 0.5)
{
fDPhi = 2 * UUtils::kPi;
fSPhi = 0;
}
else
{
fFullPhiSphere = false;
if (dPhi > 0)
{
fDPhi = dPhi;
}
else
{
std::ostringstream message;
message << "Invalid dphi." << std::endl
<< "Negative delta-Phi (" << dPhi << "), for solid: "
<< GetName();
UUtils::Exception("USphere::CheckDPhiAngle()", "GeomSolids0002",
FatalError, 1, message.str().c_str());
}
}
}
inline
void USphere::CheckPhiAngles(double sPhi, double dPhi)
{
CheckDPhiAngle(dPhi);
//if (!fFullPhiSphere && sPhi) { CheckSPhiAngle(sPhi); }
if (!fFullPhiSphere)
{
CheckSPhiAngle(sPhi);
}
fFullSphere = fFullPhiSphere && fFullThetaSphere;
InitializePhiTrigonometry();
}
inline
void USphere::SetInsideRadius(double newRmin)
{
fRmin = newRmin;
fRminTolerance = (fRmin) ? std::max(kRadTolerance, fEpsilon * fRmin) : 0;
Initialize();
}
inline
void USphere::SetInnerRadius(double newRmin)
{
SetInsideRadius(newRmin);
}
inline
void USphere::SetOuterRadius(double newRmax)
{
fRmax = newRmax;
kTolerance = std::max(kRadTolerance, fEpsilon * fRmax);
Initialize();
}
inline
void USphere::SetStartPhiAngle(double newSPhi, bool compute)
{
// Flag 'compute' can be used to explicitely avoid recomputation of
// trigonometry in case SetDeltaPhiAngle() is invoked afterwards
CheckSPhiAngle(newSPhi);
fFullPhiSphere = false;
if (compute)
{
InitializePhiTrigonometry();
}
Initialize();
}
inline
void USphere::SetDeltaPhiAngle(double newDPhi)
{
CheckPhiAngles(fSPhi, newDPhi);
Initialize();
}
inline
void USphere::SetStartThetaAngle(double newSTheta)
{
CheckThetaAngles(newSTheta, fDTheta);
Initialize();
}
inline
void USphere::SetDeltaThetaAngle(double newDTheta)
{
CheckThetaAngles(fSTheta, newDTheta);
Initialize();
}
// Old access functions
inline
double USphere::GetRmin() const
{
return GetInsideRadius();
}
inline
double USphere::GetRmax() const
{
return GetOuterRadius();
}
inline
double USphere::GetSPhi() const
{
return GetStartPhiAngle();
}
inline
double USphere::GetDPhi() const
{
return GetDeltaPhiAngle();
}
inline
double USphere::GetSTheta() const
{
return GetStartThetaAngle();
}
inline
double USphere::GetDTheta() const
{
return GetDeltaThetaAngle();
}
inline
double USphere::Capacity()
{
if (fCubicVolume != 0.)
{
;
}
else
{
fCubicVolume = fDPhi * (std::cos(fSTheta) - std::cos(fSTheta + fDTheta)) *
(fRmax * fRmax * fRmax - fRmin * fRmin * fRmin) / 3.;
}
return fCubicVolume;
}
#endif
@@ -0,0 +1,74 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UTessellatedGeometryAlgorithms
//
// Class description:
//
// The UTessellatedGeometryAlgorithms class is used to contain standard
// routines to determine whether (and if so where) simple geometric shapes
// intersect.
//
// The constructor doesn't need to do anything, and neither does the
// destructor.
//
// IntersectLineAndTriangle2D
// Determines whether there is an intersection between a line defined
// by r = p + s.v and a triangle defined by verticies P0, P0+E0 and P0+E1.
// Here:
// p = 2D vector
// s = scaler on [0,infinity)
// v = 2D vector
// P0, E0 and E1 are 2D vectors
// Information about where the intersection occurs is returned in the
// variable location.
//
// IntersectLineAndLineSegment2D
// Determines whether there is an intersection between a line defined
// by r = P0 + s.D0 and a line-segment with endpoints P1 and P1+D1.
// Here:
// P0 = 2D vector
// s = scaler on [0,infinity)
// D0 = 2D vector
// P1 and D1 are 2D vectors
// Information about where the intersection occurs is returned in the
// variable location.
//
// 11.07.12 Marek Gayer
// Created from original implementation in Geant4
// --------------------------------------------------------------------
#ifndef UTessellatedGeometryAlgorithms_hh
#define UTessellatedGeometryAlgorithms_hh 1
#include "UVector2.hh"
class UTessellatedGeometryAlgorithms
{
public:
static bool IntersectLineAndTriangle2D(const UVector2& p,
const UVector2& v,
const UVector2& p0,
const UVector2& e0,
const UVector2& e1,
UVector2 location[2]);
static int IntersectLineAndLineSegment2D(const UVector2& p0,
const UVector2& d0,
const UVector2& p1,
const UVector2& d1,
UVector2 location[2]);
static double Cross(const UVector2& v1, const UVector2& v2);
};
#endif
+266
View File
@@ -0,0 +1,266 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UTessellatedSolid
//
// Class description:
//
// UTessellatedSolid is a special Geant4 solid defined by a number of
// facets (UVFacet). It is important that the supplied facets shall form a
// fully enclose space which is the solid.
// Only two types of facet can be used for the construction of
// a UTessellatedSolid, i.e. the UTriangularFacet and UQuadrangularFacet.
//
// How to contruct a UTessellatedSolid:
//
// First declare a tessellated solid:
//
// UTessellatedSolid* solidTarget = new UTessellatedSolid("Solid_name");
//
// Define the facets which form the solid
//
// double targetSiz = 10*cm ;
// UTriangularFacet *facet1 = new
// UTriangularFacet (UVector3(-targetSize,-targetSize, 0.0),
// UVector3(+targetSize,-targetSize, 0.0),
// UVector3( 0.0, 0.0,+targetSize),
// ABSOLUTE);
// UTriangularFacet *facet2 = new
// UTriangularFacet (UVector3(+targetSize,-targetSize, 0.0),
// UVector3(+targetSize,+targetSize, 0.0),
// UVector3( 0.0, 0.0,+targetSize),
// ABSOLUTE);
// UTriangularFacet *facet3 = new
// UTriangularFacet (UVector3(+targetSize,+targetSize, 0.0),
// UVector3(-targetSize,+targetSize, 0.0),
// UVector3( 0.0, 0.0,+targetSize),
// ABSOLUTE);
// UTriangularFacet *facet4 = new
// UTriangularFacet (UVector3(-targetSize,+targetSize, 0.0),
// UVector3(-targetSize,-targetSize, 0.0),
// UVector3( 0.0, 0.0,+targetSize),
// ABSOLUTE);
// UQuadrangularFacet *facet5 = new
// UQuadrangularFacet (UVector3(-targetSize,-targetSize, 0.0),
// UVector3(-targetSize,+targetSize, 0.0),
// UVector3(+targetSize,+targetSize, 0.0),
// UVector3(+targetSize,-targetSize, 0.0),
// ABSOLUTE);
//
// Then add the facets to the solid:
//
// solidTarget->AddFacet((UVFacet*) facet1);
// solidTarget->AddFacet((UVFacet*) facet2);
// solidTarget->AddFacet((UVFacet*) facet3);
// solidTarget->AddFacet((UVFacet*) facet4);
// solidTarget->AddFacet((UVFacet*) facet5);
//
// Finally declare the solid is complete:
//
// solidTarget->SetSolidClosed(true);
//
// 11.07.12 Marek Gayer
// Created from original implementation in Geant4
// --------------------------------------------------------------------
#ifndef UTessellatedSolid_hh
#define UTessellatedSolid_hh 1
#include <iostream>
#include <vector>
#include <set>
#include <map>
#include "VUSolid.hh"
#include "VUFacet.hh"
#include "UVoxelizer.hh"
struct UVertexInfo
{
int id;
double mag2;
};
class UVertexComparator
{
public:
bool operator()(const UVertexInfo& l, const UVertexInfo& r) const
{
return l.mag2 == r.mag2 ? l.id < r.id : l.mag2 < r.mag2;
}
};
class UTessellatedSolid : public VUSolid
{
public:
UTessellatedSolid();
virtual ~UTessellatedSolid();
UTessellatedSolid(const std::string& name);
UTessellatedSolid(__void__&);
// Fake default constructor for usage restricted to direct object
// persistency for clients requiring preallocation of memory for
// persistifiable objects.
UTessellatedSolid(const UTessellatedSolid& s);
UTessellatedSolid& operator= (const UTessellatedSolid& s);
UTessellatedSolid& operator+= (const UTessellatedSolid& right);
bool AddFacet(VUFacet* aFacet);
inline VUFacet* GetFacet(int i) const { return fFacets[i]; }
int GetNumberOfFacets() const;
virtual double GetSurfaceArea();
virtual VUSolid::EnumInside Inside(const UVector3& p) const;
virtual bool Normal(const UVector3& p, UVector3& aNormal) const;
virtual double SafetyFromOutside(const UVector3& p, bool aAccurate = false) const;
virtual double SafetyFromInside(const UVector3& p, bool aAccurate = false) const;
virtual UGeometryType GetEntityType() const;
void SetSolidClosed(const bool t);
bool GetSolidClosed() const;
virtual UVector3 GetPointOnSurface() const;
virtual std::ostream& StreamInfo(std::ostream& os) const;
virtual double Capacity() { return 0; }
virtual double SurfaceArea() { return GetSurfaceArea(); }
inline virtual void GetParametersList(int /*aNumber*/, double* /*aArray*/) const {}
inline virtual void ComputeBBox(UBBox* /*aBox*/, bool /*aStore = false*/) {}
inline void SetMaxVoxels(int max) { fVoxels.SetMaxVoxels(max); }
inline UVoxelizer& GetVoxels() { return fVoxels; }
virtual VUSolid* Clone() const;
double GetMinXExtent() const;
double GetMaxXExtent() const;
double GetMinYExtent() const;
double GetMaxYExtent() const;
double GetMinZExtent() const;
double GetMaxZExtent() const;
virtual double DistanceToIn(const UVector3& p, const UVector3& v,
double aPstep = UUtils::kInfinity) const
{
return DistanceToInCore(p, v, aPstep);
}
virtual double DistanceToOut(const UVector3& p,
const UVector3& v,
UVector3& aNormalVector,
bool& aConvex,
double aPstep = UUtils::kInfinity
) const
{
return DistanceToOutCore(p, v, aNormalVector, aConvex, aPstep);
}
void Extent(UVector3& aMin, UVector3& aMax) const;
int AllocatedMemoryWithoutVoxels();
int AllocatedMemory();
void DisplayAllocatedMemory();
private:
double DistanceToOutNoVoxels(const UVector3& p,
const UVector3& v,
UVector3& aNormalVector,
bool& aConvex,
double aPstep = UUtils::kInfinity
) const;
double DistanceToInCandidates(const std::vector<int>& candidates, const UVector3& aPoint, const UVector3& aDirection /*, double aPstep, const UBits &bits*/) const;
void DistanceToOutCandidates(const std::vector<int >& candidates, const UVector3& aPoint, const UVector3& direction, double& minDist, UVector3& minNormal, int& minCandidate/*, double aPstep*/ /*, UBits &bits*/) const;
double DistanceToInNoVoxels(const UVector3& p, const UVector3& v, double aPstep = UUtils::kInfinity) const;
void SetExtremeFacets();
VUSolid::EnumInside InsideNoVoxels(const UVector3& p) const;
VUSolid::EnumInside InsideVoxels(const UVector3& aPoint) const;
void Voxelize();
void CreateVertexList();
void PrecalculateInsides();
void SetRandomVectors();
double DistanceToInCore(const UVector3& p,
const UVector3& v,
double aPstep = UUtils::kInfinity) const;
double DistanceToOutCore(const UVector3& p,
const UVector3& v,
UVector3& aNormalVector,
bool& aConvex,
double aPstep = UUtils::kInfinity) const;
int SetAllUsingStack(const std::vector<int>& voxel,
const std::vector<int>& max,
bool status, UBits& checked);
void DeleteObjects();
void CopyObjects(const UTessellatedSolid& s);
static bool CompareSortedVoxel(const std::pair<int, double>& l,
const std::pair<int, double>& r);
double MinDistanceFacet(const UVector3& p, bool simple, VUFacet*& facet) const;
inline bool OutsideOfExtent(const UVector3& p, double tolerance = 0) const
{
return (p.x < fMinExtent.x - tolerance || p.x > fMaxExtent.x + tolerance ||
p.y < fMinExtent.y - tolerance || p.y > fMaxExtent.y + tolerance ||
p.z < fMinExtent.z - tolerance || p.z > fMaxExtent.z + tolerance);
}
void Initialize();
private:
std::vector<VUFacet*> fFacets;
std::set<VUFacet*> fExtremeFacets; // Does all other facets lie on or behind this surface?
UGeometryType fGeometryType;
double fCubicVolume;
double fSurfaceArea;
std::vector<UVector3> fVertexList;
std::set<UVertexInfo, UVertexComparator> fFacetList;
UVector3 fMinExtent, fMaxExtent;
bool fSolidClosed;
static const double dirTolerance;
std::vector<UVector3> fRandir;
double fgToleranceHalf;
int fMaxTries;
UVoxelizer fVoxels; // voxelized solid
UBits fInsides;
};
#endif
+122
View File
@@ -0,0 +1,122 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UTet
//
// Class description:
//
// A UTet is a tetrahedrasolid.
//
// 19.07.13 Tatiana Nikitina
// Created from original implementation in Geant4
// --------------------------------------------------------------------
#ifndef UTet_hh
#define UTet_hh
#include "VUSolid.hh"
#include "UUtils.hh"
class UTet : public VUSolid
{
public: // with description
UTet(const std::string& name,
UVector3 anchor,
UVector3 p2,
UVector3 p3,
UVector3 p4,
bool* degeneracyFlag = 0);
virtual ~UTet();
// Methods for solid
EnumInside Inside(const UVector3& p) const;
bool Normal(const UVector3& aPoint, UVector3& aNormal) const;
double SafetyFromInside(const UVector3& aPoint,
bool aAccurate = false) const;
double SafetyFromOutside(const UVector3& aPoint,
bool aAccurate = false) const;
double DistanceToIn(const UVector3& aPoint,
const UVector3& aDirection,
// UVector3 &aNormalVector,
double aPstep = UUtils::kInfinity) const;
double DistanceToOut(const UVector3& aPoint,
const UVector3& aDirection,
UVector3& aNormalVector,
bool& aConvex,
double aPstep = UUtils::kInfinity) const;
void Extent(UVector3& aMin, UVector3& aMax) const;
double Capacity();
double SurfaceArea();
UGeometryType GetEntityType() const;
void ComputeBBox(UBBox* /*aBox*/, bool /*aStore = false*/) {}
// Visualisation
void GetParametersList(int aNumber, double* aArray) const;
VUSolid* Clone() const;
UVector3 GetPointOnSurface() const;
std::ostream& StreamInfo(std::ostream& os) const;
public: // without description
UTet(__void__&);
// Fake default constructor for usage restricted to direct object
// persistency for clients requiring preallocation of memory for
// persistifiable objects.
UTet(const UTet& rhs);
UTet& operator=(const UTet& rhs);
// Copy constructor and assignment operator.
void PrintWarnings(bool flag)
{
warningFlag = flag;
}
static bool CheckDegeneracy(UVector3& anchor,
UVector3& p2,
UVector3& p3,
UVector3& p4);
std::vector<UVector3> GetVertices() const;
// Return the four vertices of the shape.
private:
double fCubicVolume, fSurfaceArea;
UVector3 GetPointOnFace(UVector3 p1, UVector3 p2,
UVector3 p3, double& area) const;
static const char CVSVers[];
private:
UVector3 fAnchor, fP2, fP3, fP4, fMiddle;
UVector3 fNormal123, fNormal142, fNormal134, fNormal234;
bool warningFlag;
double fCdotN123, fCdotN142, fCdotN134, fCdotN234;
double fXMin, fXMax, fYMin, fYMax, fZMin, fZMax;
double fDx, fDy, fDz, fTol, fMaxSize;
};
#endif
+59
View File
@@ -0,0 +1,59 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UTransform3D
//
// Class description:
//
// UTransform3D: General transformation made by rotation + translation
//
// 19.10.12 Marek Gayer
// Created from original implementation in CLHEP
// --------------------------------------------------------------------
#ifndef USOLIDS_UTransform3D
#define USOLIDS_UTransform3D
#include "UVector3.hh"
class UTransform3D
{
public:
UVector3 fTr; // Translation
double fRot[9]; // Rotation
UTransform3D(); // Initialize to identity
UTransform3D(double tx, double ty, double tz,
double phi = 0., double theta = 0., double psi = 0.);
UTransform3D(const UTransform3D& other);
~UTransform3D() {}
virtual void RotateX(double angle);
virtual void RotateY(double angle);
virtual void RotateZ(double angle);
void SetAngles(double phi, double theta, double psi);
// Local<->global coordinate and vector conversions
UVector3 GlobalPoint(const UVector3& local) const;
UVector3 GlobalVector(const UVector3& local) const;
UVector3 LocalPoint(const UVector3& global) const;
UVector3 LocalVector(const UVector3& global) const;
// Operators
UTransform3D& operator = (const UTransform3D& other);
UTransform3D& operator *= (const UTransform3D& other);
UTransform3D& operator *= (const UVector3& vect);
};
// Vector-matrix multiplication
UVector3 operator * (const UVector3& p, const UTransform3D& trans);
#endif
+257
View File
@@ -0,0 +1,257 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UTrap
//
// Class description:
//
// A UTrap is a general trapezoid: The faces perpendicular to the
// z planes are trapezia, and their centres are not necessarily on
// a line parallel to the z axis.
//
// Note that of the 11 parameters described below, only 9 are really
// independent - a check for planarity is made in the calculation of the
// equation for each plane. If the planes are not parallel, a call to
// UException is made.
//
// pDz Half-length along the z-axis
// pTheta Polar angle of the line joining the centres of the faces
// at -/+pDz
// pPhi Azimuthal angle of the line joing the centre of the face at
// -pDz to the centre of the face at +pDz
// pDy1 Half-length along y of the face at -pDz
// pDx1 Half-length along x of the side at y=-pDy1 of the face at -pDz
// pDx2 Half-length along x of the side at y=+pDy1 of the face at -pDz
// pAlp1 Angle with respect to the y axis from the centre of the side
// at y=-pDy1 to the centre at y=+pDy1 of the face at -pDz
//
// pDy2 Half-length along y of the face at +pDz
// pDx3 Half-length along x of the side at y=-pDy2 of the face at +pDz
// pDx4 Half-length along x of the side at y=+pDy2 of the face at +pDz
// pAlp2 Angle with respect to the y axis from the centre of the side
// at y=-pDy2 to the centre at y=+pDy2 of the face at +pDz
//
// Member Data:
//
// fDz Half-length along the z axis
// fTthetaCphi = std::tan(pTheta)*std::cos(pPhi)
// fTthetaSphi = std::tan(pTheta)*std::sin(pPhi)
// These combinations are suitable for creation of the trapezoid corners
//
// fDy1 Half-length along y of the face at -fDz
// fDx1 Half-length along x of the side at y=-fDy1 of the face at -fDz
// fDx2 Half-length along x of the side at y=+fDy1 of the face at -fDz
// fTalpha1 Tan of Angle with respect to the y axis from the centre of
// the side at y=-fDy1 to the centre at y=+fDy1 of the face
// at -fDz
//
// fDy2 Half-length along y of the face at +fDz
// fDx3 Half-length along x of the side at y=-fDy2 of the face at +fDz
// fDx4 Half-length along x of the side at y=+fDy2 of the face at +fDz
// fTalpha2 Tan of Angle with respect to the y axis from the centre of
// the side at y=-fDy2 to the centre at y=+fDy2 of the face
// at +fDz
//
// UTrapSidePlane fPlanes[4] Plane equations of the faces not at +/-fDz
// NOTE: order is important !!!
//
// 12.02.13 Marek Gayer
// Created from original implementation in Geant4
// --------------------------------------------------------------------
#ifndef UTrap_HH
#define UTrap_HH
#include "VUSolid.hh"
struct UTrapSidePlane
{
double a, b, c, d; // Normal Unit vector (a,b,c) and offset (d)
// => Ax+By+Cz+D=0
};
class UTrap : public VUSolid
{
public: // with description
UTrap(const std::string& pName,
double pDz,
double pTheta, double pPhi,
double pDy1, double pDx1, double pDx2,
double pAlp1,
double pDy2, double pDx3, double pDx4,
double pAlp2);
//
// The most general constructor for UTrap which prepares plane
// equations and corner coordinates from parameters
UTrap(const std::string& pName,
const UVector3 pt[8]) ;
//
// Prepares plane equations and parameters from corner coordinates
UTrap(const std::string& pName,
double pZ,
double pY,
double pX, double pLTX);
//
// Constructor for Right Angular Wedge from STEP (assumes pLTX<=pX)
UTrap(const std::string& pName,
double pDx1, double pDx2,
double pDy1, double pDy2,
double pDz);
//
// Constructor for UTrd
UTrap(const std::string& pName,
double pDx, double pDy, double pDz,
double pAlpha, double pTheta, double pPhi);
//
// Constructor for UPara
UTrap(const std::string& pName);
//
// Constructor for "nominal" UTrap whose parameters are to be Set
// by a UVPVParamaterisation later
virtual ~UTrap() ;
//
// Destructor
// Accessors
inline double GetZHalfLength() const;
inline double GetYHalfLength1() const;
inline double GetXHalfLength1() const;
inline double GetXHalfLength2() const;
inline double GetTanAlpha1() const;
inline double GetYHalfLength2() const;
inline double GetXHalfLength3() const;
inline double GetXHalfLength4() const;
inline double GetTanAlpha2() const;
//
// Returns coordinates of Unit vector along straight
// line joining centers of -/+fDz planes
inline UTrapSidePlane GetSidePlane(int n) const;
inline UVector3 GetSymAxis() const;
// Modifiers
void SetAllParameters(double pDz,
double pTheta,
double pPhi,
double pDy1,
double pDx1,
double pDx2,
double pAlp1,
double pDy2,
double pDx3,
double pDx4,
double pAlp2);
void SetPlanes(const UVector3 pt[8]);
// Methods for solid
inline double Capacity();
inline double SurfaceArea();
VUSolid::EnumInside Inside(const UVector3& p) const;
UVector3 SurfaceNormal(const UVector3& p) const;
bool Normal(const UVector3& aPoint, UVector3& aNormal) const;
double DistanceToIn(const UVector3& p, const UVector3& v,
double aPstep = UUtils::kInfinity) const;
double SafetyFromOutside(const UVector3& p, bool precise = false) const;
double DistanceToOut(const UVector3& p,
const UVector3& v,
UVector3& aNormalVector,
bool& aConvex,
double aPstep = UUtils::kInfinity) const;
double SafetyFromInside(const UVector3& p, bool precise = false) const;
UGeometryType GetEntityType() const;
UVector3 GetPointOnSurface() const;
VUSolid* Clone() const;
virtual void Extent(UVector3& aMin, UVector3& aMax) const;
std::ostream& StreamInfo(std::ostream& os) const;
// Visualisation functions
public: // without description
UTrap(const UTrap& rhs);
UTrap& operator=(const UTrap& rhs);
// Copy constructor and assignment operator.
inline double GetThetaCphi() const;
inline double GetThetaSphi() const;
protected: // with description
bool MakePlanes();
bool MakePlane(const UVector3& p1,
const UVector3& p2,
const UVector3& p3,
const UVector3& p4,
UTrapSidePlane& plane) ;
private:
UVector3 ApproxSurfaceNormal(const UVector3& p) const;
// Algorithm for SurfaceNormal() following the original
// specification for points not on the surface
inline double GetFaceArea(const UVector3& p1,
const UVector3& p2,
const UVector3& p3,
const UVector3& p4);
//
// Provided four corners of plane in clockwise fashion,
// it returns the area of finite face
UVector3 GetPointOnPlane(UVector3 p0, UVector3 p1,
UVector3 p2, UVector3 p3,
double& area) const;
//
// Returns a random point on the surface of one of the faces
void GetParametersList(int /*aNumber*/, double* /*aArray*/) const {}
void ComputeBBox(UBBox* /*aBox*/, bool /*aStore = false*/) {}
private:
double fDz, fTthetaCphi, fTthetaSphi;
double fDy1, fDx1, fDx2, fTalpha1;
double fDy2, fDx3, fDx4, fTalpha2;
UTrapSidePlane fPlanes[4];
double fCubicVolume;
double fSurfaceArea;
};
#include "UTrap.icc"
#endif
+166
View File
@@ -0,0 +1,166 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UTrap.icc
//
// Implementation of inline methods of UTrap
//
// 12.02.13 Marek Gayer
// Created from original implementation in Geant4
// --------------------------------------------------------------------
inline
double UTrap::GetZHalfLength() const
{
return fDz ;
}
inline
UVector3 UTrap::GetSymAxis() const
{
double cosTheta = 1.0 / std::sqrt(1 + fTthetaCphi * fTthetaCphi +
fTthetaSphi * fTthetaSphi) ;
return UVector3(fTthetaCphi * cosTheta,
fTthetaSphi * cosTheta,
cosTheta) ;
}
inline
double UTrap::GetYHalfLength1() const
{
return fDy1 ;
}
inline
double UTrap::GetXHalfLength1() const
{
return fDx1 ;
}
inline
double UTrap::GetXHalfLength2() const
{
return fDx2 ;
}
inline
double UTrap::GetTanAlpha1() const
{
return fTalpha1 ;
}
inline
double UTrap::GetYHalfLength2() const
{
return fDy2 ;
}
inline
double UTrap::GetXHalfLength3() const
{
return fDx3 ;
}
inline
double UTrap::GetXHalfLength4() const
{
return fDx4 ;
}
inline
double UTrap::GetTanAlpha2() const
{
return fTalpha2 ;
}
inline
double UTrap::GetThetaCphi() const
{
return fTthetaCphi ;
}
inline
double UTrap::GetThetaSphi() const
{
return fTthetaSphi ;
}
inline
UTrapSidePlane UTrap::GetSidePlane(int n) const
{
return fPlanes[n] ;
}
inline
double UTrap::GetFaceArea(const UVector3& p0, const UVector3& p1,
const UVector3& p2, const UVector3& p3)
{
double area = 0.5 * ((p1 - p0).Cross(p2 - p1).Mag() + (p3 - p2).Cross(p0 - p3).Mag());
return area;
}
inline
double UTrap::Capacity()
{
if (fCubicVolume != 0.)
{
;
}
else
{
fCubicVolume = fDz * ((fDx1 + fDx2 + fDx3 + fDx4) * (fDy1 + fDy2)
+ (fDx4 + fDx3 - fDx2 - fDx1) * (fDy2 - fDy1) / 3);
}
return fCubicVolume;
}
inline
double UTrap::SurfaceArea()
{
if (fSurfaceArea != 0.)
{
;
}
else
{
UVector3 ba(fDx1 - fDx2 + fTalpha1 * 2 * fDy1, 2 * fDy1, 0);
UVector3 bc(2 * fDz * fTthetaCphi - (fDx4 - fDx2) + fTalpha2 * fDy2 - fTalpha1 * fDy1,
2 * fDz * fTthetaSphi + fDy2 - fDy1, 2 * fDz);
UVector3 dc(-fDx4 + fDx3 + 2 * fTalpha2 * fDy2, 2 * fDy2, 0);
UVector3 da(-2 * fDz * fTthetaCphi - (fDx1 - fDx3) - fTalpha1 * fDy1 + fTalpha2 * fDy2,
-2 * fDz * fTthetaSphi - fDy1 + fDy2, -2 * fDz);
UVector3 ef(fDx2 - fDx1 + 2 * fTalpha1 * fDy1, 2 * fDy1, 0);
UVector3 eh(2 * fDz * fTthetaCphi + fDx3 - fDx1 + fTalpha1 * fDy1 - fTalpha2 * fDy2,
2 * fDz * fTthetaSphi - fDy2 + fDy1, 2 * fDz);
UVector3 gh(fDx3 - fDx4 - 2 * fTalpha2 * fDy2, -2 * fDy2, 0);
UVector3 gf(-2 * fDz * fTthetaCphi + fDx2 - fDx4 + fTalpha1 * fDy1 - fTalpha2 * fDy2,
-2 * fDz * fTthetaSphi + fDy1 - fDy2, -2 * fDz);
UVector3 cr;
cr = ba.Cross(bc);
double babc = cr.Mag();
cr = dc.Cross(da);
double dcda = cr.Mag();
cr = ef.Cross(eh);
double efeh = cr.Mag();
cr = gh.Cross(gf);
double ghgf = cr.Mag();
fSurfaceArea = 2 * fDy1 * (fDx1 + fDx2) + 2 * fDy2 * (fDx3 + fDx4)
+ (fDx1 + fDx3)
* std::sqrt(4 * fDz * fDz + std::pow(fDy2 - fDy1 - 2 * fDz * fTthetaSphi, 2))
+ (fDx2 + fDx4)
* std::sqrt(4 * fDz * fDz + std::pow(fDy2 - fDy1 + 2 * fDz * fTthetaSphi, 2))
+ 0.5 * (babc + dcda + efeh + ghgf);
}
return fSurfaceArea;
}
+115
View File
@@ -0,0 +1,115 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UTrd
//
// Class description:
//
// A UTrd is a trapezoid with the x and y dimensions varying along z
// functions.
//
// 19.10.12 Marek Gayer
// Created from original implementation in Geant4
// --------------------------------------------------------------------
#ifndef USOLIDS_UTrd
#define USOLIDS_UTrd
#include "VUSolid.hh"
#include "UUtils.hh"
class UTrd : public VUSolid
{
enum ESide {kUndefined, kPX, kMX, kPY, kMY, kPZ, kMZ};
public:
UTrd() : VUSolid(), fDx1(0), fDx2(0), fDy1(0), fDy2(0), fDz(0) {}
UTrd(const std::string& pName, double pdx1, double pdx2, double pdy1, double pdy2, double pdz);
virtual ~UTrd() {}
UTrd(const UTrd& rhs);
UTrd& operator=(const UTrd& rhs);
// Copy constructor and assignment operator
// Accessors
inline double GetXHalfLength1() const;
inline double GetXHalfLength2() const;
inline double GetYHalfLength1() const;
inline double GetYHalfLength2() const;
inline double GetZHalfLength() const;
// Modifiers
inline void SetXHalfLength1(double val);
inline void SetXHalfLength2(double val);
inline void SetYHalfLength1(double val);
inline void SetYHalfLength2(double val);
inline void SetZHalfLength(double val);
// Navigation methods
EnumInside Inside(const UVector3& aPoint) const;
virtual double SafetyFromInside(const UVector3& aPoint, bool aAccurate = false) const;
double SafetyFromInsideAccurate(const UVector3& aPoint) const;
virtual double SafetyFromOutside(const UVector3& aPoint, bool aAccurate = false) const;
double SafetyFromOutsideAccurate(const UVector3& aPoint) const;
virtual double DistanceToIn(const UVector3& aPoint,
const UVector3& aDirection,
// UVector3 &aNormalVector,
double aPstep = UUtils::kInfinity) const;
virtual double DistanceToOut(const UVector3& aPoint,
const UVector3& aDirection,
UVector3& aNormalVector,
bool& aConvex,
double aPstep = UUtils::kInfinity) const;
virtual bool Normal(const UVector3& aPoint, UVector3& aNormal) const;
void CheckAndSetAllParameters ( double pdx1, double pdx2,
double pdy1, double pdy2,
double pdz );
void SetAllParameters ( double pdx1, double pdx2,
double pdy1, double pdy2,
double pdz );
// virtual void Extent ( EAxisType aAxis, double &aMin, double &aMax ) const;
void Extent(UVector3& aMin, UVector3& aMax) const;
inline double Capacity();
inline double SurfaceArea();
VUSolid* Clone() const;
UGeometryType GetEntityType() const;
virtual void ComputeBBox(UBBox* /*aBox*/, bool /*aStore = false*/) {}
//G4Visualisation
virtual void GetParametersList(int /*aNumber*/, double* /*aArray*/) const;
std::ostream& StreamInfo(std::ostream& os) const;
UVector3 GetPointOnSurface() const;
private:
UVector3 ApproxSurfaceNormal(const UVector3& p) const;
inline double amin(int n, const double* a) const;
inline double amax(int n, const double* a)const;
double fDx1, fDx2, fDy1, fDy2, fDz;
double fCubicVolume; // Cubic Volume
double fSurfaceArea; // Surface Area
};
#include "UTrd.icc"
#endif
+142
View File
@@ -0,0 +1,142 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UTrd.icc
//
// Implementation of inline methods of UTrd
//
// 19.10.12 Marek Gayer
// Created from original implementation in Geant4
// --------------------------------------------------------------------
inline
double UTrd::GetXHalfLength1() const
{
return fDx1;
}
inline
double UTrd::GetXHalfLength2() const
{
return fDx2;
}
inline
double UTrd::GetYHalfLength1() const
{
return fDy1;
}
inline
double UTrd::GetYHalfLength2() const
{
return fDy2;
}
inline
double UTrd::GetZHalfLength() const
{
return fDz;
}
inline
void UTrd::SetXHalfLength1(double val)
{
fDx1 = val;
fCubicVolume = 0.;
fSurfaceArea = 0;
}
inline
void UTrd::SetXHalfLength2(double val)
{
fDx2 = val;
fCubicVolume = 0.;
fSurfaceArea = 0;
}
inline
void UTrd::SetYHalfLength1(double val)
{
fDy1 = val;
fCubicVolume = 0.;
fSurfaceArea = 0;
}
inline
void UTrd::SetYHalfLength2(double val)
{
fDy2 = val;
fCubicVolume = 0.;
fSurfaceArea = 0;
}
inline
void UTrd::SetZHalfLength(double val)
{
fDz = val;
fCubicVolume = 0.;
fSurfaceArea = 0;
}
inline
double UTrd::Capacity()
{
if (fCubicVolume != 0.)
{
;
}
else
{
fCubicVolume = 2 * fDz * ((fDx1 + fDx2) * (fDy1 + fDy2)
+ (fDx2 - fDx1) * (fDy2 - fDy1) / 3);
}
return fCubicVolume;
}
inline
double UTrd::SurfaceArea()
{
if (fSurfaceArea != 0.)
{
;
}
else
{
fSurfaceArea = 4 * (fDx1 * fDy1 + fDx2 * fDy2)
+ 2 * ((fDy1 + fDy2) * std::sqrt(4 * fDz * fDz + (fDx2 - fDx1) * (fDx2 - fDx1))
+ (fDx1 + fDx2) * std::sqrt(4 * fDz * fDz + (fDy2 - fDy1) * (fDy2 - fDy1)));
}
return fSurfaceArea;
}
inline double UTrd::amin(int n, const double* a) const
{
// Return value from array with the minimum element.
double xmin = a[0];
for (int i = 1; i < n; i++)
{
if (xmin > a[i]) xmin = a[i];
}
return xmin;
}
inline double UTrd::amax(int n, const double* a)const
{
// Return value from array with the maximum element.
double xmax = a[0];
for (int i = 1; i < n; i++)
{
if (xmax < a[i]) xmax = a[i];
}
return xmax;
}
+151
View File
@@ -0,0 +1,151 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UTriangularFacet
//
// Class description:
//
// The UTriangularFacet class is used for the contruction of
// UTessellatedSolid.
// It is defined by three fVertices, which shall be supplied in anti-clockwise
// order looking from the outsider of the solid where it belongs.
// Its constructor:
//
// UTriangularFacet (const UVector3 Pt0, const UVector3 vt1,
// const UVector3 vt2, UFacetVertexType);
//
// takes 4 parameters to define the three fVertices:
// 1) UFacetvertexType = "ABSOLUTE": in this case Pt0, vt1 and vt2 are
// the 3 fVertices in anti-clockwise order looking from the outsider.
// 2) UFacetvertexType = "RELATIVE": in this case the first vertex is Pt0,
// the second vertex is Pt0+vt1 and the third vertex is Pt0+vt2, all
// in anti-clockwise order when looking from the outsider.
//
// 22.08.12 Marek Gayer
// Created from original implementation in Geant4
// --------------------------------------------------------------------
#ifndef UTriangularFacet_hh
#define UTriangularFacet_hh 1
#include "VUFacet.hh"
#include "UVector3.hh"
#include "UTessellatedGeometryAlgorithms.hh"
class UTriangularFacet : public VUFacet
{
public:
UTriangularFacet(const UVector3& vt0, const UVector3& vt1, const UVector3& vt2, UFacetVertexType);
UTriangularFacet();
~UTriangularFacet();
UTriangularFacet(const UTriangularFacet& right);
UTriangularFacet& operator=(const UTriangularFacet& right);
VUFacet* GetClone();
UTriangularFacet* GetFlippedFacet();
UVector3 Distance(const UVector3& p);
double Distance(const UVector3& p, const double minDist);
double Distance(const UVector3& p, const double minDist, const bool outgoing);
double Extent(const UVector3 axis);
bool Intersect(const UVector3& p, const UVector3& v, const bool outgoing, double& distance, double& distFromSurface, UVector3& normal);
double GetArea();
UVector3 GetPointOnFace() const;
UVector3 GetSurfaceNormal() const;
inline bool IsDefined() const
{
return fIsDefined;
}
UGeometryType GetEntityType() const;
inline int GetNumberOfVertices() const
{
return 3;
}
UVector3 GetVertex(int i) const
{
int indice = fIndices[i];
return indice < 0 ? (*fVertices)[i] : (*fVertices)[indice];
}
inline void SetVertex(int i, const UVector3& val)
{
(*fVertices)[i] = val;
}
inline UVector3 GetCircumcentre() const
{
return fCircumcentre;
}
inline double GetRadius() const
{
return fRadius;
}
void SetSurfaceNormal(UVector3 normal);
int AllocatedMemory()
{
int size = sizeof(*this);
// size += geometryType.length();
// size += GetNumberOfVertices() * sizeof(UVector3);
//7 size += E.size() * sizeof(UVector3);
return size;
}
inline int GetVertexIndex(int i) const
{
return fIndices[i];
}
inline void SetVertexIndex(int i, int j)
{
fIndices[i] = j;
}
inline void SetVertices(std::vector<UVector3>* v)
{
if (fIndices[0] < 0 && fVertices) delete fVertices;
fVertices = v;
}
private:
UVector3 fSurfaceNormal;
double fArea;
UVector3 fCircumcentre;
double fRadius;
int fIndices[3];
std::vector<UVector3>* fVertices;
void CopyFrom(const UTriangularFacet& rhs);
private:
double fA, fB, fC;
double fDet;
double fSqrDist;
UVector3 fE1, fE2;
bool fIsDefined;
};
#endif
+192
View File
@@ -0,0 +1,192 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UTubs
//
// Class description:
//
// A tube or tube segment with curved sides parallel to
// the z-axis. The tube has a specified half-length along
// the z-axis, about which it is centered, and a given
// minimum and maximum radius. A minimum radius of 0
// corresponds to filled tube /cylinder. The tube segment is
// specified by starting and delta angles for phi, with 0
// being the +x axis, PI/2 the +y axis.
// A delta angle of 2PI signifies a complete, unsegmented
// tube/cylinder.
//
// Member Data:
//
// fRMin Inner radius
// fRMax Outer radius
// fDz half length in z
//
// fSPhi The starting phi angle in radians,
// adjusted such that fSPhi+fDPhi<=2PI, fSPhi>-2PI
//
// fDPhi Delta angle of the segment.
//
// fPhiFullTube Boolean variable used for indicate the Phi Section
//
// 19.10.12 Marek Gayer
// Created from original implementation in Geant4
// --------------------------------------------------------------------
#ifndef UTUBS_HH
#define UTUBS_HH
#include "VUSolid.hh"
class UTubs : public VUSolid
{
public: // with description
UTubs(const std::string& pName,
double pRMin,
double pRMax,
double pDz,
double pSPhi,
double pDPhi);
//
// Constructs a tubs with the given name and dimensions
virtual ~UTubs();
//
// Destructor
// Accessors
inline double GetInnerRadius() const;
inline double GetOuterRadius() const;
inline double GetZHalfLength() const;
inline double GetStartPhiAngle() const;
inline double GetDeltaPhiAngle() const;
// Modifiers
inline void SetInnerRadius(double newRMin);
inline void SetOuterRadius(double newRMax);
inline void SetZHalfLength(double newDz);
inline void SetStartPhiAngle(double newSPhi, bool trig = true);
inline void SetDeltaPhiAngle(double newDPhi);
// Methods for solid
inline double Capacity();
inline double SurfaceArea();
VUSolid::EnumInside Inside(const UVector3& p) const;
bool Normal(const UVector3& p, UVector3& normal) const;
double DistanceToIn(const UVector3& p, const UVector3& v,
double aPstep = UUtils::kInfinity) const;
double SafetyFromInside(const UVector3& p, bool precise = false) const;
double DistanceToOut(const UVector3& p, const UVector3& v, UVector3& n,
bool& validNorm, double aPstep=UUtils::kInfinity) const;
double SafetyFromOutside(const UVector3& p, bool precise = false ) const;
inline double SafetyFromInsideR(const UVector3& p, const double rho,
bool precise = false) const;
inline double SafetyFromOutsideR(const UVector3& p, const double rho,
bool precise = false) const;
UGeometryType GetEntityType() const;
UVector3 GetPointOnSurface() const;
VUSolid* Clone() const;
std::ostream& StreamInfo(std::ostream& os) const;
void Extent(UVector3& aMin, UVector3& aMax) const;
virtual void GetParametersList(int /*aNumber*/, double* /*aArray*/) const;
virtual void ComputeBBox(UBBox* /*aBox*/, bool /*aStore = false*/) {}
public: // without description
UTubs();
//
// Fake default constructor for usage restricted to direct object
// persistency for clients requiring preallocation of memory for
// persistifiable objects.
UTubs(const UTubs& rhs);
UTubs& operator=(const UTubs& rhs);
// Copy constructor and assignment operator.
// Older names for access functions
inline double GetRMin() const;
inline double GetRMax() const;
inline double GetDz() const;
inline double GetSPhi() const;
inline double GetDPhi() const;
protected:
// UVector3List*
// CreateRotatedVertices( const UAffineTransform& pTransform ) const;
//
// Creates the List of transformed vertices in the format required
// for VUSolid:: ClipCrossSection and ClipBetweenSections
inline void Initialize();
//
// Reset relevant values to zero
inline void CheckSPhiAngle(double sPhi);
inline void CheckDPhiAngle(double dPhi);
inline void CheckPhiAngles(double sPhi, double dPhi);
//
// Reset relevant flags and angle values
inline void InitializeTrigonometry();
//
// Recompute relevant trigonometric values and cache them
virtual UVector3 ApproxSurfaceNormal(const UVector3& p) const;
//
// Algorithm for SurfaceNormal() following the original
// specification for points not on the surface
inline double SafetyToPhi(const UVector3& p, const double rho, bool& outside) const;
protected:
double fCubicVolume, fSurfaceArea;
// Used by distanceToOut
//
enum ESide {kNull, kRMin, kRMax, kSPhi, kEPhi, kPZ, kMZ};
// Used by normal
//
enum ENorm {kNRMin, kNRMax, kNSPhi, kNEPhi, kNZ};
double kRadTolerance, kAngTolerance;
//
// Radial and angular tolerances
double fRMin, fRMax, fDz, fSPhi, fDPhi;
//
// Radial and angular dimensions
double fSinCPhi, fCosCPhi, fCosHDPhiOT, fCosHDPhiIT,
fSinSPhi, fCosSPhi, fSinEPhi, fCosEPhi, fSinSPhiDPhi, fCosSPhiDPhi;
//
// Cached trigonometric values
bool fPhiFullTube;
//
// Flag for identification of section or full tube
};
#include "UTubs.icc"
#endif
+376
View File
@@ -0,0 +1,376 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UTubs.icc
//
// Implementation of inline methods of UTubs
//
// 19.10.12 Marek Gayer
// Created from original implementation in Geant4
// --------------------------------------------------------------------
inline
double UTubs::GetInnerRadius() const
{
return fRMin;
}
inline
double UTubs::GetOuterRadius() const
{
return fRMax;
}
inline
double UTubs::GetZHalfLength() const
{
return fDz;
}
inline
double UTubs::GetStartPhiAngle() const
{
return fSPhi;
}
inline
double UTubs::GetDeltaPhiAngle() const
{
return fDPhi;
}
inline
void UTubs::Initialize()
{
fCubicVolume = 0.;
fSurfaceArea = 0.;
}
inline
void UTubs::InitializeTrigonometry()
{
double hDPhi = 0.5 * fDPhi; // half delta phi
double cPhi = fSPhi + hDPhi;
double ePhi = fSPhi + fDPhi;
fSinCPhi = std::sin(cPhi);
fCosCPhi = std::cos(cPhi);
fCosHDPhiIT = std::cos(hDPhi - 0.5 * kAngTolerance); // inner/outer tol half dphi
fCosHDPhiOT = std::cos(hDPhi + 0.5 * kAngTolerance);
fSinSPhi = std::sin(fSPhi);
fCosSPhi = std::cos(fSPhi);
fSinEPhi = std::sin(ePhi);
fCosEPhi = std::cos(ePhi);
fSinSPhiDPhi = std::sin(fSPhi + fDPhi);
fCosSPhiDPhi = std::cos(fSPhi + fDPhi);
}
inline void UTubs::CheckSPhiAngle(double sPhi)
{
// Ensure fSphi in 0-2PI or -2PI-0 range if shape crosses 0
if (sPhi < 0)
{
fSPhi = 2 * UUtils::kPi - std::fmod(std::fabs(sPhi), 2 * UUtils::kPi);
}
else
{
fSPhi = std::fmod(sPhi, 2 * UUtils::kPi) ;
}
if (fSPhi + fDPhi > 2 * UUtils::kPi)
{
fSPhi -= 2 * UUtils::kPi ;
}
}
inline void UTubs::CheckDPhiAngle(double dPhi)
{
fPhiFullTube = true;
if (dPhi >= 2 * UUtils::kPi - kAngTolerance * 0.5)
{
fDPhi = 2 * UUtils::kPi;
fSPhi = 0;
}
else
{
fPhiFullTube = false;
if (dPhi > 0)
{
fDPhi = dPhi;
}
else
{
std::ostringstream message;
message << "Invalid dphi." << std::endl
<< "Negative or zero delta-Phi (" << dPhi << "), for solid: "
<< GetName();
UUtils::Exception("UTubs::CheckDPhiAngle()", "GeomSolids0002",
FatalError, 1, message.str().c_str());
}
}
}
inline void UTubs::CheckPhiAngles(double sPhi, double dPhi)
{
CheckDPhiAngle(dPhi);
if ((fDPhi < 2 * UUtils::kPi) && (sPhi))
{
CheckSPhiAngle(sPhi);
}
InitializeTrigonometry();
}
inline
void UTubs::SetInnerRadius(double newRMin)
{
if (newRMin < 0) // Check radii
{
std::ostringstream message;
message << "Invalid radii." << std::endl
<< "Invalid values for radii in solid " << GetName() << std::endl
<< " newRMin = " << newRMin
<< ", fRMax = " << fRMax << std::endl
<< " Negative inner radius!";
UUtils::Exception("UTubs::SetInnerRadius()", "GeomSolids0002",
FatalError, 1, message.str().c_str());
}
fRMin = newRMin;
Initialize();
}
inline
void UTubs::SetOuterRadius(double newRMax)
{
if (newRMax <= 0) // Check radii
{
std::ostringstream message;
message << "Invalid radii." << std::endl
<< "Invalid values for radii in solid " << GetName() << std::endl
<< " fRMin = " << fRMin
<< ", newRMax = " << newRMax << std::endl
<< " Invalid outer radius!";
UUtils::Exception("UTubs::SetOuterRadius()", "GeomSolids0002",
FatalError, 1, message.str().c_str());
}
fRMax = newRMax;
Initialize();
}
inline
void UTubs::SetZHalfLength(double newDz)
{
if (newDz <= 0) // Check z-len
{
std::ostringstream message;
message << "Invalid Z half-length." << std::endl
<< "Negative Z half-length (" << newDz << "), for solid: "
<< GetName();
UUtils::Exception("UTubs::SetZHalfLength()", "GeomSolids0002",
FatalError, 1, message.str().c_str());
}
fDz = newDz;
Initialize();
}
inline
void UTubs::SetStartPhiAngle(double newSPhi, bool 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 UTubs::SetDeltaPhiAngle(double newDPhi)
{
CheckPhiAngles(fSPhi, newDPhi);
Initialize();
}
// Older names for access functions
inline
double UTubs::GetRMin() const
{
return GetInnerRadius();
}
inline
double UTubs::GetRMax() const
{
return GetOuterRadius();
}
inline
double UTubs::GetDz() const
{
return GetZHalfLength() ;
}
inline
double UTubs::GetSPhi() const
{
return GetStartPhiAngle();
}
inline
double UTubs::GetDPhi() const
{
return GetDeltaPhiAngle();
}
inline
double UTubs::Capacity()
{
if (fCubicVolume != 0.)
{
;
}
else
{
fCubicVolume = fDPhi * fDz * (fRMax * fRMax - fRMin * fRMin);
}
return fCubicVolume;
}
inline
double UTubs::SurfaceArea()
{
if (fSurfaceArea != 0.)
{
;
}
else
{
fSurfaceArea = fDPhi * (fRMin + fRMax) * (2 * fDz + fRMax - fRMin);
if (!fPhiFullTube)
{
fSurfaceArea = fSurfaceArea + 4 * fDz * (fRMax - fRMin);
}
}
return fSurfaceArea;
}
inline
double UTubs::SafetyFromInsideR(const UVector3& p,
const double rho, bool) const
{
// Safety From Inside R, used for UPolycone Section
double safe = 0.0, safeR1, safeR2, safePhi;
if (fRMin)
{
safeR1 = rho - fRMin;
safeR2 = fRMax - rho;
if (safeR1 < safeR2)
{
safe = safeR1;
}
else
{
safe = safeR2;
}
}
else
{
safe = fRMax - rho;
}
// Check if phi divided, Calc distances closest phi plane
//
if (!fPhiFullTube)
{
if (p.y * fCosCPhi - p.x * fSinCPhi <= 0)
{
safePhi = -(p.x * fSinSPhi - p.y * fCosSPhi);
}
else
{
safePhi = (p.x * fSinEPhi - p.y * fCosEPhi);
}
if (safePhi < safe)
{
safe = safePhi;
}
}
return safe;
}
inline
double UTubs::SafetyFromOutsideR(const UVector3& p,
const double rho, bool) const
{
// Safety for R ,used in UPolycone for sections
double safe = 0.0, safe1, safe2;
double safePhi;
bool outside;
safe1 = rho-fRMin; //fRMin - rho;
safe2 = fRMax - rho;
if (safe1 < safe2)
{
safe = safe1;
}
else
{
safe = safe2;
}
if ((!fPhiFullTube) && (rho))
{
safePhi = SafetyToPhi(p,rho,outside);
if ((outside) && (safePhi > safe))
{
safe = safePhi;
}
}
return safe; // not accurate safety
}
inline
double UTubs::SafetyToPhi(const UVector3& p,
const double rho, bool& outside) const
{
double cosPsi, safePhi = 0.0;
// Psi=angle from central phi to point
//
cosPsi = (p.x * fCosCPhi + p.y * fSinCPhi) / rho;
outside = false;
if (cosPsi < std::cos(fDPhi * 0.5))
{
// Point lies outside phi range
//
outside=true;
if ((p.y * fCosCPhi - p.x * fSinCPhi) <= 0)
{
safePhi = std::fabs(p.x * fSinSPhi - p.y * fCosSPhi);
}
else
{
safePhi = std::fabs(p.x * fSinEPhi - p.y * fCosEPhi);
}
}
return safePhi;
}
+41
View File
@@ -0,0 +1,41 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UTypes
//
// Description:
//
// Internal utility types defined for the unified solids library
//
// 19.10.12 Marek Gayer
// --------------------------------------------------------------------
#ifndef USOLIDS_Utypes
#define USOLIDS_Utypes
#include "UVector3.hh"
#include <iostream>
#include <string>
#include <vector>
class __void__;
typedef unsigned int UInt_t;
struct UBBoxStruct
{
double extent[3]; // half-lengths on the 3 axis (arrays for indexing)
double orig[3]; // center coordinates
};
typedef UBBoxStruct UBBox;
typedef std::string UGeometryType;
#endif
+229
View File
@@ -0,0 +1,229 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UUtils
//
// Description:
//
// Utility namespace providing common constants and mathematical utilities.
//
// 19.10.12 Marek Gayer
// --------------------------------------------------------------------
#ifndef USOLIDS_UUtils
#define USOLIDS_UUtils
#include <iostream>
#include <fstream>
#include <limits>
#include <cmath>
#include <cfloat>
#include <vector>
#include <algorithm>
struct UVector3;
class UTransform3D;
enum ExceptionSeverity
{ FatalError, FatalErrorInArguments, Error, Warning, Info };
namespace UUtils
{
// Sign
inline short Sign(short a, short b);
inline int Sign(int a, int b);
inline long Sign(long a, long b);
inline float Sign(float a, float b);
inline double Sign(double a, double b);
// Trigonometric
static const double kPi = 3.14159265358979323846;
static const double kTwoPi = 2.0 * kPi;
static const double kRadToDeg = 180.0 / kPi;
static const double kDegToRad = kPi / 180.0;
static const double kSqrt2 = 1.4142135623730950488016887242097;
static const double kInfinity = DBL_MAX;
static const double kMeshAngleDefault = (kPi / 4); // Angle for mesh `wedges' in rads
static const int kMinMeshSections = 3; // Min wedges+1 to make
static const int kMaxMeshSections = 37; // max wedges+1 to make
inline double Infinity();
inline double ASin(double);
inline double ACos(double);
inline double ATan(double);
inline double ATan2(double, double);
//Warnings and Errors Messages
void Exception(const char* originOfException,
const char* exceptionCode,
ExceptionSeverity severity,
int level,
const char* description);
// Comparing floating points
inline bool AreEqualAbs(double af, double bf, double epsilon)
{
//return true if absolute difference between af and bf is less than epsilon
return std::abs(af - bf) < epsilon;
}
inline bool AreEqualRel(double af, double bf, double relPrec)
{
//return true if relative difference between af and bf is less than relPrec
return std::abs(af - bf) <= 0.5 * relPrec * (std::abs(af) + std::abs(bf));
}
// Locate Min, Max element number in an array
long LocMin(long n, const double* a);
long LocMax(long n, const double* a);
// TransformLimits: Use the transformation to convert the local limits defined
// by min/max vectors to the master frame. Returns modified limits.
void TransformLimits(UVector3& min, UVector3& max, const UTransform3D& transformation);
double Random(double min = 0.0, double max = 1.0);
// Templates:
template<typename T>
struct CompareDesc
{
CompareDesc(T d) : fData(d) {}
template<typename Index>
bool operator()(Index i1, Index i2)
{
return *(fData + i1) > *(fData + i2);
}
T fData;
};
template<typename T>
struct CompareAsc
{
CompareAsc(T d) : fData(d) {}
template<typename Index>
bool operator()(Index i1, Index i2)
{
return *(fData + i1) < *(fData + i2);
}
T fData;
};
std::string ToString(int number);
std::string ToString(double number);
int FileSize(const std::string& filePath);
int StrPos(const std::string& haystack, const std::string& needle);
inline double GetRadiusInRing(double rmin, double rmax);
template <class T>
inline T sqr(const T& x)
{
return x * x;
}
inline bool StrEnds(std::string const& fullString, std::string const& ending)
{
if (fullString.length() >= ending.length())
{
return (0 == fullString.compare(fullString.length() - ending.length(), ending.length(), ending));
}
else
{
return false;
}
}
}
inline double UUtils::GetRadiusInRing(double rmin, double rmax)
{
// Generate radius in annular ring according to uniform area
//
if (rmin <= 0.)
{
return rmax * std::sqrt(Random());
}
if (rmin != rmax)
{
return std::sqrt(Random()
* (sqr(rmax) - sqr(rmin)) + sqr(rmin));
}
return rmin;
}
//____________________________________________________________________________
inline double UUtils::Infinity()
{
// returns an infinity as defined by the IEEE standard
return std::numeric_limits<double>::infinity();
}
//---- Sign --------------------------------------------------------------------
inline short UUtils::Sign(short a, short b)
{
return (b >= 0) ? std::abs(a) : -std::abs(a);
}
inline int UUtils::Sign(int a, int b)
{
return (b >= 0) ? std::abs(a) : -std::abs(a);
}
inline long UUtils::Sign(long a, long b)
{
return (b >= 0) ? std::abs(a) : -std::abs(a);
}
inline float UUtils::Sign(float a, float b)
{
return (b >= 0) ? std::abs(a) : -std::abs(a);
}
inline double UUtils::Sign(double a, double b)
{
return (b >= 0) ? std::abs(a) : -std::abs(a);
}
//---- Trigonometric------------------------------------------------------------
inline double UUtils::ASin(double x)
{
if (x < -1.) return -kPi / 2;
if (x > 1.) return kPi / 2;
return std::asin(x);
}
inline double UUtils::ACos(double x)
{
if (x < -1.) return kPi;
if (x > 1.) return 0;
return std::acos(x);
}
inline double UUtils::ATan2(double y, double x)
{
if (x != 0) return std::atan2(y, x);
if (y == 0) return 0;
if (y > 0) return kPi / 2;
else return -kPi / 2;
}
#endif
+68
View File
@@ -0,0 +1,68 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UVCSGface
//
// Class description:
//
// Definition of the virtual base class UVCSGface, one side (or face)
// of a CSG-like solid. It should be possible to build a CSG entirely out of
// connecting CSG faces.
// Each face has an inside and outside surface, the former represents
// the inside of the volume, the latter, the outside.
//
// 19.09.13 Marek Gayer
// Created from original implementation in Geant4
// --------------------------------------------------------------------
#ifndef UVCSGface_hh
#define UVCSGface_hh
#include "UTypes.hh"
#include "VUSolid.hh"
class UVoxelLimits;
class UAffineTransform;
class USolidExtentList;
class UVCSGface
{
public: // with description
UVCSGface() {}
virtual ~UVCSGface() {}
virtual bool Distance(const UVector3& p, const UVector3& v,
bool outgoing, double surfTolerance,
double& distance, double& distFromSurface,
UVector3& normal, bool& allBehind) = 0;
virtual double Safety(const UVector3& p, bool outgoing) = 0;
virtual VUSolid::EnumInside Inside(const UVector3& p, double tolerance,
double* bestDistance) = 0;
virtual UVector3 Normal(const UVector3& p,
double* bestDistance) = 0;
virtual double Extent(const UVector3 axis) = 0;
/* virtual void CalculateExtent( const EAxisType axis,
const UVoxelLimits &voxelLimit,
const UAffineTransform &tranform,
USolidExtentList &extentList ) = 0;*/
virtual UVCSGface* Clone() = 0;
virtual double SurfaceArea() = 0;
virtual UVector3 GetPointOnFace() = 0;
};
#endif
+145
View File
@@ -0,0 +1,145 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UVCSGfaceted
//
// Class description:
//
// Virtual class defining CSG-like type shape that is built entire
// of UCSGface faces.
//
// 19.09.13 Marek Gayer
// Created from original implementation in Geant4
// --------------------------------------------------------------------
#ifndef UVCSGfaceted_hh
#define UVCSGfaceted_hh
#include "VUSolid.hh"
#include "UVoxelizer.hh"
#include "UBox.hh"
#include "UReduciblePolygon.hh"
class UVCSGface;
class UVisExtent;
class UVCSGfaceted : public VUSolid
{
public: // with description
UVCSGfaceted(const std::string& name);
virtual ~UVCSGfaceted();
UVCSGfaceted(const UVCSGfaceted& source);
UVCSGfaceted& operator=(const UVCSGfaceted& source);
VUSolid::EnumInside InsideNoVoxels(const UVector3& p) const;
virtual VUSolid::EnumInside Inside(const UVector3& p) const;
virtual bool Normal(const UVector3& p, UVector3& n) const;
double DistanceToInNoVoxels(const UVector3& p,
const UVector3& v) const;
virtual double DistanceToIn(const UVector3& p,
const UVector3& v, double aPstep = UUtils::kInfinity) const;
virtual double SafetyFromOutside(const UVector3& aPoint, bool aAccurate = false) const;
double DistanceTo(const UVector3& p, const bool outgoing) const;
double DistanceToOutNoVoxels(const UVector3& p,
const UVector3& v,
UVector3& n,
bool& aConvex) const;
virtual double DistanceToOut(const UVector3& p,
const UVector3& v,
UVector3& n,
bool& aConvex,
double aPstep = UUtils::kInfinity) const;
virtual double SafetyFromInside(const UVector3& aPoint, bool aAccurate = false) const;
virtual double SafetyFromInsideNoVoxels(const UVector3& aPoint, bool aAccurate = false) const;
virtual UGeometryType GetEntityType() const;
virtual std::ostream& StreamInfo(std::ostream& os) const;
int GetCubVolStatistics() const;
double GetCubVolEpsilon() const;
void SetCubVolStatistics(int st);
void SetCubVolEpsilon(double ep);
int GetAreaStatistics() const;
double GetAreaAccuracy() const;
void SetAreaStatistics(int st);
void SetAreaAccuracy(double ep);
virtual double Capacity();
// Returns an estimation of the geometrical cubic volume of the
// solid. Caches the computed value once computed the first time.
virtual double SurfaceArea();
// Returns an estimation of the geometrical surface area of the
// solid. Caches the computed value once computed the first time.
public: // without description
protected: // without description
double SafetyFromInsideSection(int index, const UVector3& p, UBits& bits) const;
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;
}
int numFace;
UVCSGface** faces;
double fCubicVolume;
double fSurfaceArea;
std::vector<double> fZs; // z coordinates of given sections
std::vector<std::vector<int> > fCandidates; // precalculated candidates for each of the section
int fMaxSection; // maximum index number of sections of the solid (i.e. their number - 1). regular polyhedra with z = 1,2,3 section has 2 sections numbered 0 and 1, therefore the fMaxSection will be 1 (that is 2 - 1 = 1)
mutable UBox fBox; // bounding box of the polyhedra, used in some methods
double fBoxShift; // z-shift which is added during evaluation, because bounding box center does not have to be at (0,0,0)
bool fNoVoxels; // if set to true, no voxelized algorithms will be used
UVector3 GetPointOnSurfaceGeneric()const;
// Returns a random point located on the surface of the solid
// in case of generic Polycone or generic Polyhedra.
void CopyStuff(const UVCSGfaceted& source);
void DeleteStuff();
void FindCandidates(double z, std::vector <int>& candidates, bool sides = false);
void InitVoxels(UReduciblePolygon& z, double radius);
private:
int fStatistics;
double fCubVolEpsilon;
double fAreaAccuracy;
// Statistics, error accuracy for volume estimation.
};
#endif
+407
View File
@@ -0,0 +1,407 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UVector2
//
// Class description:
//
// UVector2 is a general 2-vector class defining vectors in two
// dimension using double components.
//
// 19.09.12 Marek Gayer
// Created from original implementation in CLHEP
// --------------------------------------------------------------------
#ifndef UVECTOR2_H
#define UVECTOR2_H
#include <cmath>
#include <iostream>
#include "UVector3.hh"
// Declarations of classes and global methods
class UVector2;
std::ostream& operator << (std::ostream&, const UVector2&);
//std::istream & operator >> (std::istream &, UVector2 &);
inline double operator * (const UVector2& a, const UVector2& b);
inline UVector2 operator * (const UVector2& p, double a);
inline UVector2 operator * (double a, const UVector2& p);
UVector2 operator / (const UVector2& p, double a);
inline UVector2 operator + (const UVector2& a, const UVector2& b);
inline UVector2 operator - (const UVector2& a, const UVector2& b);
/**
* @author
* @ingroup vector
*/
class UVector2
{
public:
enum { X = 0, Y = 1, NUM_COORDINATES = 2, SIZE = NUM_COORDINATES };
// Safe indexing of the coordinates when using with matrices, arrays, etc.
inline UVector2(double x = 0.0, double y = 0.0);
// The constructor.
inline UVector2(const UVector2& p);
// The copy constructor.
explicit UVector2(const UVector3& s);
// "demotion" constructor"
// WARNING -- THIS IGNORES THE Z COMPONENT OF THE UVector3.
// SO IN GENERAL, UVector2(v)==v WILL NOT HOLD!
inline ~UVector2();
// The destructor.
// inline double x() const;
// inline double y() const;
// The components in cartesian coordinate system.
double operator()(int i) const;
inline double operator [](int i) const;
// Get components by index. 0-based.
double& operator()(int i);
inline double& operator [](int i);
// Set components by index. 0-based.
inline void setX(double x);
inline void setY(double y);
inline void set(double x, double y);
// Set the components in cartesian coordinate system.
inline double phi() const;
// The azimuth angle.
inline double mag2() const;
// The magnitude squared.
inline double mag() const;
// The magnitude.
inline double r() const;
// r in polar coordinates (r, phi): equal to mag().
inline void setPhi(double phi);
// Set phi keeping mag constant.
inline void setMag(double r);
// Set magnitude keeping phi constant.
inline void setR(double r);
// Set R keeping phi constant. Same as setMag.
inline void setPolar(double r, double phi);
// Set by polar coordinates.
inline UVector2& operator = (const UVector2& p);
// Assignment.
inline bool operator == (const UVector2& v) const;
inline bool operator != (const UVector2& v) const;
// Comparisons.
int compare(const UVector2& v) const;
bool operator > (const UVector2& v) const;
bool operator < (const UVector2& v) const;
bool operator>= (const UVector2& v) const;
bool operator<= (const UVector2& v) const;
// dictionary ordering according to y, then x component
static inline double getTolerance();
static double setTolerance(double tol);
double howNear(const UVector2& p) const;
bool isNear(const UVector2& p, double epsilon = tolerance) const;
double howParallel(const UVector2& p) const;
bool isParallel
(const UVector2& p, double epsilon = tolerance) const;
double howOrthogonal(const UVector2& p) const;
bool isOrthogonal
(const UVector2& p, double epsilon = tolerance) const;
inline UVector2& operator += (const UVector2& p);
// Addition.
inline UVector2& operator -= (const UVector2& p);
// Subtraction.
inline UVector2 operator - () const;
// Unary minus.
inline UVector2& operator *= (double a);
// Scaling with real numbers.
inline UVector2 unit() const;
// Unit vector parallel to this.
inline UVector2 orthogonal() const;
// Vector orthogonal to this.
inline double dot(const UVector2& p) const;
// Scalar product.
inline double angle(const UVector2&) const;
// The angle w.r.t. another 2-vector.
void rotate(double);
// Rotates the UVector2.
operator UVector3() const;
// Cast a UVector2 as a UVector3.
// The remaining methods are friends, thus defined at global scope:
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
friend std::ostream& operator<< (std::ostream&, const UVector2&);
// Output to a stream.
inline friend double operator * (const UVector2& a,
const UVector2& b);
// Scalar product.
inline friend UVector2 operator * (const UVector2& p, double a);
// v*c
inline friend UVector2 operator * (double a, const UVector2& p);
// c*v
friend UVector2 operator / (const UVector2& p, double a);
// v/c
inline friend UVector2 operator + (const UVector2& a,
const UVector2& b);
// v1+v2
inline friend UVector2 operator - (const UVector2& a,
const UVector2& b);
// v1-v2
enum { ZMpvToleranceTicks = 100 };
double x;
double y;
// The components.
private:
static double tolerance;
// default tolerance criterion for isNear() to return true.
}; // UVector2
static const UVector2 X_HAT2(1.0, 0.0);
static const UVector2 Y_HAT2(0.0, 1.0);
/*
inline double UVector2::x() const {
return x;
}
inline double UVector2::y() const {
return y;
}
*/
inline UVector2::UVector2(double x1, double y1)
: x(x1), y(y1) {}
inline UVector2::UVector2(const UVector3& s1)
: x(s1.x), y(s1.y) {}
inline void UVector2::setX(double x1)
{
x = x1;
}
inline void UVector2::setY(double y1)
{
y = y1;
}
inline void UVector2::set(double x1, double y1)
{
x = x1;
y = y1;
}
double& UVector2::operator[](int i)
{
return operator()(i);
}
double UVector2::operator[](int i) const
{
return operator()(i);
}
inline UVector2::UVector2(const UVector2& p)
: x(p.x), y(p.y) {}
inline UVector2::~UVector2() {}
inline UVector2& UVector2::operator = (const UVector2& p)
{
if (this == &p) { return *this; }
x = p.x;
y = p.y;
return *this;
}
inline bool UVector2::operator == (const UVector2& v) const
{
return (v.x == x && v.y == y) ? true : false;
}
inline bool UVector2::operator != (const UVector2& v) const
{
return (v.x != x || v.y != y) ? true : false;
}
inline UVector2& UVector2::operator += (const UVector2& p)
{
x += p.x;
y += p.y;
return *this;
}
inline UVector2& UVector2::operator -= (const UVector2& p)
{
x -= p.x;
y -= p.y;
return *this;
}
inline UVector2 UVector2::operator - () const
{
return UVector2(-x, -y);
}
inline UVector2& UVector2::operator *= (double a)
{
x *= a;
y *= a;
return *this;
}
inline double UVector2::dot(const UVector2& p) const
{
return x * p.x + y * p.y;
}
inline double UVector2::mag2() const
{
return x * x + y * y;
}
inline double UVector2::mag() const
{
return std::sqrt(mag2());
}
inline double UVector2::r() const
{
return std::sqrt(mag2());
}
inline UVector2 UVector2::unit() const
{
double tot = mag2();
UVector2 p(*this);
return tot > 0.0 ? p *= (1.0 / std::sqrt(tot)) : UVector2(1, 0);
}
inline UVector2 UVector2::orthogonal() const
{
double x1 = std::fabs(x), y1 = std::fabs(y);
if (x1 < y1)
{
return UVector2(y, -x);
}
else
{
return UVector2(-y, x);
}
}
inline double UVector2::phi() const
{
return x == 0.0 && y == 0.0 ? 0.0 : std::atan2(y, x);
}
inline double UVector2::angle(const UVector2& q) const
{
double ptot2 = mag2() * q.mag2();
return ptot2 <= 0.0 ? 0.0 : std::acos(dot(q) / std::sqrt(ptot2));
}
inline void UVector2::setMag(double r1)
{
double ph = phi();
setX(r1 * std::cos(ph));
setY(r1 * std::sin(ph));
}
inline void UVector2::setR(double r1)
{
setMag(r1);
}
inline void UVector2::setPhi(double phi1)
{
double ma = mag();
setX(ma * std::cos(phi1));
setY(ma * std::sin(phi1));
}
inline void UVector2::setPolar(double r1, double phi1)
{
setX(r1 * std::cos(phi1));
setY(r1 * std::sin(phi1));
}
inline UVector2 operator + (const UVector2& a, const UVector2& b)
{
return UVector2(a.x + b.x, a.y + b.y);
}
inline UVector2 operator - (const UVector2& a, const UVector2& b)
{
return UVector2(a.x - b.x, a.y - b.y);
}
inline UVector2 operator * (const UVector2& p, double a)
{
return UVector2(a * p.x, a * p.y);
}
inline UVector2 operator * (double a, const UVector2& p)
{
return UVector2(a * p.x, a * p.y);
}
inline double operator * (const UVector2& a, const UVector2& b)
{
return a.dot(b);
}
inline double UVector2::getTolerance()
{
return tolerance;
}
#endif /* UVECTOR2_H */
+180
View File
@@ -0,0 +1,180 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UVector2.icc
//
// Implementation of inline methods of UVector2
//
// 19.10.12 Marek Gayer
// Created from original implementation in CLHEP
// --------------------------------------------------------------------
#include <cmath>
namespace CLHEP {
inline double Hep2Vector::x() const {
return dx;
}
inline double Hep2Vector::y() const {
return dy;
}
inline Hep2Vector::Hep2Vector(double x1, double y1)
: dx(x1), dy(y1) {}
inline Hep2Vector::Hep2Vector( const Hep3Vector & s)
: dx(s.x()), dy(s.y()) {}
inline void Hep2Vector::setX(double x1) {
dx = x1;
}
inline void Hep2Vector::setY(double y1) {
dy = y1;
}
inline void Hep2Vector::set(double x1, double y1) {
dx = x1;
dy = y1;
}
double & Hep2Vector::operator[] (int i) { return operator()(i); }
double Hep2Vector::operator[] (int i) const { return operator()(i); }
inline Hep2Vector::Hep2Vector(const Hep2Vector & p)
: dx(p.x()), dy(p.y()) {}
inline Hep2Vector::~Hep2Vector() {}
inline Hep2Vector & Hep2Vector::operator = (const Hep2Vector & p) {
dx = p.x();
dy = p.y();
return *this;
}
inline bool Hep2Vector::operator == (const Hep2Vector& v) const {
return (v.x()==x() && v.y()==y()) ? true : false;
}
inline bool Hep2Vector::operator != (const Hep2Vector& v) const {
return (v.x()!=x() || v.y()!=y()) ? true : false;
}
inline Hep2Vector& Hep2Vector::operator += (const Hep2Vector & p) {
dx += p.x();
dy += p.y();
return *this;
}
inline Hep2Vector& Hep2Vector::operator -= (const Hep2Vector & p) {
dx -= p.x();
dy -= p.y();
return *this;
}
inline Hep2Vector Hep2Vector::operator - () const {
return Hep2Vector(-dx, -dy);
}
inline Hep2Vector& Hep2Vector::operator *= (double a) {
dx *= a;
dy *= a;
return *this;
}
inline double Hep2Vector::dot(const Hep2Vector & p) const {
return dx*p.x() + dy*p.y();
}
inline double Hep2Vector::mag2() const {
return dx*dx + dy*dy;
}
inline double Hep2Vector::mag() const {
return std::sqrt(mag2());
}
inline double Hep2Vector::r() const {
return std::sqrt(mag2());
}
inline Hep2Vector Hep2Vector::unit() const {
double tot = mag2();
Hep2Vector p(*this);
return tot > 0.0 ? p *= (1.0/std::sqrt(tot)) : Hep2Vector(1,0);
}
inline Hep2Vector Hep2Vector::orthogonal() const {
double x1 = std::fabs(dx), y1 = std::fabs(dy);
if (x1 < y1) {
return Hep2Vector(dy,-dx);
}else{
return Hep2Vector(-dy,dx);
}
}
inline double Hep2Vector::phi() const {
return dx == 0.0 && dy == 0.0 ? 0.0 : std::atan2(dy,dx);
}
inline double Hep2Vector::angle(const Hep2Vector & q) const {
double ptot2 = mag2()*q.mag2();
return ptot2 <= 0.0 ? 0.0 : std::acos(dot(q)/std::sqrt(ptot2));
}
inline void Hep2Vector::setMag(double r1){
double ph = phi();
setX( r1 * std::cos(ph) );
setY( r1 * std::sin(ph) );
}
inline void Hep2Vector::setR(double r1){
setMag(r1);
}
inline void Hep2Vector::setPhi(double phi1){
double ma = mag();
setX( ma * std::cos(phi1) );
setY( ma * std::sin(phi1) );
}
inline void Hep2Vector::setPolar(double r1, double phi1){
setX( r1 * std::cos(phi1) );
setY( r1 * std::sin(phi1) );
}
inline Hep2Vector operator + (const Hep2Vector & a, const Hep2Vector & b) {
return Hep2Vector(a.x() + b.x(), a.y() + b.y());
}
inline Hep2Vector operator - (const Hep2Vector & a, const Hep2Vector & b) {
return Hep2Vector(a.x() - b.x(), a.y() - b.y());
}
inline Hep2Vector operator * (const Hep2Vector & p, double a) {
return Hep2Vector(a*p.x(), a*p.y());
}
inline Hep2Vector operator * (double a, const Hep2Vector & p) {
return Hep2Vector(a*p.x(), a*p.y());
}
inline double operator * (const Hep2Vector & a, const Hep2Vector & b) {
return a.dot(b);
}
inline double Hep2Vector::getTolerance () {
return tolerance;
}
} // namespace CLHEP
+329
View File
@@ -0,0 +1,329 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UVector3
//
// Class description:
//
// Bucket type for Vector type.
//
// 19.09.12 Marek Gayer
// Created from original implementation in CLHEP
// --------------------------------------------------------------------
#ifndef USOLIDS_UVector3
#define USOLIDS_UVector3
#include <cmath>
#include <iostream>
#include <fstream>
struct UVector3
{
public:
UVector3()
{
x = y = z = 0.0;
}
UVector3(double xval, double yval, double zval)
{
x = xval;
y = yval;
z = zval;
}
UVector3(double theta, double phi);
UVector3(const double coord[3])
{
x = coord[0];
y = coord[1];
z = coord[2];
}
inline UVector3& operator = (const UVector3& v);
inline UVector3& operator = (const double* vect);
// Assignments
inline bool operator == (const UVector3&) const;
inline bool operator != (const UVector3&) const;
// Comparisons.
inline UVector3 operator - () const;
// Unary minus.
inline UVector3& operator += (const UVector3&);
// Addition.
inline UVector3& operator -= (const UVector3&);
// Subtraction.
inline double& operator[](int index);
inline double operator[](int index) const;
inline UVector3& operator *= (double);
// Scaling with real numbers.
inline UVector3& operator /= (double);
// Dividing with real numbers.
inline double Dot(const UVector3&) const;
// Scalar product.
inline UVector3 Cross(const UVector3&) const;
// Cross product.
double Angle(const UVector3&) const;
// The angle w.r.t. another 3-vector.
UVector3 Unit() const;
// Unit vector parallel to this.
inline bool IsNull() const;
// Check if vector is null
inline void SetNull();
// Set all components to 0.
inline void Set(double xx, double yy, double zz);
// Assign values to components
inline void Set(double xx);
// Assign value to all components
double Normalize();
// Normalize to unit this vector
double Phi() const;
// The azimuth angle. returns phi from -pi to pi
double Theta() const;
// The polar angle.
inline double CosTheta() const;
// Cosine of the polar angle.
inline double Mag2() const;
// The magnitude squared (rho^2 in spherical coordinate system).
double Mag() const;
// The magnitude (rho in spherical coordinate system).
double Perp2() const;
// The transverse component (R^2 in cylindrical coordinate system).
double Perp() const;
// The transverse component (R in cylindrical coordinate system).
void RotateX(double);
// Rotates the vector around the x-axis.
void RotateY(double);
// Rotates the vector around the y-axis.
void RotateZ(double);
// Rotates the vector around the z-axis.
inline UVector3& MultiplyByComponents(const UVector3& p);
public:
double x;
double y;
double z;
};
UVector3 operator + (const UVector3&, const UVector3&);
// Addition of 3-vectors.
UVector3 operator - (const UVector3&, const UVector3&);
// Subtraction of 3-vectors.
double operator * (const UVector3&, const UVector3&);
// Scalar product of 3-vectors.
UVector3 operator * (const UVector3&, double a);
UVector3 operator / (const UVector3&, double a);
UVector3 operator * (double a, const UVector3&);
// Scaling of 3-vectors with a real number
//______________________________________________________________________________
inline UVector3& UVector3::MultiplyByComponents(const UVector3& p)
{
// Assignment of a UVector3
x *= p.x;
y *= p.y;
z *= p.z;
return *this;
}
//______________________________________________________________________________
inline UVector3& UVector3::operator = (const UVector3& p)
{
// Assignment of a UVector3
if (this == &p) { return *this; }
x = p.x;
y = p.y;
z = p.z;
return *this;
}
inline UVector3& UVector3::operator = (const double vect[3])
{
// Assignment of a C array
x = vect[0];
y = vect[1];
z = vect[2];
return *this;
}
inline bool UVector3::operator == (const UVector3& v) const
{
return (v.x == x && v.y == y && v.z == z) ? true : false;
}
inline bool UVector3::operator != (const UVector3& v) const
{
return (v.x != x || v.y != y || v.z != z) ? true : false;
}
inline UVector3& UVector3::operator += (const UVector3& p)
{
x += p.x;
y += p.y;
z += p.z;
return *this;
}
inline UVector3& UVector3::operator -= (const UVector3& p)
{
x -= p.x;
y -= p.y;
z -= p.z;
return *this;
}
inline UVector3 UVector3::operator - () const
{
return UVector3(-x, -y, -z);
}
inline UVector3& UVector3::operator *= (double a)
{
x *= a;
y *= a;
z *= a;
return *this;
}
inline UVector3& UVector3::operator /= (double a)
{
a = 1. / a;
x *= a;
y *= a;
z *= a;
return *this;
}
inline bool UVector3::IsNull() const
{
return ((std::abs(x) + std::abs(y) + std::abs(z)) == 0.0) ? true : false;
}
/*
inline void UVector3::SetNull() {
x = y = z = 0.0;
}
*/
inline void UVector3::Set(double xx, double yy, double zz)
{
x = xx;
y = yy;
z = zz;
}
inline void UVector3::Set(double xx)
{
x = y = z = xx;
}
inline double UVector3::Dot(const UVector3& p) const
{
return x * p.x + y * p.y + z * p.z;
}
inline UVector3 UVector3::Cross(const UVector3& p) const
{
return UVector3(y * p.z - p.y * z, z * p.x - p.z * x, x * p.y - p.x * y);
}
inline double UVector3::Mag2() const
{
return x * x + y * y + z * z;
}
inline double UVector3::Perp2() const
{
return x * x + y * y;
}
inline double UVector3::CosTheta() const
{
double ptot = Mag();
return ptot == 0.0 ? 1.0 : z / ptot;
}
inline double& UVector3::operator[](int index)
{
switch (index)
{
case 0:
return x;
case 1:
return y;
case 2:
return z;
default:
return x;
}
}
inline double UVector3::operator[](int index) const
{
// return operator()(index);
// TODO: test performance of both versions on Linux
// => first version is slightly faster
if (true)
{
double vec[3] = {x, y, z};
return vec[index];
}
switch (index)
{
case 0:
return x;
case 1:
return y;
case 2:
return z;
default:
return 0;
}
}
inline std::ostream& operator<< (std::ostream& os, const UVector3& v)
{
return os << "(" << v.x << "," << v.y << "," << v.z << ")";
}
#endif
+304
View File
@@ -0,0 +1,304 @@
//
// ********************************************************************
// * This Software is part of the AIDA Unified Solids Library package *
// * See: https://aidasoft.web.cern.ch/USolids *
// ********************************************************************
//
// $Id:$
//
// --------------------------------------------------------------------
//
// UVoxelizer
//
// Class description:
//
// Voxelizer used for UPolycone, UPolyhedra, UTessellatedSolid
// and UMultiUnion.
//
// 19.10.12 Marek Gayer
// Created from original implementation in ROOT
// --------------------------------------------------------------------
#ifndef UVoxelizer_HH
#define UVoxelizer_HH
#include <vector>
#include <string>
#include <map>
#include "UBits.hh"
#include "UBox.hh"
#include "VUFacet.hh"
#include "VUSolid.hh"
#include "UUtils.hh"
#include "UTransform3D.hh"
struct UVoxelBox
{
UVector3 hlen; // half length of the box
UVector3 pos; // position of the box
};
struct UVoxelInfo
{
int count;
int previous;
int next;
};
class UVoxelizer
{
// friend class UVoxelCandidatesIterator;
public:
// Binary search
template <typename T>
static inline int BinarySearch(const std::vector<T>& vec, T value)
{
// Binary search in an array of doubles. If match is found, function returns
// position of element. If no match found, function gives nearest
// element smaller than value.
typename std::vector<T>::const_iterator begin = vec.begin(), end = vec.end();
int res = std::upper_bound(begin, end, value) - begin - 1;
return res;
}
#ifdef USOLIDSONLY
void Voxelize(std::vector<VUSolid*>& solids, std::vector<UTransform3D>& transforms);
#endif // USOLIDSONLY
void Voxelize(std::vector<VUFacet*>& facets);
void DisplayVoxelLimits();
void DisplayBoundaries();
void DisplayListNodes();
UVoxelizer();
~UVoxelizer();
// Method displaying the nodes located in a voxel characterized by its three indexes:
void GetCandidatesVoxel(std::vector<int>& voxels);
// Method returning in a vector container the nodes located in a voxel characterized by its three indexes:
int GetCandidatesVoxelArray(const UVector3& point, std::vector<int>& list, UBits* crossed = NULL) const;
int GetCandidatesVoxelArray(const std::vector<int>& voxels, const UBits bitmasks[], std::vector<int>& list, UBits* crossed = NULL) const;
int GetCandidatesVoxelArray(const std::vector<int>& voxels, std::vector<int>& list, UBits* crossed = NULL)const;
// Method returning the pointer to the array containing the characteristics of each box:
inline const std::vector<UVoxelBox>& GetBoxes() const
{
return fBoxes;
}
inline const std::vector<double>& GetBoundary(int index) const
{
return fBoundaries[index];
}
bool UpdateCurrentVoxel(const UVector3& point, const UVector3& direction, std::vector<int>& curVoxel) const;
inline void GetVoxel(std::vector<int>& curVoxel, const UVector3& point) const
{
for (int i = 0; i <= 2; ++i)
{
const std::vector<double>& boundary = GetBoundary(i);
int n = BinarySearch(boundary, point[i]);
if (n == -1) n = 0;
else if (n == (int) boundary.size() - 1) n--;
curVoxel[i] = n;
}
}
inline int GetBitsPerSlice() const
{
return fNPerSlice * 8 * sizeof(unsigned int);
}
bool Contains(const UVector3& point) const;
double DistanceToNext(const UVector3& point, const UVector3& direction, std::vector<int>& curVoxel) const;
double DistanceToFirst(const UVector3& point, const UVector3& direction) const;
double SafetyToBoundingBox(const UVector3& point) const;
inline int GetVoxelsIndex(int x, int y, int z) const
{
if (x < 0 || y < 0 || z < 0) return -1;
int maxX = fBoundaries[0].size();
int maxY = fBoundaries[1].size();
int index = x + y * maxX + z * maxX * maxY;
return index;
}
inline int GetVoxelsIndex(const std::vector<int>& voxels) const
{
return GetVoxelsIndex(voxels[0], voxels[1], voxels[2]);
}
inline bool GetPointVoxel(const UVector3& p, std::vector<int>& voxels) const
{
for (int i = 0; i <= 2; ++i)
if (p[i] < *fBoundaries[i].begin() || p[i] > *fBoundaries[i].end()) return false;
for (int i = 0; i <= 2; ++i)
voxels[i] = BinarySearch(fBoundaries[i], p[i]);
return true;
}
inline int GetPointIndex(const UVector3& p) const
{
int maxX = fBoundaries[0].size();
int maxY = fBoundaries[1].size();
int x = BinarySearch(fBoundaries[0], p[0]);
int y = BinarySearch(fBoundaries[1], p[1]);
int z = BinarySearch(fBoundaries[2], p[2]);
int index = x + y * maxX + z * maxX * maxY;
return index;
}
inline const UBits& Empty() const
{
return fEmpty;
}
inline bool IsEmpty(int index) const
{
return fEmpty[index];
}
void SetMaxVoxels(int max);
void SetMaxVoxels(const UVector3& reductionRatio);
inline int GetMaxVoxels(UVector3& ratioOfReduction)
{
ratioOfReduction = fReductionRatio;
return fMaxVoxels;
}
int AllocatedMemory();
inline long long GetCountOfVoxels() const
{
return fCountOfVoxels;
}
inline long long CountVoxels(std::vector<double> boundaries[]) const
{
long long sx = boundaries[0].size() - 1;
long long sy = boundaries[1].size() - 1;
long long sz = boundaries[2].size() - 1;
return sx * sy * sz;
}
inline const std::vector<int>& GetCandidates(std::vector<int>& curVoxel) const
{
int voxelsIndex = GetVoxelsIndex(curVoxel);
if (voxelsIndex >= 0 && !fEmpty[voxelsIndex])
{
return fCandidates[voxelsIndex];
}
return fNoCandidates;
}
inline int GetVoxelBoxesSize() const
{
return fVoxelBoxes.size();
}
inline const UVoxelBox& GetVoxelBox(int i) const
{
return fVoxelBoxes[i];
}
inline const std::vector<int>& GetVoxelBoxCandidates(int i) const
{
return fVoxelBoxesCandidates[i];
}
inline int GetTotalCandidates() const
{
return fTotalCandidates;
}
static double MinDistanceToBox(const UVector3& aPoint, const UVector3& f);
static void SetDefaultVoxelsCount(int count);
static int GetDefaultVoxelsCount();
void BuildBoundingBox();
void BuildBoundingBox(UVector3& amin, UVector3& amax, double tolerance = 0);
static void FindComponentsFastest(unsigned int mask,
std::vector<int> &list, int i);
private:
static int fDefaultVoxelsCount;
std::vector<UVoxelBox> fVoxelBoxes;
std::vector<std::vector<int> > fVoxelBoxesCandidates;
mutable std::map<int, std::vector<int> > fCandidates;
const std::vector<int> fNoCandidates;
long long fCountOfVoxels;
void BuildEmpty();
std::string GetCandidatesAsString(const UBits& bits);
void CreateSortedBoundary(std::vector<double>& boundaryRaw, int axis);
void BuildBoundaries();
void BuildReduceVoxels(std::vector<double> fBoundaries[], UVector3 reductionRatio);
void BuildReduceVoxels2(std::vector<double> fBoundaries[], UVector3 reductionRatio);
#ifdef USOLIDSONLY
void BuildVoxelLimits(std::vector<VUSolid*>& solids, std::vector<UTransform3D>& transforms);
#endif // USOLIDSONLY
void BuildVoxelLimits(std::vector<VUFacet*>& facets);
void DisplayBoundaries(std::vector<double>& fBoundaries);
void BuildBitmasks(std::vector<double> fBoundaries[], UBits bitmasks[]);
void SetReductionRatio(int maxVoxels, UVector3& reductionRatio);
void CreateMiniVoxels(std::vector<double> fBoundaries[], UBits bitmasks[]);
int fNPerSlice;
std::vector<UVoxelBox> fBoxes; // Array of box limits on the 3 cartesian axis
std::vector<double> fBoundaries[3]; // Sorted and if need skimmed fBoundaries along X,Y,Z axis
std::vector<int> fCandidatesCounts[3];
int fTotalCandidates;
UBits fBitmasks[3];
UVector3 fBoundingBoxCenter;
UBox fBoundingBox;
UVector3 fBoundingBoxSize;
UVector3 fReductionRatio;
int fMaxVoxels;
double fTolerance;
UBits fEmpty;
};
#endif
+92
View File
@@ -0,0 +1,92 @@
//
// ********************************************************************
// * 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 and of QinetiQ Ltd, *
// * subject to DEFCON 705 IPR conditions. *
// * 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: UFacet.hh,v 1.8 2010-09-23 10:27:25 gcosmo Exp $
// GEANT4 tag $Name: not supported by cvs2svn $
//
// Author: Marek Gayer, started from original implementation by P R Truscott, 2004
//
//
// Class description:
//
// Base class defining the facets which are components of a
// UTessellatedSolid shape.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef UFacet_hh
#define UFacet_hh
#include <iostream>
#include <vector>
#include "UVector3.hh"
#include "UTypes.hh"
enum UFacetVertexType {UABSOLUTE, URELATIVE};
class UTessellatedSolid;
class VUFacet
{
public:
virtual ~VUFacet () {};
virtual int GetNumberOfVertices () const = 0;
virtual UVector3 GetVertex (int i) const = 0;
virtual void SetVertex (int i, const UVector3 &val) = 0;
virtual UGeometryType GetEntityType () const = 0;
virtual UVector3 GetSurfaceNormal () const = 0;
virtual bool IsDefined () const = 0;
virtual UVector3 GetCircumcentre () const = 0;
virtual double GetRadius () const = 0;
virtual VUFacet *GetClone () = 0;
virtual double Distance (const UVector3&, const double) = 0;
virtual double Distance (const UVector3&, const double, const bool) = 0;
virtual double Extent (const UVector3) = 0;
virtual bool Intersect (const UVector3&, const UVector3 &, const bool , double &, double &, UVector3 &) = 0;
virtual double GetArea() = 0;
virtual UVector3 GetPointOnFace() const = 0;
bool operator== (const VUFacet &right) const;
void ApplyTranslation (const UVector3 v);
std::ostream &StreamInfo(std::ostream &os) const;
bool IsInside(const UVector3 &p) const;
virtual int AllocatedMemory() = 0;
virtual void SetVertexIndex (const int i, const int j) = 0;
virtual int GetVertexIndex (const int i) const = 0;
virtual void SetVertices(std::vector<UVector3> *vertices) = 0;
protected:
static const double dirTolerance;
static const double kCarTolerance;
};
#endif
+156
View File
@@ -0,0 +1,156 @@
#ifndef USOLIDS_VUSolid
#define USOLIDS_VUSolid
////////////////////////////////////////////////////////////////////////////////
// "Universal" Solid Interface
// Authors: J. Apostolakis, G. Cosmo, M. Gayer, A. Gheata, A. Munnich, T. Nikitina (CERN)
//
// Created: 25 May 2011
//
////////////////////////////////////////////////////////////////////////////////
#include "UTypes.hh"
#include "UVector3.hh"
#include "UUtils.hh"
#define USOLIDS
#define USOLIDSONLY
class VUSolid
{
public:
enum EnumInside { eInside=0, eSurface=1, eOutside=2 };
// Use eInside < eSurface < eOutside: allows "max(,)" to combine Inside of surfaces
// Potentially replace eSurface with eInSurface, eOutSurface
enum EAxisType { eXaxis=0, eYaxis=1, eZaxis=2};
protected:
static double fgTolerance;
static double frTolerance;
static double faTolerance;
// =>10 degrees/wedge for complete tube
public:
VUSolid();
VUSolid(const std::string &name);
virtual ~VUSolid();
// Accessors and modifiers for Tolerance
inline double GetCarTolerance() const;
inline double GetRadTolerance() const;
inline double GetAngTolerance() const;
void SetCarTolerance(double eps);
void SetRadTolerance(double eps);
void SetAngTolerance(double eps);
// Navigation methods
virtual EnumInside Inside (const UVector3 &aPoint) const = 0;
//
// Evaluate if point is inside, outside or on the surface within the tolerance
virtual double SafetyFromInside ( const UVector3 &aPoint,
bool aAccurate=false) const = 0;
virtual double SafetyFromOutside( const UVector3 &aPoint,
bool aAccurate=false) const = 0;
//
// Estimates isotropic distance to the surface of the solid. This must
// be either accurate or an underestimate.
// Two modes: - default/fast mode, sacrificing accuracy for speed
// - "precise" mode, requests accurate value if available.
// For both modes, if at a large distance from solid ( > ? )
// it is expected that a simplified calculation will be made if available.
virtual double DistanceToIn( const UVector3 &aPoint,
const UVector3 &aDirection,
double aPstep = UUtils::kInfinity) const = 0;
virtual double DistanceToOut( const UVector3 &aPoint,
const UVector3 &aDirection,
UVector3 &aNormalVector,
bool &aConvex,
double aPstep = UUtils::kInfinity) const = 0;
//
// o return the exact distance (double) from a surface, given a direction
// o compute the normal on the surface, returned as argument, calculated
// within the method to verify if it is close to the surface or not
// o for DistanceToOut(), normal-vector and convexity flag could be optional (to decide).
// If normal cannot be computed (or shape is not convex), set 'convex' to 'false'.
// o for DistanceToIn(), the normal-vector could be added as optional
virtual bool Normal( const UVector3& aPoint, UVector3 &aNormal ) const = 0;
// Computes the normal on a surface and returns it as a unit vector
// In case a point is further than tolerance_normal from a surface, set validNormal=false
// Must return a valid vector. (even if the point is not on the surface.)
//
// On an edge or corner, provide an average normal of all facets within tolerance
// Decision: provide or not the Boolean 'validNormal' argument for returning validity
virtual void ExtentAxis(EAxisType aAxis, double &aMin, double &aMax) const;
virtual void Extent( UVector3 &aMin, UVector3 &aMax ) const = 0;
// Return the minimum and maximum extent along all Cartesian axes
// For both the Extent methods
// o Expect mostly to use a GetBBox()/CalculateBBox() method internally to compute the extent
// o Decision: whether to store the computed BBox (containing or representing 6 double values),
// and whether to compute it at construction time.
// Methods are *not* const to allow caching of the Bounding Box
virtual UGeometryType GetEntityType() const = 0;
// Provide identification of the class of an object.
// (required for persistency and STEP interface)
const std::string &GetName() const {return fName;}
void SetName(const std::string &aName) {fName = aName;}
// Auxiliary methods
virtual double Capacity() = 0 ; // like CubicVolume()
virtual double SurfaceArea() = 0 ;
// Expect the solids to cache the values of Capacity and Surface Area
// Sampling
virtual void SamplePointsInside(int /*aNpoints*/, UVector3 * /*aArray*/) const {}
virtual void SamplePointsOnSurface(int /*aNpoints*/, UVector3 * /*aArray*/) const {}
virtual void SamplePointsOnEdge(int /*aNpoints*/, UVector3 * /*aArray*/) const {}
// o generates points on the edges of a solid - primarily for testing purposes
// o for solids composed only of curved surfaces(like full spheres or toruses) or
// where an implementation is not available, it defaults to PointOnSurface.
// Visualisation
virtual void GetParametersList(int aNumber,double *aArray) const =0;
virtual VUSolid* Clone() const =0;
// o provide a new object which is a clone of the solid
// Visualization
static double Tolerance() {return fgTolerance;}
virtual std::ostream& StreamInfo( std::ostream& os ) const = 0;
virtual UVector3 GetPointOnSurface() const = 0;
double EstimateCubicVolume(int nStat, double epsilon) const;
// Calculate cubic volume based on Inside() method.
// Accuracy is limited by the second argument or the statistics
// expressed by the first argument.
double EstimateSurfaceArea(int nStat, double ell) const;
// Calculate surface area only based on Inside() method.
// Accuracy is limited by the second argument or the statistics
// expressed by the first argument.
protected:
virtual void ComputeBBox(UBBox *aBox, bool aStore = false) = 0;
// o Compute the bounding box for the solid. Called automatically and stored ?
// o Can throw an exception if the solid is invalid
private:
std::string fName; // Name of the solid
//UBBox *fBBox; // Bounding box
};
inline double VUSolid::GetCarTolerance() const { return fgTolerance;}
inline double VUSolid::GetRadTolerance() const { return frTolerance;}
inline double VUSolid::GetAngTolerance() const { return faTolerance;}
#endif