Import Geant4 10.1.0 source tree
This commit is contained in:
+222
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
@@ -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
@@ -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
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user