Import Geant4 10.3.0.beta source tree
This commit is contained in:
@@ -24,7 +24,7 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4ExtrudedSolid.cc 92024 2015-08-13 14:16:00Z gcosmo $
|
||||
// $Id: G4ExtrudedSolid.cc 95956 2016-03-03 10:59:53Z gcosmo $
|
||||
//
|
||||
//
|
||||
// --------------------------------------------------------------------
|
||||
@@ -33,6 +33,11 @@
|
||||
// G4ExtrudedSolid.cc
|
||||
//
|
||||
// Author: Ivana Hrivnacova, IPN Orsay
|
||||
//
|
||||
// CHANGE HISTORY
|
||||
// --------------
|
||||
// 02 March 2016, E Tcherniaev, added CheckPolygon() to remove
|
||||
// collinear and coincident points from polygon
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4ExtrudedSolid.hh"
|
||||
@@ -44,6 +49,7 @@
|
||||
#include <cmath>
|
||||
#include <iomanip>
|
||||
|
||||
#include "G4GeometryTolerance.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4VFacet.hh"
|
||||
@@ -53,8 +59,8 @@
|
||||
//_____________________________________________________________________________
|
||||
|
||||
G4ExtrudedSolid::G4ExtrudedSolid( const G4String& pName,
|
||||
std::vector<G4TwoVector> polygon,
|
||||
std::vector<ZSection> zsections)
|
||||
const std::vector<G4TwoVector>& polygon,
|
||||
const std::vector<ZSection>& zsections)
|
||||
: G4TessellatedSolid(pName),
|
||||
fNv(polygon.size()),
|
||||
fNz(zsections.size()),
|
||||
@@ -69,15 +75,15 @@ G4ExtrudedSolid::G4ExtrudedSolid( const G4String& pName,
|
||||
|
||||
// First check input parameters
|
||||
|
||||
if ( fNv < 3 )
|
||||
if (fNv < 3)
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Number of polygon vertices < 3 - " << pName;
|
||||
message << "Number of vertices in polygon < 3 - " << pName;
|
||||
G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids0002",
|
||||
FatalErrorInArgument, message);
|
||||
}
|
||||
|
||||
if ( fNz < 2 )
|
||||
if (fNz < 2)
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Number of z-sides < 2 - " << pName;
|
||||
@@ -95,7 +101,7 @@ G4ExtrudedSolid::G4ExtrudedSolid( const G4String& pName,
|
||||
G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids0002",
|
||||
FatalErrorInArgument, message);
|
||||
}
|
||||
if ( std::fabs( zsections[i+1].fZ - zsections[i].fZ ) < kCarTolerance * 0.5 )
|
||||
if ( std::fabs( zsections[i+1].fZ - zsections[i].fZ ) < kCarToleranceHalf )
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Z-sections with the same z position are not supported - "
|
||||
@@ -105,35 +111,53 @@ G4ExtrudedSolid::G4ExtrudedSolid( const G4String& pName,
|
||||
}
|
||||
}
|
||||
|
||||
// Copy polygon
|
||||
//
|
||||
fPolygon = polygon;
|
||||
|
||||
// Remove collinear and coincident vertices, if any
|
||||
//
|
||||
G4String removedVertices;
|
||||
CheckPolygon(removedVertices);
|
||||
if (fNv != G4int(polygon.size()))
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "The following vertices have been removed from the polygon in "
|
||||
<< pName << G4endl
|
||||
<< "as collinear or coincident with other vertices: "
|
||||
<< removedVertices;
|
||||
G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids1001",
|
||||
JustWarning, message);
|
||||
}
|
||||
if (fNv < 3)
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Number of vertices in polygon after removal < 3 - " << pName;
|
||||
G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids0002",
|
||||
FatalErrorInArgument, message);
|
||||
}
|
||||
|
||||
// Check if polygon vertices are defined clockwise
|
||||
// (the area is positive if polygon vertices are defined anti-clockwise)
|
||||
//
|
||||
G4double area = 0.;
|
||||
for ( G4int i=0; i<fNv; ++i ) {
|
||||
G4int j = i+1;
|
||||
if ( j == fNv ) j = 0;
|
||||
area += 0.5 * ( polygon[i].x()*polygon[j].y() - polygon[j].x()*polygon[i].y());
|
||||
for (G4int i=fNv-1, k=0; k<fNv; i=k++)
|
||||
{
|
||||
area += fPolygon[i].x()*fPolygon[k].y() - fPolygon[k].x()*fPolygon[i].y();
|
||||
}
|
||||
|
||||
// Copy polygon
|
||||
//
|
||||
if ( area < 0. ) {
|
||||
// Polygon vertices are defined clockwise, we just copy the polygon
|
||||
for ( G4int i=0; i<fNv; ++i ) { fPolygon.push_back(polygon[i]); }
|
||||
}
|
||||
else {
|
||||
|
||||
if (area > 0.)
|
||||
{
|
||||
// Polygon vertices are defined anti-clockwise, we revert them
|
||||
//G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids1001",
|
||||
// G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids1001",
|
||||
// JustWarning,
|
||||
// "Polygon vertices defined anti-clockwise, reverting polygon");
|
||||
for ( G4int i=0; i<fNv; ++i ) { fPolygon.push_back(polygon[fNv-i-1]); }
|
||||
// "Polygon vertices defined anti-clockwise, reverting polygon");
|
||||
std::reverse(fPolygon.begin(),fPolygon.end());
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Copy z-sections
|
||||
//
|
||||
for ( G4int i=0; i<fNz; ++i ) { fZSections.push_back(zsections[i]); }
|
||||
|
||||
fZSections = zsections;
|
||||
|
||||
G4bool result = MakeFacets();
|
||||
if (!result)
|
||||
@@ -144,7 +168,6 @@ G4ExtrudedSolid::G4ExtrudedSolid( const G4String& pName,
|
||||
FatalException, message);
|
||||
}
|
||||
fIsConvex = IsConvex();
|
||||
|
||||
|
||||
ComputeProjectionParameters();
|
||||
}
|
||||
@@ -152,10 +175,10 @@ G4ExtrudedSolid::G4ExtrudedSolid( const G4String& pName,
|
||||
//_____________________________________________________________________________
|
||||
|
||||
G4ExtrudedSolid::G4ExtrudedSolid( const G4String& pName,
|
||||
std::vector<G4TwoVector> polygon,
|
||||
const std::vector<G4TwoVector>& polygon,
|
||||
G4double dz,
|
||||
G4TwoVector off1, G4double scale1,
|
||||
G4TwoVector off2, G4double scale2 )
|
||||
const G4TwoVector& off1, G4double scale1,
|
||||
const G4TwoVector& off2, G4double scale2 )
|
||||
: G4TessellatedSolid(pName),
|
||||
fNv(polygon.size()),
|
||||
fNz(2),
|
||||
@@ -170,40 +193,56 @@ G4ExtrudedSolid::G4ExtrudedSolid( const G4String& pName,
|
||||
|
||||
// First check input parameters
|
||||
//
|
||||
if ( fNv < 3 )
|
||||
if (fNv < 3)
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Number of polygon vertices < 3 - " << pName;
|
||||
message << "Number of vertices in polygon < 3 - " << pName;
|
||||
G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids0002",
|
||||
FatalErrorInArgument, message);
|
||||
}
|
||||
|
||||
// Check if polygon vertices are defined clockwise
|
||||
// (the area is positive if polygon vertices are defined anti-clockwise)
|
||||
|
||||
G4double area = 0.;
|
||||
for ( G4int i=0; i<fNv; ++i )
|
||||
{
|
||||
G4int j = i+1;
|
||||
if ( j == fNv ) { j = 0; }
|
||||
area += 0.5 * ( polygon[i].x()*polygon[j].y()
|
||||
- polygon[j].x()*polygon[i].y());
|
||||
}
|
||||
|
||||
// Copy polygon
|
||||
//
|
||||
if ( area < 0. )
|
||||
{
|
||||
// Polygon vertices are defined clockwise, we just copy the polygon
|
||||
for ( G4int i=0; i<fNv; ++i ) { fPolygon.push_back(polygon[i]); }
|
||||
fPolygon = polygon;
|
||||
|
||||
// Remove collinear and coincident vertices, if any
|
||||
//
|
||||
G4String removedVertices;
|
||||
CheckPolygon(removedVertices);
|
||||
if (fNv != G4int(polygon.size()))
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "The following vertices have been removed from the polygon in "
|
||||
<< pName << G4endl
|
||||
<< "as collinear or coincident with other vertices: "
|
||||
<< removedVertices;
|
||||
G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids1001",
|
||||
JustWarning, message);
|
||||
}
|
||||
else
|
||||
if (fNv < 3)
|
||||
{
|
||||
std::ostringstream message;
|
||||
message << "Number of vertices in polygon after removal < 3 - " << pName;
|
||||
G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids0002",
|
||||
FatalErrorInArgument, message);
|
||||
}
|
||||
|
||||
// Check if polygon vertices are defined clockwise
|
||||
// (the area is positive if polygon vertices are defined anti-clockwise)
|
||||
//
|
||||
G4double area = 0.;
|
||||
for (G4int i=fNv-1, k=0; k<fNv; i=k++)
|
||||
{
|
||||
area += fPolygon[i].x()*fPolygon[k].y() - fPolygon[k].x()*fPolygon[i].y();
|
||||
}
|
||||
|
||||
if (area > 0.)
|
||||
{
|
||||
// Polygon vertices are defined anti-clockwise, we revert them
|
||||
//G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids1001",
|
||||
// G4Exception("G4ExtrudedSolid::G4ExtrudedSolid()", "GeomSolids1001",
|
||||
// JustWarning,
|
||||
// "Polygon vertices defined anti-clockwise, reverting polygon");
|
||||
for ( G4int i=0; i<fNv; ++i ) { fPolygon.push_back(polygon[fNv-i-1]); }
|
||||
// "Polygon vertices defined anti-clockwise, reverting polygon");
|
||||
std::reverse(fPolygon.begin(),fPolygon.end());
|
||||
}
|
||||
|
||||
// Copy z-sections
|
||||
@@ -279,6 +318,93 @@ G4ExtrudedSolid::~G4ExtrudedSolid()
|
||||
|
||||
//_____________________________________________________________________________
|
||||
|
||||
void G4ExtrudedSolid::CheckPolygon(G4String & removedVertices)
|
||||
{
|
||||
// Remove collinear and coincident vertices from 2D polygon
|
||||
|
||||
G4double delta = kCarTolerance; // dimension tolerance
|
||||
G4double removeIt = kInfinity; // special value to mark vertices for removal
|
||||
|
||||
// Main loop: check every three consecutive points, if the points
|
||||
// are collinear then mark middle point for removal
|
||||
//
|
||||
G4int icur, iprev=0, inext=0;
|
||||
for (G4int i=0; i<fNv; ++i)
|
||||
{
|
||||
icur = i;
|
||||
|
||||
// Find index of previous point
|
||||
for (G4int k=1; k<fNv+1; ++k)
|
||||
{
|
||||
iprev = icur - k;
|
||||
if (iprev < 0) iprev += fNv;
|
||||
if (fPolygon[iprev].x() != removeIt) break;
|
||||
}
|
||||
|
||||
// Find index of next point
|
||||
for (G4int k=1; k<fNv+1; ++k)
|
||||
{
|
||||
inext = icur + k;
|
||||
if (inext >= fNv) inext -= fNv;
|
||||
if (fPolygon[inext].x() != removeIt) break;
|
||||
}
|
||||
|
||||
if (iprev == inext) break; // degenerate polygon, stop
|
||||
|
||||
// Calculate parameters of the triangle (iprev->icur->inext).
|
||||
// If the triangle is too small or too narrow then
|
||||
// mark current point for removal
|
||||
G4TwoVector e1 = fPolygon[iprev] - fPolygon[icur];
|
||||
G4TwoVector e2 = fPolygon[inext] - fPolygon[icur];
|
||||
|
||||
G4double leng1 = e1.mag();
|
||||
G4double leng2 = e2.mag();
|
||||
G4double leng3 = (e2-e1).mag();
|
||||
|
||||
G4double lmax = std::max(std::max(leng1,leng2),leng3);
|
||||
G4double area = std::fabs(e1.x()*e2.y()-e1.y()*e2.x());
|
||||
|
||||
// Check length of edges, then check height of the triangle
|
||||
if (leng1 < delta || leng2 < delta || leng3 < delta)
|
||||
{
|
||||
fPolygon[icur].setX(removeIt);
|
||||
}
|
||||
else if (area/lmax < delta)
|
||||
{
|
||||
fPolygon[icur].setX(removeIt);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove marked points
|
||||
//
|
||||
std::ostringstream message;
|
||||
icur = 0;
|
||||
for (G4int i=0; i<fNv; ++i)
|
||||
{
|
||||
if (fPolygon[i].x() != removeIt)
|
||||
{
|
||||
fPolygon[icur] = fPolygon[i];
|
||||
icur++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (icur != i) message << ",";
|
||||
message << i;
|
||||
}
|
||||
}
|
||||
|
||||
// Resize fPolygon, if required
|
||||
//
|
||||
if (icur != fNv)
|
||||
{
|
||||
fPolygon.resize(icur);
|
||||
removedVertices = message.str();
|
||||
fNv = icur;
|
||||
}
|
||||
}
|
||||
|
||||
//_____________________________________________________________________________
|
||||
|
||||
void G4ExtrudedSolid::ComputeProjectionParameters()
|
||||
{
|
||||
// Compute parameters for point projections p(z)
|
||||
@@ -357,28 +483,29 @@ G4TwoVector G4ExtrudedSolid::ProjectPoint(const G4ThreeVector& point) const
|
||||
|
||||
//_____________________________________________________________________________
|
||||
|
||||
G4bool G4ExtrudedSolid::IsSameLine(G4TwoVector p,
|
||||
G4TwoVector l1, G4TwoVector l2) const
|
||||
G4bool G4ExtrudedSolid::IsSameLine(const G4TwoVector& p,
|
||||
const G4TwoVector& l1,
|
||||
const G4TwoVector& l2) const
|
||||
{
|
||||
// Return true if p is on the line through l1, l2
|
||||
|
||||
if ( l1.x() == l2.x() )
|
||||
{
|
||||
return std::fabs(p.x() - l1.x()) < kCarTolerance * 0.5;
|
||||
return std::fabs(p.x() - l1.x()) < kCarToleranceHalf;
|
||||
}
|
||||
G4double slope= ((l2.y() - l1.y())/(l2.x() - l1.x()));
|
||||
G4double slope= ((l2.y() - l1.y())/(l2.x() - l1.x()));
|
||||
G4double predy= l1.y() + slope *(p.x() - l1.x());
|
||||
G4double dy= p.y() - predy;
|
||||
|
||||
// Calculate perpendicular distance
|
||||
//
|
||||
// G4double perpD= std::fabs(dy) / std::sqrt( 1 + slope * slope );
|
||||
// G4bool simpleComp= (perpD<0.5*kCarTolerance);
|
||||
// G4bool simpleComp= (perpD<kCarToleranceHalf);
|
||||
|
||||
// Check perpendicular distance vs tolerance 'directly'
|
||||
//
|
||||
const G4double tol= 0.5 * kCarTolerance ;
|
||||
G4bool squareComp= (dy*dy < (1+slope*slope) * tol * tol);
|
||||
G4bool squareComp = (dy*dy < (1+slope*slope)
|
||||
* kCarToleranceHalf * kCarToleranceHalf);
|
||||
|
||||
// return simpleComp;
|
||||
return squareComp;
|
||||
@@ -386,16 +513,17 @@ G4bool G4ExtrudedSolid::IsSameLine(G4TwoVector p,
|
||||
|
||||
//_____________________________________________________________________________
|
||||
|
||||
G4bool G4ExtrudedSolid::IsSameLineSegment(G4TwoVector p,
|
||||
G4TwoVector l1, G4TwoVector l2) const
|
||||
G4bool G4ExtrudedSolid::IsSameLineSegment(const G4TwoVector& p,
|
||||
const G4TwoVector& l1,
|
||||
const G4TwoVector& l2) const
|
||||
{
|
||||
// Return true if p is on the line through l1, l2 and lies between
|
||||
// l1 and l2
|
||||
|
||||
if ( p.x() < std::min(l1.x(), l2.x()) - kCarTolerance * 0.5 ||
|
||||
p.x() > std::max(l1.x(), l2.x()) + kCarTolerance * 0.5 ||
|
||||
p.y() < std::min(l1.y(), l2.y()) - kCarTolerance * 0.5 ||
|
||||
p.y() > std::max(l1.y(), l2.y()) + kCarTolerance * 0.5 )
|
||||
if ( p.x() < std::min(l1.x(), l2.x()) - kCarToleranceHalf ||
|
||||
p.x() > std::max(l1.x(), l2.x()) + kCarToleranceHalf ||
|
||||
p.y() < std::min(l1.y(), l2.y()) - kCarToleranceHalf ||
|
||||
p.y() > std::max(l1.y(), l2.y()) + kCarToleranceHalf )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -405,21 +533,25 @@ G4bool G4ExtrudedSolid::IsSameLineSegment(G4TwoVector p,
|
||||
|
||||
//_____________________________________________________________________________
|
||||
|
||||
G4bool G4ExtrudedSolid::IsSameSide(G4TwoVector p1, G4TwoVector p2,
|
||||
G4TwoVector l1, G4TwoVector l2) const
|
||||
G4bool G4ExtrudedSolid::IsSameSide(const G4TwoVector& p1,
|
||||
const G4TwoVector& p2,
|
||||
const G4TwoVector& l1,
|
||||
const G4TwoVector& l2) const
|
||||
{
|
||||
// Return true if p1 and p2 are on the same side of the line through l1, l2
|
||||
|
||||
return ( (p1.x() - l1.x()) * (l2.y() - l1.y())
|
||||
- (l2.x() - l1.x()) * (p1.y() - l1.y()) )
|
||||
- (l2.x() - l1.x()) * (p1.y() - l1.y()) )
|
||||
* ( (p2.x() - l1.x()) * (l2.y() - l1.y())
|
||||
- (l2.x() - l1.x()) * (p2.y() - l1.y()) ) > 0;
|
||||
}
|
||||
|
||||
//_____________________________________________________________________________
|
||||
|
||||
G4bool G4ExtrudedSolid::IsPointInside(G4TwoVector a, G4TwoVector b,
|
||||
G4TwoVector c, G4TwoVector p) const
|
||||
G4bool G4ExtrudedSolid::IsPointInside(const G4TwoVector& a,
|
||||
const G4TwoVector& b,
|
||||
const G4TwoVector& c,
|
||||
const G4TwoVector& p) const
|
||||
{
|
||||
// Return true if p is inside of triangle abc or on its edges,
|
||||
// else returns false
|
||||
@@ -447,7 +579,9 @@ G4bool G4ExtrudedSolid::IsPointInside(G4TwoVector a, G4TwoVector b,
|
||||
//_____________________________________________________________________________
|
||||
|
||||
G4double
|
||||
G4ExtrudedSolid::GetAngle(G4TwoVector po, G4TwoVector pa, G4TwoVector pb) const
|
||||
G4ExtrudedSolid::GetAngle(const G4TwoVector& po,
|
||||
const G4TwoVector& pa,
|
||||
const G4TwoVector& pb) const
|
||||
{
|
||||
// Return the angle of the vertex in po
|
||||
|
||||
@@ -537,6 +671,9 @@ G4bool G4ExtrudedSolid::AddGeneralPolygonFacets()
|
||||
|
||||
typedef std::pair < G4TwoVector, G4int > Vertex;
|
||||
|
||||
static const G4double kAngTolerance =
|
||||
G4GeometryTolerance::GetInstance()->GetAngularTolerance();
|
||||
|
||||
// Fill one more vector
|
||||
//
|
||||
std::vector< Vertex > verticesToBeDone;
|
||||
@@ -566,7 +703,7 @@ G4bool G4ExtrudedSolid::AddGeneralPolygonFacets()
|
||||
//G4cout << "angle " << angle << G4endl;
|
||||
|
||||
G4int counter = 0;
|
||||
while ( angle >= pi ) // Loop checking, 13.08.2015, G.Cosmo
|
||||
while ( angle >= (pi-kAngTolerance) ) // Loop checking, 13.08.2015, G.Cosmo
|
||||
{
|
||||
// G4cout << "Skipping concave vertex " << c2->second << G4endl;
|
||||
|
||||
@@ -773,12 +910,12 @@ EInside G4ExtrudedSolid::Inside (const G4ThreeVector &p) const
|
||||
|
||||
// Check first if outside extent
|
||||
//
|
||||
if ( p.x() < GetMinXExtent() - kCarTolerance * 0.5 ||
|
||||
p.x() > GetMaxXExtent() + kCarTolerance * 0.5 ||
|
||||
p.y() < GetMinYExtent() - kCarTolerance * 0.5 ||
|
||||
p.y() > GetMaxYExtent() + kCarTolerance * 0.5 ||
|
||||
p.z() < GetMinZExtent() - kCarTolerance * 0.5 ||
|
||||
p.z() > GetMaxZExtent() + kCarTolerance * 0.5 )
|
||||
if ( p.x() < GetMinXExtent() - kCarToleranceHalf ||
|
||||
p.x() > GetMaxXExtent() + kCarToleranceHalf ||
|
||||
p.y() < GetMinYExtent() - kCarToleranceHalf ||
|
||||
p.y() > GetMaxYExtent() + kCarToleranceHalf ||
|
||||
p.z() < GetMinZExtent() - kCarToleranceHalf ||
|
||||
p.z() > GetMaxZExtent() + kCarToleranceHalf )
|
||||
{
|
||||
// G4cout << "G4ExtrudedSolid::Outside extent: " << p << G4endl;
|
||||
return kOutside;
|
||||
@@ -817,8 +954,8 @@ EInside G4ExtrudedSolid::Inside (const G4ThreeVector &p) const
|
||||
{
|
||||
// Check if on surface of z sides
|
||||
//
|
||||
if ( std::fabs( p.z() - fZSections[0].fZ ) < kCarTolerance * 0.5 ||
|
||||
std::fabs( p.z() - fZSections[fNz-1].fZ ) < kCarTolerance * 0.5 )
|
||||
if ( std::fabs( p.z() - fZSections[0].fZ ) < kCarToleranceHalf ||
|
||||
std::fabs( p.z() - fZSections[fNz-1].fZ ) < kCarToleranceHalf )
|
||||
{
|
||||
// G4cout << "G4ExtrudedSolid::Inside return Surface (on z side)"
|
||||
// << G4endl;
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4GenericTrap.cc 83851 2014-09-19 10:12:12Z gcosmo $
|
||||
// $Id: G4GenericTrap.cc 95592 2016-02-16 10:48:01Z gcosmo $
|
||||
//
|
||||
//
|
||||
// --------------------------------------------------------------------
|
||||
@@ -36,9 +36,12 @@
|
||||
// Tatiana Nikitina, CERN; Ivana Hrivnacova, IPN Orsay
|
||||
// Adapted from Root Arb8 implementation by Andrei Gheata, CERN
|
||||
//
|
||||
// History :
|
||||
// 04 August 2011 T.Nikitina Add SetReferences() and InvertFacets()
|
||||
// to CreatePolyhedron() for Visualisation of Boolean
|
||||
// History:
|
||||
// 04.08.2011 T.Nikitina - Added SetReferences() and InvertFacets()
|
||||
// to CreatePolyhedron() for Visualisation of Boolean
|
||||
//
|
||||
// 03.02.2016 E.Tcherniaev - Revised GetSurfaceArea() and GetCubicVolume(),
|
||||
// rewritten GetFaceSurfaceArea(), added GetFaceCubicVolume()
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4GenericTrap.hh"
|
||||
@@ -505,8 +508,10 @@ G4ThreeVector G4GenericTrap::SurfaceNormal( const G4ThreeVector& p ) const
|
||||
//
|
||||
if ( noSurfaces == 0 )
|
||||
{
|
||||
#ifdef G4SPECSDEBUG
|
||||
G4Exception("G4GenericTrap::SurfaceNormal(p)", "GeomSolids1002",
|
||||
JustWarning, "Point p is not on surface !?" );
|
||||
#endif
|
||||
sumnorm=apprnorm;
|
||||
// Add Approximative Surface Normal Calculation?
|
||||
}
|
||||
@@ -549,7 +554,9 @@ G4ThreeVector G4GenericTrap::NormalToPlane( const G4ThreeVector& p,
|
||||
|
||||
if (std::fabs(distz)<halfCarTolerance)
|
||||
{
|
||||
p1=G4ThreeVector(fVertices[i].x(),fVertices[i].y(),-fDz);distz=-1;}
|
||||
p1=G4ThreeVector(fVertices[i].x(),fVertices[i].y(),-fDz);
|
||||
distz=-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
p1=G4ThreeVector(fVertices[i+4].x(),fVertices[i+4].y(),fDz);
|
||||
@@ -1218,11 +1225,8 @@ G4bool G4GenericTrap::CalculateExtent(const EAxis pAxis,
|
||||
|
||||
// Computes bounding vectors for a shape
|
||||
//
|
||||
G4double Dx,Dy;
|
||||
G4ThreeVector minVec = GetMinimumBBox();
|
||||
G4ThreeVector maxVec = GetMaximumBBox();
|
||||
Dx = 0.5*(maxVec.x()- minVec.x());
|
||||
Dy = 0.5*(maxVec.y()- minVec.y());
|
||||
|
||||
if (!pTransform.IsRotated())
|
||||
{
|
||||
@@ -1235,8 +1239,8 @@ G4bool G4GenericTrap::CalculateExtent(const EAxis pAxis,
|
||||
G4double zoffset,zMin,zMax;
|
||||
|
||||
xoffset=pTransform.NetTranslation().x();
|
||||
xMin=xoffset-Dx;
|
||||
xMax=xoffset+Dx;
|
||||
xMin=xoffset+minVec.x();
|
||||
xMax=xoffset+maxVec.x();
|
||||
if (pVoxelLimit.IsXLimited())
|
||||
{
|
||||
if ( (xMin>pVoxelLimit.GetMaxXExtent()+kCarTolerance)
|
||||
@@ -1258,8 +1262,8 @@ G4bool G4GenericTrap::CalculateExtent(const EAxis pAxis,
|
||||
}
|
||||
|
||||
yoffset=pTransform.NetTranslation().y();
|
||||
yMin=yoffset-Dy;
|
||||
yMax=yoffset+Dy;
|
||||
yMin=yoffset+minVec.y();
|
||||
yMax=yoffset+maxVec.y();
|
||||
if (pVoxelLimit.IsYLimited())
|
||||
{
|
||||
if ( (yMin>pVoxelLimit.GetMaxYExtent()+kCarTolerance)
|
||||
@@ -1281,8 +1285,8 @@ G4bool G4GenericTrap::CalculateExtent(const EAxis pAxis,
|
||||
}
|
||||
|
||||
zoffset=pTransform.NetTranslation().z();
|
||||
zMin=zoffset-fDz;
|
||||
zMax=zoffset+fDz;
|
||||
zMin=zoffset+minVec.z();
|
||||
zMax=zoffset+maxVec.z();
|
||||
if (pVoxelLimit.IsZLimited())
|
||||
{
|
||||
if ( (zMin>pVoxelLimit.GetMaxZExtent()+kCarTolerance)
|
||||
@@ -1548,58 +1552,62 @@ G4ThreeVector G4GenericTrap::GetPointOnSurface() const
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
G4double G4GenericTrap::GetCubicVolume()
|
||||
G4double G4GenericTrap::GetSurfaceArea()
|
||||
{
|
||||
if(fCubicVolume != 0.) {;}
|
||||
else { fCubicVolume = G4VSolid::GetCubicVolume(); }
|
||||
return fCubicVolume;
|
||||
if (fSurfaceArea == 0.0) {
|
||||
if(fIsTwisted) {
|
||||
fSurfaceArea = G4VSolid::GetSurfaceArea();
|
||||
} else {
|
||||
// Set vertices
|
||||
G4ThreeVector vertix0(fVertices[0].x(),fVertices[0].y(),-fDz);
|
||||
G4ThreeVector vertix1(fVertices[1].x(),fVertices[1].y(),-fDz);
|
||||
G4ThreeVector vertix2(fVertices[2].x(),fVertices[2].y(),-fDz);
|
||||
G4ThreeVector vertix3(fVertices[3].x(),fVertices[3].y(),-fDz);
|
||||
G4ThreeVector vertix4(fVertices[4].x(),fVertices[4].y(), fDz);
|
||||
G4ThreeVector vertix5(fVertices[5].x(),fVertices[5].y(), fDz);
|
||||
G4ThreeVector vertix6(fVertices[6].x(),fVertices[6].y(), fDz);
|
||||
G4ThreeVector vertix7(fVertices[7].x(),fVertices[7].y(), fDz);
|
||||
|
||||
// Find Surface Area
|
||||
fSurfaceArea = GetFaceSurfaceArea(vertix0,vertix1,vertix2,vertix3) // -fDz plane
|
||||
+ GetFaceSurfaceArea(vertix1,vertix0,vertix4,vertix5) // Lat plane
|
||||
+ GetFaceSurfaceArea(vertix2,vertix1,vertix5,vertix6) // Lat plane
|
||||
+ GetFaceSurfaceArea(vertix3,vertix2,vertix6,vertix7) // Lat plane
|
||||
+ GetFaceSurfaceArea(vertix0,vertix3,vertix7,vertix4) // Lat plane
|
||||
+ GetFaceSurfaceArea(vertix7,vertix6,vertix5,vertix4); // +fDz plane
|
||||
}
|
||||
}
|
||||
return fSurfaceArea;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
G4double G4GenericTrap::GetSurfaceArea()
|
||||
G4double G4GenericTrap::GetCubicVolume()
|
||||
{
|
||||
if(fSurfaceArea != 0.) {;}
|
||||
else
|
||||
{
|
||||
std::vector<G4ThreeVector> vertices;
|
||||
for (G4int i=0; i<4;i++)
|
||||
{
|
||||
vertices.push_back(G4ThreeVector(fVertices[i].x(),fVertices[i].y(),-fDz));
|
||||
}
|
||||
for (G4int i=4; i<8;i++)
|
||||
{
|
||||
vertices.push_back(G4ThreeVector(fVertices[i].x(),fVertices[i].y(),fDz));
|
||||
}
|
||||
if (fCubicVolume == 0.0) {
|
||||
if(fIsTwisted) {
|
||||
fCubicVolume = G4VSolid::GetCubicVolume();
|
||||
} else {
|
||||
// Set vertices
|
||||
G4ThreeVector vertix0(fVertices[0].x(),fVertices[0].y(),-fDz);
|
||||
G4ThreeVector vertix1(fVertices[1].x(),fVertices[1].y(),-fDz);
|
||||
G4ThreeVector vertix2(fVertices[2].x(),fVertices[2].y(),-fDz);
|
||||
G4ThreeVector vertix3(fVertices[3].x(),fVertices[3].y(),-fDz);
|
||||
G4ThreeVector vertix4(fVertices[4].x(),fVertices[4].y(), fDz);
|
||||
G4ThreeVector vertix5(fVertices[5].x(),fVertices[5].y(), fDz);
|
||||
G4ThreeVector vertix6(fVertices[6].x(),fVertices[6].y(), fDz);
|
||||
G4ThreeVector vertix7(fVertices[7].x(),fVertices[7].y(), fDz);
|
||||
|
||||
// Surface Area of Planes(only estimation for twisted)
|
||||
//
|
||||
G4double fSurface0=GetFaceSurfaceArea(vertices[0],vertices[1],
|
||||
vertices[2],vertices[3]);//-fDz plane
|
||||
G4double fSurface1=GetFaceSurfaceArea(vertices[0],vertices[1],
|
||||
vertices[5],vertices[4]);// Lat plane
|
||||
G4double fSurface2=GetFaceSurfaceArea(vertices[3],vertices[0],
|
||||
vertices[4],vertices[7]);// Lat plane
|
||||
G4double fSurface3=GetFaceSurfaceArea(vertices[2],vertices[3],
|
||||
vertices[7],vertices[6]);// Lat plane
|
||||
G4double fSurface4=GetFaceSurfaceArea(vertices[2],vertices[1],
|
||||
vertices[5],vertices[6]);// Lat plane
|
||||
G4double fSurface5=GetFaceSurfaceArea(vertices[4],vertices[5],
|
||||
vertices[6],vertices[7]);// fDz plane
|
||||
|
||||
// Total Surface Area
|
||||
//
|
||||
if(!fIsTwisted)
|
||||
{
|
||||
fSurfaceArea = fSurface0+fSurface1+fSurface2
|
||||
+ fSurface3+fSurface4+fSurface5;
|
||||
}
|
||||
else
|
||||
{
|
||||
fSurfaceArea = G4VSolid::GetSurfaceArea();
|
||||
// Find Cubic Volume
|
||||
fCubicVolume = GetFaceCubicVolume(vertix0,vertix1,vertix2,vertix3) // -fDz plane
|
||||
+ GetFaceCubicVolume(vertix1,vertix0,vertix4,vertix5) // Lat plane
|
||||
+ GetFaceCubicVolume(vertix2,vertix1,vertix5,vertix6) // Lat plane
|
||||
+ GetFaceCubicVolume(vertix3,vertix2,vertix6,vertix7) // Lat plane
|
||||
+ GetFaceCubicVolume(vertix0,vertix3,vertix7,vertix4) // Lat plane
|
||||
+ GetFaceCubicVolume(vertix7,vertix6,vertix5,vertix4); // +fDz plane
|
||||
}
|
||||
}
|
||||
return fSurfaceArea;
|
||||
return fCubicVolume;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
@@ -1609,23 +1617,20 @@ G4double G4GenericTrap::GetFaceSurfaceArea(const G4ThreeVector& p0,
|
||||
const G4ThreeVector& p2,
|
||||
const G4ThreeVector& p3) const
|
||||
{
|
||||
// Auxiliary method for Get Surface Area of Face
|
||||
|
||||
G4double aOne, aTwo;
|
||||
G4ThreeVector t, u, v, w, Area, normal;
|
||||
// Returns area of the facet
|
||||
return (((p2-p0).cross(p3-p1)).mag()) / 2.;
|
||||
}
|
||||
|
||||
t = p2 - p1;
|
||||
u = p0 - p1;
|
||||
v = p2 - p3;
|
||||
w = p0 - p3;
|
||||
|
||||
Area = w.cross(v);
|
||||
aOne = 0.5*Area.mag();
|
||||
|
||||
Area = t.cross(u);
|
||||
aTwo = 0.5*Area.mag();
|
||||
|
||||
return aOne + aTwo;
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
G4double G4GenericTrap::GetFaceCubicVolume(const G4ThreeVector& p0,
|
||||
const G4ThreeVector& p1,
|
||||
const G4ThreeVector& p2,
|
||||
const G4ThreeVector& p3) const
|
||||
{
|
||||
// Returns contribution of the facet to the volume of the solid.
|
||||
// Orientation of the facet is important, normal should point to outside.
|
||||
return (((p2-p0).cross(p3-p1)).dot(p0)) / 6.;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
@@ -2150,13 +2155,11 @@ G4VisExtent G4GenericTrap::GetExtent() const
|
||||
}
|
||||
#endif
|
||||
|
||||
G4double Dx,Dy;
|
||||
G4ThreeVector minVec = GetMinimumBBox();
|
||||
G4ThreeVector maxVec = GetMaximumBBox();
|
||||
Dx = 0.5*(maxVec.x()- minVec.x());
|
||||
Dy = 0.5*(maxVec.y()- minVec.y());
|
||||
|
||||
return G4VisExtent (-Dx, Dx, -Dy, Dy, -fDz, fDz);
|
||||
return G4VisExtent (minVec.x(), maxVec.x(),
|
||||
minVec.y(), maxVec.y(),
|
||||
minVec.z(), maxVec.z());
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4IntersectingCone.cc 72937 2013-08-14 13:20:38Z gcosmo $
|
||||
// $Id: G4IntersectingCone.cc 95997 2016-03-07 13:16:25Z gcosmo $
|
||||
//
|
||||
//
|
||||
// --------------------------------------------------------------------
|
||||
@@ -215,6 +215,8 @@ G4int G4IntersectingCone::LineHitsCone1( const G4ThreeVector &p,
|
||||
const G4ThreeVector &v,
|
||||
G4double *s1, G4double *s2 )
|
||||
{
|
||||
static const G4double EPS = DBL_EPSILON; // Precision constant,
|
||||
// originally it was 1E-6
|
||||
G4double x0 = p.x(), y0 = p.y(), z0 = p.z();
|
||||
G4double tx = v.x(), ty = v.y(), tz = v.z();
|
||||
|
||||
@@ -224,9 +226,9 @@ G4int G4IntersectingCone::LineHitsCone1( const G4ThreeVector &p,
|
||||
|
||||
G4double radical = b*b - 4*a*c;
|
||||
|
||||
if (radical < -1E-6*std::fabs(b)) { return 0; } // No solution
|
||||
if (radical < -EPS*std::fabs(b)) { return 0; } // No solution
|
||||
|
||||
if (radical < 1E-6*std::fabs(b))
|
||||
if (radical < EPS*std::fabs(b))
|
||||
{
|
||||
//
|
||||
// The radical is roughly zero: check for special, very rare, cases
|
||||
@@ -234,7 +236,7 @@ G4int G4IntersectingCone::LineHitsCone1( const G4ThreeVector &p,
|
||||
if (std::fabs(a) > 1/kInfinity)
|
||||
{
|
||||
if(B==0.) { return 0; }
|
||||
if ( std::fabs(x0*ty - y0*tx) < std::fabs(1E-6/B) )
|
||||
if ( std::fabs(x0*ty - y0*tx) < std::fabs(EPS/B) )
|
||||
{
|
||||
*s1 = -0.5*b/a;
|
||||
return 1;
|
||||
@@ -305,10 +307,11 @@ G4int G4IntersectingCone::LineHitsCone2( const G4ThreeVector &p,
|
||||
const G4ThreeVector &v,
|
||||
G4double *s1, G4double *s2 )
|
||||
{
|
||||
static const G4double EPS = DBL_EPSILON; // Precision constant,
|
||||
// originally it was 1E-6
|
||||
G4double x0 = p.x(), y0 = p.y(), z0 = p.z();
|
||||
G4double tx = v.x(), ty = v.y(), tz = v.z();
|
||||
|
||||
|
||||
// Special case which might not be so rare: B = 0 (precisely)
|
||||
//
|
||||
if (B==0)
|
||||
@@ -327,16 +330,16 @@ G4int G4IntersectingCone::LineHitsCone2( const G4ThreeVector &p,
|
||||
|
||||
G4double radical = b*b - 4*a*c;
|
||||
|
||||
if (radical < -1E-6*std::fabs(b)) { return 0; } // No solution
|
||||
if (radical < -EPS*std::fabs(b)) { return 0; } // No solution
|
||||
|
||||
if (radical < 1E-6*std::fabs(b))
|
||||
if (radical < EPS*std::fabs(b))
|
||||
{
|
||||
//
|
||||
// The radical is roughly zero: check for special, very rare, cases
|
||||
//
|
||||
if (std::fabs(a) > 1/kInfinity)
|
||||
{
|
||||
if ( std::fabs(x0*ty - y0*tx) < std::fabs(1E-6/B) )
|
||||
if ( std::fabs(x0*ty - y0*tx) < std::fabs(EPS/B) )
|
||||
{
|
||||
*s1 = -0.5*b/a;
|
||||
return 1;
|
||||
|
||||
@@ -25,19 +25,25 @@
|
||||
// ********************************************************************
|
||||
//
|
||||
//
|
||||
// $Id: G4QuadrangularFacet.cc 66819 2013-01-12 16:20:10Z gcosmo $
|
||||
// $Id: G4QuadrangularFacet.cc 95945 2016-03-03 09:54:38Z gcosmo $
|
||||
//
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
// CHANGE HISTORY
|
||||
// --------------
|
||||
//
|
||||
// 31 October 2004, P R Truscott, QinetiQ Ltd, UK - Created.
|
||||
// 12 October 2012, M Gayer, CERN
|
||||
// 31 October 2004 P R Truscott, QinetiQ Ltd, UK - Created.
|
||||
//
|
||||
// 12 October 2012 M Gayer, CERN
|
||||
// New implementation reducing memory requirements by 50%,
|
||||
// and considerable CPU speedup together with the new
|
||||
// implementation of G4TessellatedSolid.
|
||||
//
|
||||
// 29 February 2016 E Tcherniaev, CERN
|
||||
// Added exhaustive tests to catch various problems with a
|
||||
// quadrangular facet: collinear vertices, non planar surface,
|
||||
// degenerate, concave or self intersecting quadrilateral.
|
||||
//
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
#include "G4QuadrangularFacet.hh"
|
||||
@@ -57,8 +63,12 @@ G4QuadrangularFacet::G4QuadrangularFacet (const G4ThreeVector &vt0,
|
||||
const G4ThreeVector &vt3,
|
||||
G4FacetVertexType vertexType)
|
||||
{
|
||||
G4ThreeVector e1, e2, e3;
|
||||
G4double delta = 1.0 * kCarTolerance; // dimension tolerance
|
||||
G4double epsilon = 0.01 * kCarTolerance; // planarity tolerance
|
||||
|
||||
fRadius = 0.0;
|
||||
|
||||
G4ThreeVector e1, e2, e3;
|
||||
SetVertex(0, vt0);
|
||||
if (vertexType == ABSOLUTE)
|
||||
{
|
||||
@@ -80,59 +90,128 @@ G4QuadrangularFacet::G4QuadrangularFacet (const G4ThreeVector &vt0,
|
||||
e2 = vt2;
|
||||
e3 = vt3;
|
||||
}
|
||||
G4double length1 = e1.mag();
|
||||
G4double length2 = (GetVertex(2)-GetVertex(1)).mag();
|
||||
G4double length3 = (GetVertex(3)-GetVertex(2)).mag();
|
||||
G4double length4 = e3.mag();
|
||||
|
||||
G4ThreeVector normal1 = e1.cross(e2).unit();
|
||||
G4ThreeVector normal2 = e2.cross(e3).unit();
|
||||
// Check length of sides and diagonals
|
||||
//
|
||||
G4double leng1 = e1.mag();
|
||||
G4double leng2 = (e2-e1).mag();
|
||||
G4double leng3 = (e3-e2).mag();
|
||||
G4double leng4 = e3.mag();
|
||||
|
||||
bool isDefined = (length1 > kCarTolerance && length2 > kCarTolerance &&
|
||||
length3 > kCarTolerance && length4 > kCarTolerance &&
|
||||
normal1.dot(normal2) >= 0.9999999999);
|
||||
G4double diag1 = e2.mag();
|
||||
G4double diag2 = (e3-e1).mag();
|
||||
|
||||
if (isDefined)
|
||||
{
|
||||
fFacet1 = G4TriangularFacet (GetVertex(0),GetVertex(1),
|
||||
GetVertex(2),ABSOLUTE);
|
||||
fFacet2 = G4TriangularFacet (GetVertex(0),GetVertex(2),
|
||||
GetVertex(3),ABSOLUTE);
|
||||
|
||||
G4TriangularFacet facet3 (GetVertex(0),GetVertex(1),GetVertex(3),ABSOLUTE);
|
||||
G4TriangularFacet facet4 (GetVertex(1),GetVertex(2),GetVertex(3),ABSOLUTE);
|
||||
|
||||
G4ThreeVector normal12 = fFacet1.GetSurfaceNormal()
|
||||
+ fFacet2.GetSurfaceNormal();
|
||||
G4ThreeVector normal34 = facet3.GetSurfaceNormal()
|
||||
+ facet4.GetSurfaceNormal();
|
||||
G4ThreeVector normal = 0.25 * (normal12 + normal34);
|
||||
|
||||
fFacet1.SetSurfaceNormal (normal);
|
||||
fFacet2.SetSurfaceNormal (normal);
|
||||
|
||||
G4ThreeVector vtmp = 0.5 * (e1 + e2);
|
||||
fCircumcentre = GetVertex(0) + vtmp;
|
||||
G4double radiusSqr = vtmp.mag2();
|
||||
fRadius = std::sqrt(radiusSqr);
|
||||
}
|
||||
else
|
||||
if (leng1 <= delta || leng2 <= delta || leng3 <= delta || leng4 <= delta ||
|
||||
diag1 <= delta || diag2 <= delta)
|
||||
{
|
||||
ostringstream message;
|
||||
message << "Sides/diagonals of facet are too small." << G4endl
|
||||
<< "P0 = " << GetVertex(0) << G4endl
|
||||
<< "P1 = " << GetVertex(1) << G4endl
|
||||
<< "P2 = " << GetVertex(2) << G4endl
|
||||
<< "P3 = " << GetVertex(3) << G4endl
|
||||
<< "Side1 length (P0->P1) = " << leng1 << G4endl
|
||||
<< "Side2 length (P1->P2) = " << leng2 << G4endl
|
||||
<< "Side3 length (P2->P3) = " << leng3 << G4endl
|
||||
<< "Side4 length (P3->P0) = " << leng4 << G4endl
|
||||
<< "Diagonal1 length (P0->P2) = " << diag1 << G4endl
|
||||
<< "Diagonal2 length (P1->P3) = " << diag2;
|
||||
G4Exception("G4QuadrangularFacet::G4QuadrangularFacet()",
|
||||
"GeomSolids0002", JustWarning,
|
||||
"Length of sides of facet are too small or sides not planar.");
|
||||
G4cout << G4endl;
|
||||
G4cout << "P0 = " << GetVertex(0) << G4endl;
|
||||
G4cout << "P1 = " << GetVertex(1) << G4endl;
|
||||
G4cout << "P2 = " << GetVertex(2) << G4endl;
|
||||
G4cout << "P3 = " << GetVertex(3) << G4endl;
|
||||
G4cout << "Side lengths = P0->P1" << length1 << G4endl;
|
||||
G4cout << "Side lengths = P1->P2" << length2 << G4endl;
|
||||
G4cout << "Side lengths = P2->P3" << length3 << G4endl;
|
||||
G4cout << "Side lengths = P3->P0" << length4 << G4endl;
|
||||
G4cout << G4endl;
|
||||
fRadius = 0.0;
|
||||
"GeomSolids1001", JustWarning, message);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check that vertices are not collinear
|
||||
//
|
||||
G4double s1 = (e1.cross(e2)).mag()*0.5;
|
||||
G4double s2 = ((e2-e1).cross(e3-e2)).mag()*0.5;
|
||||
G4double s3 = (e2.cross(e3)).mag()*0.5;
|
||||
G4double s4 = (e1.cross(e3)).mag()*0.5;
|
||||
|
||||
G4double h1 = 2.*s1 / std::max(std::max(leng1,leng2),diag1);
|
||||
G4double h2 = 2.*s2 / std::max(std::max(leng2,leng3),diag2);
|
||||
G4double h3 = 2.*s3 / std::max(std::max(leng3,leng4),diag1);
|
||||
G4double h4 = 2.*s4 / std::max(std::max(leng4,leng1),diag2);
|
||||
|
||||
if (h1 <= delta || h2 <= delta || h3 <= delta || h4 <= delta )
|
||||
{
|
||||
ostringstream message;
|
||||
message << "Facet has three or more collinear vertices." << G4endl
|
||||
<< "P0 = " << GetVertex(0) << G4endl
|
||||
<< "P1 = " << GetVertex(1) << G4endl
|
||||
<< "P2 = " << GetVertex(2) << G4endl
|
||||
<< "P3 = " << GetVertex(3) << G4endl
|
||||
<< "Height in P0-P1-P2 = " << h1 << G4endl
|
||||
<< "Height in P1-P2-P3 = " << h2 << G4endl
|
||||
<< "Height in P2-P3-P4 = " << h3 << G4endl
|
||||
<< "Height in P4-P0-P1 = " << h4;
|
||||
G4Exception("G4QuadrangularFacet::G4QuadrangularFacet()",
|
||||
"GeomSolids1001", JustWarning, message);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check that vertices are coplanar by computing minimal
|
||||
// height of tetrahedron comprising of vertices
|
||||
//
|
||||
G4double smax = std::max( std::max(s1,s2), std::max(s3,s4) );
|
||||
G4double hmin = 0.5 * std::fabs( e1.dot(e2.cross(e3)) ) / smax;
|
||||
if (hmin >= epsilon)
|
||||
{
|
||||
ostringstream message;
|
||||
message << "Facet is not planar." << G4endl
|
||||
<< "Disrepancy = " << hmin << G4endl
|
||||
<< "P0 = " << GetVertex(0) << G4endl
|
||||
<< "P1 = " << GetVertex(1) << G4endl
|
||||
<< "P2 = " << GetVertex(2) << G4endl
|
||||
<< "P3 = " << GetVertex(3);
|
||||
G4Exception("G4QuadrangularFacet::G4QuadrangularFacet()",
|
||||
"GeomSolids1001", JustWarning, message);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check that facet is convex by computing crosspoint
|
||||
// of diagonals
|
||||
//
|
||||
G4ThreeVector normal = e2.cross(e3-e1);
|
||||
G4double s = kInfinity, t = kInfinity, magnitude2 = normal.mag2();
|
||||
if (magnitude2 > delta*delta) // check: magnitude2 != 0.
|
||||
{
|
||||
s = normal.dot(e1.cross(e3-e1)) / magnitude2;
|
||||
t = normal.dot(e1.cross(e2)) / magnitude2;
|
||||
}
|
||||
if (s <= 0. || s >= 1. || t <= 0. || t >= 1.)
|
||||
{
|
||||
ostringstream message;
|
||||
message << "Facet is not convex." << G4endl
|
||||
<< "Parameters of crosspoint of diagonals: "
|
||||
<< s << " and " << t << G4endl
|
||||
<< "should both be within (0,1) range" << G4endl
|
||||
<< "P0 = " << GetVertex(0) << G4endl
|
||||
<< "P1 = " << GetVertex(1) << G4endl
|
||||
<< "P2 = " << GetVertex(2) << G4endl
|
||||
<< "P3 = " << GetVertex(3);
|
||||
G4Exception("G4QuadrangularFacet::G4QuadrangularFacet()",
|
||||
"GeomSolids1001", JustWarning, message);
|
||||
return;
|
||||
}
|
||||
|
||||
// Define facet
|
||||
//
|
||||
fFacet1 = G4TriangularFacet(GetVertex(0),GetVertex(1),GetVertex(2),ABSOLUTE);
|
||||
fFacet2 = G4TriangularFacet(GetVertex(0),GetVertex(2),GetVertex(3),ABSOLUTE);
|
||||
|
||||
normal = normal.unit();
|
||||
fFacet1.SetSurfaceNormal(normal);
|
||||
fFacet2.SetSurfaceNormal(normal);
|
||||
|
||||
G4ThreeVector vtmp = 0.5 * (e1 + e2);
|
||||
fCircumcentre = GetVertex(0) + vtmp;
|
||||
G4double radiusSqr = vtmp.mag2();
|
||||
fRadius = std::sqrt(radiusSqr);
|
||||
// 29.02.2016 Remark by E.Tcherniaev: computation
|
||||
// of fCircumcenter and fRadius is wrong, however
|
||||
// it did not create any problem till now.
|
||||
// Bizarre! Need to investigate!
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -250,20 +329,21 @@ G4bool G4QuadrangularFacet::Intersect (const G4ThreeVector &p,
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Auxiliary method to get a random point on surface
|
||||
// Auxiliary method to get a uniform random point on the facet
|
||||
//
|
||||
G4ThreeVector G4QuadrangularFacet::GetPointOnFace() const
|
||||
{
|
||||
G4ThreeVector pr = (G4RandFlat::shoot(0.,1.) < 0.5)
|
||||
? fFacet1.GetPointOnFace() : fFacet2.GetPointOnFace();
|
||||
return pr;
|
||||
G4double s1 = fFacet1.GetArea();
|
||||
G4double s2 = fFacet2.GetArea();
|
||||
return ((s1+s2)*G4UniformRand() < s1) ?
|
||||
fFacet1.GetPointOnFace() : fFacet2.GetPointOnFace();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Auxiliary method for returning the surface area
|
||||
//
|
||||
G4double G4QuadrangularFacet::GetArea()
|
||||
G4double G4QuadrangularFacet::GetArea() const
|
||||
{
|
||||
G4double area = fFacet1.GetArea() + fFacet2.GetArea();
|
||||
return area;
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4TessellatedSolid.cc 94457 2015-11-18 14:35:46Z gcosmo $
|
||||
// $Id: G4TessellatedSolid.cc 95311 2016-02-04 13:54:13Z gcosmo $
|
||||
//
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
@@ -1968,7 +1968,7 @@ G4double G4TessellatedSolid::GetCubicVolume ()
|
||||
G4VFacet &facet = *fFacets[i];
|
||||
G4double area = facet.GetArea();
|
||||
G4ThreeVector unit_normal = facet.GetSurfaceNormal();
|
||||
fCubicVolume += area * (facet.GetVertex(0) * unit_normal);
|
||||
fCubicVolume += area * (facet.GetVertex(0).dot(unit_normal));
|
||||
}
|
||||
fCubicVolume /= 3.;
|
||||
return fCubicVolume;
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// $Id: G4TriangularFacet.cc 87920 2015-01-21 13:11:38Z gcosmo $
|
||||
// $Id: G4TriangularFacet.cc 95945 2016-03-03 09:54:38Z gcosmo $
|
||||
//
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//
|
||||
@@ -56,6 +56,10 @@
|
||||
// and considerable CPU speedup together with the new
|
||||
// implementation of G4TessellatedSolid.
|
||||
//
|
||||
// 23 February 2016 E Tcherniaev, CERN
|
||||
// Improved test to detect degenerate (too small or
|
||||
// too narrow) triangles.
|
||||
//
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
#include "G4TriangularFacet.hh"
|
||||
@@ -96,69 +100,65 @@ G4TriangularFacet::G4TriangularFacet (const G4ThreeVector &vt0,
|
||||
fE2 = vt2;
|
||||
}
|
||||
|
||||
G4ThreeVector E1xE2 = fE1.cross(fE2);
|
||||
fArea = 0.5 * E1xE2.mag();
|
||||
for (G4int i = 0; i < 3; ++i) fIndices[i] = -1;
|
||||
|
||||
G4double eMag1 = fE1.mag();
|
||||
G4double eMag2 = fE2.mag();
|
||||
G4double eMag3 = (fE2-fE1).mag();
|
||||
fIsDefined = true;
|
||||
G4double delta = kCarTolerance; // Set tolerance for checking
|
||||
|
||||
if (eMag1 <= kCarTolerance || eMag2 <= kCarTolerance
|
||||
|| eMag3 <= kCarTolerance)
|
||||
// Check length of edges
|
||||
//
|
||||
G4double leng1 = fE1.mag();
|
||||
G4double leng2 = (fE2-fE1).mag();
|
||||
G4double leng3 = fE2.mag();
|
||||
if (leng1 <= delta || leng2 <= delta || leng3 <= delta)
|
||||
{
|
||||
fIsDefined = false;
|
||||
}
|
||||
|
||||
// Check min height of triangle
|
||||
//
|
||||
if (fIsDefined)
|
||||
{
|
||||
if (2.*fArea/std::max(std::max(leng1,leng2),leng3) <= delta)
|
||||
{
|
||||
fIsDefined = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Define facet
|
||||
//
|
||||
if (!fIsDefined)
|
||||
{
|
||||
ostringstream message;
|
||||
message << "Length of sides of facet are too small." << G4endl
|
||||
<< "fVertices[0] = " << GetVertex(0) << G4endl
|
||||
<< "fVertices[1] = " << GetVertex(1) << G4endl
|
||||
<< "fVertices[2] = " << GetVertex(2) << G4endl
|
||||
<< "Side lengths = fVertices[0]->fVertices[1]" << eMag1 << G4endl
|
||||
<< "Side lengths = fVertices[0]->fVertices[2]" << eMag2 << G4endl
|
||||
<< "Side lengths = fVertices[1]->fVertices[2]" << eMag3;
|
||||
message << "Facet is too small or too narrow." << G4endl
|
||||
<< "Triangle area = " << fArea << G4endl
|
||||
<< "P0 = " << GetVertex(0) << G4endl
|
||||
<< "P1 = " << GetVertex(1) << G4endl
|
||||
<< "P2 = " << GetVertex(2) << G4endl
|
||||
<< "Side1 length (P0->P1) = " << leng1 << G4endl
|
||||
<< "Side2 length (P1->P2) = " << leng2 << G4endl
|
||||
<< "Side3 length (P2->P0) = " << leng3;
|
||||
G4Exception("G4TriangularFacet::G4TriangularFacet()",
|
||||
"GeomSolids1001", JustWarning, message);
|
||||
fIsDefined = false;
|
||||
"GeomSolids1001", JustWarning, message);
|
||||
fSurfaceNormal.set(0,0,0);
|
||||
fA = fB = fC = 0.0;
|
||||
fDet = 0.0;
|
||||
fCircumcentre = vt0 + 0.5*fE1 + 0.5*fE2;
|
||||
fArea = fRadius = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
fIsDefined = true;
|
||||
fSurfaceNormal = fE1.cross(fE2).unit();
|
||||
fSurfaceNormal = E1xE2.unit();
|
||||
fA = fE1.mag2();
|
||||
fB = fE1.dot(fE2);
|
||||
fC = fE2.mag2();
|
||||
fDet = fabs(fA*fC - fB*fB);
|
||||
fDet = std::fabs(fA*fC - fB*fB);
|
||||
|
||||
// sMin = -0.5*kCarTolerance/sqrt(fA);
|
||||
// sMax = 1.0 - sMin;
|
||||
// tMin = -0.5*kCarTolerance/sqrt(fC);
|
||||
// G4ThreeVector vtmp = 0.25 * (fE1 + fE2);
|
||||
|
||||
fArea = 0.5 * (fE1.cross(fE2)).mag();
|
||||
G4double lambda0, lambda1;
|
||||
if(std::fabs(fArea) < kCarTolerance*kCarTolerance)
|
||||
{
|
||||
ostringstream message;
|
||||
message << "Area of Facet is too small, possible flat triangle!" << G4endl
|
||||
<< " fVertices[0] = " << GetVertex(0) << G4endl
|
||||
<< " fVertices[1] = " << GetVertex(1) << G4endl
|
||||
<< " fVertices[2] = " << GetVertex(2) << G4endl
|
||||
<< "Area = " << fArea;
|
||||
G4Exception("G4TriangularFacet::G4TriangularFacet()",
|
||||
"GeomSolids1001", JustWarning, message);
|
||||
lambda0 = 0.5;
|
||||
lambda1 = 0.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
lambda0 = (fA-fB) * fC / (8.0*fArea*fArea);
|
||||
lambda1 = (fC-fB) * fA / (8.0*fArea*fArea);
|
||||
}
|
||||
G4ThreeVector p0 = GetVertex(0);
|
||||
fCircumcentre = p0 + lambda0*fE1 + lambda1*fE2;
|
||||
G4double radiusSqr = (fCircumcentre-p0).mag2();
|
||||
fRadius = sqrt(radiusSqr);
|
||||
fCircumcentre =
|
||||
vt0 + (E1xE2.cross(fE1)*fC + fE2.cross(E1xE2)*fA) / (2.*E1xE2.mag2());
|
||||
fRadius = (fCircumcentre - vt0).mag();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -752,16 +752,14 @@ G4bool G4TriangularFacet::Intersect (const G4ThreeVector &p,
|
||||
//
|
||||
// GetPointOnFace
|
||||
//
|
||||
// Auxiliary method for get fA random point on surface
|
||||
// Auxiliary method, returns a uniform random point on the facet
|
||||
//
|
||||
G4ThreeVector G4TriangularFacet::GetPointOnFace() const
|
||||
{
|
||||
G4double alpha = G4RandFlat::shoot(0., 1.);
|
||||
G4double beta = G4RandFlat::shoot(0., 1.);
|
||||
G4double lambda1 = alpha*beta;
|
||||
G4double lambda0 = alpha-lambda1;
|
||||
|
||||
return GetVertex(0) + lambda0*fE1 + lambda1*fE2;
|
||||
G4double u = G4UniformRand();
|
||||
G4double v = G4UniformRand();
|
||||
if (u+v > 1.) { u = 1. - u; v = 1. - v; }
|
||||
return GetVertex(0) + u*fE1 + v*fE2;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@@ -770,7 +768,7 @@ G4ThreeVector G4TriangularFacet::GetPointOnFace() const
|
||||
//
|
||||
// Auxiliary method for returning the surface fArea
|
||||
//
|
||||
G4double G4TriangularFacet::GetArea()
|
||||
G4double G4TriangularFacet::GetArea() const
|
||||
{
|
||||
return fArea;
|
||||
}
|
||||
|
||||
@@ -33,9 +33,9 @@
|
||||
#include "G4ExtrudedSolid.hh"
|
||||
#include "G4UExtrudedSolid.hh"
|
||||
|
||||
#if defined(G4GEOM_USE_USOLIDS)
|
||||
#if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
|
||||
|
||||
#include "G4Polyhedron.hh"
|
||||
#include "G4PolyhedronArbitrary.hh"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -124,4 +124,90 @@ G4UExtrudedSolid::operator=(const G4UExtrudedSolid &source)
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Accessors
|
||||
|
||||
G4int G4UExtrudedSolid::GetNofVertices() const
|
||||
{
|
||||
return GetShape()->GetNofVertices();
|
||||
}
|
||||
G4TwoVector G4UExtrudedSolid::GetVertex(G4int i) const
|
||||
{
|
||||
UVector2 v = GetShape()->GetVertex(i);
|
||||
return G4TwoVector(v.x, v.y);
|
||||
}
|
||||
std::vector<G4TwoVector> G4UExtrudedSolid::GetPolygon() const
|
||||
{
|
||||
std::vector<UVector2> pol = GetShape()->GetPolygon();
|
||||
std::vector<G4TwoVector> v;
|
||||
for (unsigned int i=0; i<pol.size(); ++i)
|
||||
{
|
||||
v.push_back(G4TwoVector(pol[i].x, pol[i].y));
|
||||
}
|
||||
return v;
|
||||
}
|
||||
G4int G4UExtrudedSolid::GetNofZSections() const
|
||||
{
|
||||
return GetShape()->GetNofZSections();
|
||||
}
|
||||
G4UExtrudedSolid::ZSection G4UExtrudedSolid::GetZSection(G4int i) const
|
||||
{
|
||||
return ZSection(GetShape()->GetZSection(i));
|
||||
}
|
||||
std::vector<G4UExtrudedSolid::ZSection> G4UExtrudedSolid::GetZSections() const
|
||||
{
|
||||
std::vector<UExtrudedSolid::ZSection> sv = GetShape()->GetZSections();
|
||||
std::vector<G4UExtrudedSolid::ZSection> vec;
|
||||
for (unsigned int i=0; i<sv.size(); ++i)
|
||||
{
|
||||
vec.push_back(ZSection(sv[i]));
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CreatePolyhedron()
|
||||
//
|
||||
G4Polyhedron* G4UExtrudedSolid::CreatePolyhedron () const
|
||||
{
|
||||
G4int nFacets = GetShape()->GetNumberOfFacets();
|
||||
G4int nVertices = 0;
|
||||
for (G4int l = 0; l<nFacets; ++l) // compute total number of vertices first
|
||||
{
|
||||
VUFacet* facet = GetShape()->GetFacet(l);
|
||||
G4int n = facet->GetNumberOfVertices();
|
||||
nVertices += n;
|
||||
}
|
||||
|
||||
G4PolyhedronArbitrary *polyhedron =
|
||||
new G4PolyhedronArbitrary (nVertices,nFacets);
|
||||
|
||||
for (G4int i = 0; i<nFacets; ++i)
|
||||
{
|
||||
VUFacet* facet = GetShape()->GetFacet(i);
|
||||
G4int v[4];
|
||||
G4int n = facet->GetNumberOfVertices();
|
||||
for (G4int m = 0; m<n; ++m)
|
||||
{
|
||||
UVector3 vtx = facet->GetVertex(m);
|
||||
polyhedron->AddVertex(G4ThreeVector(vtx.x(), vtx.y(), vtx.z()));
|
||||
}
|
||||
if (n > 4) n = 4;
|
||||
else if (n == 3) v[3] = 0;
|
||||
for (G4int j=0; j<n; ++j)
|
||||
{
|
||||
G4int k = facet->GetVertexIndex(j);
|
||||
v[j] = k+1;
|
||||
}
|
||||
polyhedron->AddFacet(v[0],v[1],v[2],v[3]);
|
||||
}
|
||||
polyhedron->SetReferences();
|
||||
|
||||
return (G4Polyhedron*) polyhedron;
|
||||
}
|
||||
|
||||
#endif // G4GEOM_USE_USOLIDS
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#include "G4GenericPolycone.hh"
|
||||
#include "G4UGenericPolycone.hh"
|
||||
|
||||
#if defined(G4GEOM_USE_USOLIDS)
|
||||
#if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
|
||||
|
||||
#include "G4Polyhedron.hh"
|
||||
|
||||
@@ -98,6 +98,30 @@ G4UGenericPolycone::operator=(const G4UGenericPolycone &source)
|
||||
return *this;
|
||||
}
|
||||
|
||||
G4double G4UGenericPolycone::GetStartPhi() const
|
||||
{
|
||||
return GetShape()->GetStartPhi();
|
||||
}
|
||||
G4double G4UGenericPolycone::GetEndPhi() const
|
||||
{
|
||||
return GetShape()->GetEndPhi();
|
||||
}
|
||||
G4bool G4UGenericPolycone::IsOpen() const
|
||||
{
|
||||
return GetShape()->IsOpen();
|
||||
}
|
||||
G4int G4UGenericPolycone::GetNumRZCorner() const
|
||||
{
|
||||
return GetShape()->GetNumRZCorner();
|
||||
}
|
||||
G4PolyconeSideRZ G4UGenericPolycone::GetCorner(G4int index) const
|
||||
{
|
||||
UPolyconeSideRZ pside = GetShape()->GetCorner(index);
|
||||
G4PolyconeSideRZ psiderz = { pside.r, pside.z };
|
||||
|
||||
return psiderz;
|
||||
}
|
||||
|
||||
G4Polyhedron* G4UGenericPolycone::CreatePolyhedron() const
|
||||
{
|
||||
|
||||
|
||||
@@ -33,11 +33,14 @@
|
||||
#include "G4GenericTrap.hh"
|
||||
#include "G4UGenericTrap.hh"
|
||||
|
||||
#if defined(G4GEOM_USE_USOLIDS)
|
||||
#if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
|
||||
|
||||
#include "G4Polyhedron.hh"
|
||||
#include "G4PolyhedronArbitrary.hh"
|
||||
|
||||
#include "G4AutoLock.hh"
|
||||
namespace { G4Mutex UGenericTrapMutex = G4MUTEX_INITIALIZER; }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Constructor (generic parameters)
|
||||
@@ -101,6 +104,57 @@ G4UGenericTrap::operator=(const G4UGenericTrap &source)
|
||||
return *this;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Accessors & modifiers
|
||||
//
|
||||
G4double G4UGenericTrap::GetZHalfLength() const
|
||||
{
|
||||
return GetShape()->GetZHalfLength();
|
||||
}
|
||||
G4int G4UGenericTrap::GetNofVertices() const
|
||||
{
|
||||
return GetShape()->GetNofVertices();
|
||||
}
|
||||
G4TwoVector G4UGenericTrap::GetVertex(G4int index) const
|
||||
{
|
||||
UVector2 v = GetShape()->GetVertex(index);
|
||||
return G4TwoVector(v.x, v.y);
|
||||
}
|
||||
const std::vector<G4TwoVector>& G4UGenericTrap::GetVertices() const
|
||||
{
|
||||
G4AutoLock l(&UGenericTrapMutex);
|
||||
std::vector<UVector2> v = GetShape()->GetVertices();
|
||||
static std::vector<G4TwoVector> vertices; vertices.clear();
|
||||
for (size_t n=0; n<v.size(); ++n)
|
||||
{
|
||||
vertices.push_back(G4TwoVector(v[n].x,v[n].y));
|
||||
}
|
||||
return vertices;
|
||||
}
|
||||
G4double G4UGenericTrap::GetTwistAngle(G4int index) const
|
||||
{
|
||||
return GetShape()->GetTwistAngle(index);
|
||||
}
|
||||
G4bool G4UGenericTrap::IsTwisted() const
|
||||
{
|
||||
return GetShape()->IsTwisted();
|
||||
}
|
||||
G4int G4UGenericTrap::GetVisSubdivisions() const
|
||||
{
|
||||
return GetShape()->GetVisSubdivisions();
|
||||
}
|
||||
|
||||
void G4UGenericTrap::SetVisSubdivisions(G4int subdiv)
|
||||
{
|
||||
GetShape()->SetVisSubdivisions(subdiv);
|
||||
}
|
||||
|
||||
void G4UGenericTrap::SetZHalfLength(G4double halfZ)
|
||||
{
|
||||
GetShape()->SetZHalfLength(halfZ);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CreatePolyhedron()
|
||||
|
||||
@@ -35,9 +35,11 @@
|
||||
#include "G4Paraboloid.hh"
|
||||
#include "G4UParaboloid.hh"
|
||||
|
||||
#if defined(G4GEOM_USE_USOLIDS)
|
||||
#if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
|
||||
|
||||
#include "G4VPVParameterisation.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
#include "G4Polyhedron.hh"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -91,6 +93,25 @@ G4UParaboloid& G4UParaboloid::operator = (const G4UParaboloid& rhs)
|
||||
return *this;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Accessors
|
||||
|
||||
G4double G4UParaboloid::GetZHalfLength() const
|
||||
{
|
||||
return GetShape()->GetDz();
|
||||
}
|
||||
|
||||
G4double G4UParaboloid::GetRadiusMinusZ() const
|
||||
{
|
||||
return GetShape()->GetRlo();
|
||||
}
|
||||
|
||||
G4double G4UParaboloid::GetRadiusPlusZ() const
|
||||
{
|
||||
return GetShape()->GetRhi();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Make a clone of the object
|
||||
@@ -100,4 +121,15 @@ G4VSolid* G4UParaboloid::Clone() const
|
||||
return new G4UParaboloid(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CreatePolyhedron
|
||||
//
|
||||
G4Polyhedron* G4UParaboloid::CreatePolyhedron() const
|
||||
{
|
||||
return new G4PolyhedronParaboloid(GetRadiusMinusZ(),
|
||||
GetRadiusPlusZ(),
|
||||
GetZHalfLength(), 0., twopi);
|
||||
}
|
||||
|
||||
#endif // G4GEOM_USE_USOLIDS
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include "G4Polycone.hh"
|
||||
#include "G4UPolycone.hh"
|
||||
|
||||
#if defined(G4GEOM_USE_USOLIDS)
|
||||
#if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
|
||||
|
||||
#include "G4VPVParameterisation.hh"
|
||||
|
||||
@@ -112,6 +112,67 @@ G4UPolycone &G4UPolycone::operator=( const G4UPolycone &source )
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Accessors & modifiers
|
||||
//
|
||||
G4double G4UPolycone::GetStartPhi() const
|
||||
{
|
||||
return GetShape()->GetStartPhi();
|
||||
}
|
||||
G4double G4UPolycone::GetEndPhi() const
|
||||
{
|
||||
return GetShape()->GetEndPhi();
|
||||
}
|
||||
G4bool G4UPolycone::IsOpen() const
|
||||
{
|
||||
return GetShape()->IsOpen();
|
||||
}
|
||||
G4int G4UPolycone::GetNumRZCorner() const
|
||||
{
|
||||
return GetShape()->GetNumRZCorner();
|
||||
}
|
||||
G4PolyconeSideRZ G4UPolycone::GetCorner(G4int index) const
|
||||
{
|
||||
UPolyconeSideRZ pside = GetShape()->GetCorner(index);
|
||||
G4PolyconeSideRZ psiderz = { pside.r, pside.z };
|
||||
|
||||
return psiderz;
|
||||
}
|
||||
G4PolyconeHistorical* G4UPolycone::GetOriginalParameters() const
|
||||
{
|
||||
UPolyconeHistorical* pars = GetShape()->GetOriginalParameters();
|
||||
G4PolyconeHistorical* pdata = new G4PolyconeHistorical(pars->fNumZPlanes);
|
||||
pdata->Start_angle = pars->fStartAngle;
|
||||
pdata->Opening_angle = pars->fOpeningAngle;
|
||||
for (G4int i=0; i<pars->fNumZPlanes; ++i)
|
||||
{
|
||||
pdata->Z_values[i] = pars->fZValues[i];
|
||||
pdata->Rmin[i] = pars->Rmin[i];
|
||||
pdata->Rmax[i] = pars->Rmax[i];
|
||||
}
|
||||
return pdata;
|
||||
}
|
||||
void G4UPolycone::SetOriginalParameters(G4PolyconeHistorical* pars)
|
||||
{
|
||||
UPolyconeHistorical* pdata = GetShape()->GetOriginalParameters();
|
||||
pdata->fStartAngle = pars->Start_angle;
|
||||
pdata->fOpeningAngle = pars->Opening_angle;
|
||||
pdata->fNumZPlanes = pars->Num_z_planes;
|
||||
for (G4int i=0; i<pdata->fNumZPlanes; ++i)
|
||||
{
|
||||
pdata->fZValues[i] = pars->Z_values[i];
|
||||
pdata->Rmin[i] = pars->Rmin[i];
|
||||
pdata->Rmax[i] = pars->Rmax[i];
|
||||
}
|
||||
fRebuildPolyhedron = true;
|
||||
}
|
||||
G4bool G4UPolycone::Reset()
|
||||
{
|
||||
GetShape()->Reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dispatch to parameterisation for replication mechanism dimension
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include "G4Polyhedra.hh"
|
||||
#include "G4UPolyhedra.hh"
|
||||
|
||||
#if defined(G4GEOM_USE_USOLIDS)
|
||||
#if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
|
||||
|
||||
#include "G4VPVParameterisation.hh"
|
||||
|
||||
@@ -119,6 +119,77 @@ G4UPolyhedra& G4UPolyhedra::operator=( const G4UPolyhedra &source )
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Accessors & modifiers
|
||||
//
|
||||
G4int G4UPolyhedra::GetNumSide() const
|
||||
{
|
||||
return GetShape()->GetNumSide();
|
||||
}
|
||||
G4double G4UPolyhedra::GetStartPhi() const
|
||||
{
|
||||
return GetShape()->GetStartPhi();
|
||||
}
|
||||
G4double G4UPolyhedra::GetEndPhi() const
|
||||
{
|
||||
return GetShape()->GetEndPhi();
|
||||
}
|
||||
G4bool G4UPolyhedra::IsOpen() const
|
||||
{
|
||||
return GetShape()->IsOpen();
|
||||
}
|
||||
G4bool G4UPolyhedra::IsGeneric() const
|
||||
{
|
||||
return GetShape()->IsGeneric();
|
||||
}
|
||||
G4int G4UPolyhedra::GetNumRZCorner() const
|
||||
{
|
||||
return GetShape()->GetNumRZCorner();
|
||||
}
|
||||
G4PolyhedraSideRZ G4UPolyhedra::GetCorner(G4int index) const
|
||||
{
|
||||
UPolyhedraSideRZ pside = GetShape()->GetCorner(index);
|
||||
G4PolyhedraSideRZ psiderz = { pside.r, pside.z };
|
||||
|
||||
return psiderz;
|
||||
}
|
||||
G4PolyhedraHistorical* G4UPolyhedra::GetOriginalParameters() const
|
||||
{
|
||||
UPolyhedraHistorical* pars = GetShape()->GetOriginalParameters();
|
||||
G4PolyhedraHistorical* pdata = new G4PolyhedraHistorical(pars->fNumZPlanes);
|
||||
pdata->Start_angle = pars->fStartAngle;
|
||||
pdata->Opening_angle = pars->fOpeningAngle;
|
||||
pdata->numSide = pars->fNumSide;
|
||||
for (G4int i=0; i<pars->fNumZPlanes; ++i)
|
||||
{
|
||||
pdata->Z_values[i] = pars->fZValues[i];
|
||||
pdata->Rmin[i] = pars->Rmin[i];
|
||||
pdata->Rmax[i] = pars->Rmax[i];
|
||||
}
|
||||
return pdata;
|
||||
}
|
||||
void G4UPolyhedra::SetOriginalParameters(G4PolyhedraHistorical* pars)
|
||||
{
|
||||
UPolyhedraHistorical* pdata = GetShape()->GetOriginalParameters();
|
||||
pdata->fStartAngle = pars->Start_angle;
|
||||
pdata->fOpeningAngle = pars->Opening_angle;
|
||||
pdata->fNumSide = pars->numSide;
|
||||
pdata->fNumZPlanes = pars->Num_z_planes;
|
||||
for (G4int i=0; i<pdata->fNumZPlanes; ++i)
|
||||
{
|
||||
pdata->fZValues[i] = pars->Z_values[i];
|
||||
pdata->Rmin[i] = pars->Rmin[i];
|
||||
pdata->Rmax[i] = pars->Rmax[i];
|
||||
}
|
||||
fRebuildPolyhedron = true;
|
||||
}
|
||||
G4bool G4UPolyhedra::Reset()
|
||||
{
|
||||
return GetShape()->Reset();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dispatch to parameterisation for replication mechanism dimension
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
#include "G4Tet.hh"
|
||||
#include "G4UTet.hh"
|
||||
|
||||
#if defined(G4GEOM_USE_USOLIDS)
|
||||
#if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -106,4 +106,43 @@ G4UTet& G4UTet::operator = (const G4UTet& rhs)
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Accessors
|
||||
//
|
||||
std::vector<G4ThreeVector> G4UTet::GetVertices() const
|
||||
{
|
||||
std::vector<UVector3> vec = GetShape()->GetVertices();
|
||||
std::vector<G4ThreeVector> vertices;
|
||||
for (unsigned int i=0; i<vec.size(); ++i)
|
||||
{
|
||||
G4ThreeVector v(vec[i].x(), vec[i].y(), vec[i].z());
|
||||
vertices.push_back(v);
|
||||
}
|
||||
return vertices;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CreatePolyhedron
|
||||
//
|
||||
G4Polyhedron* G4UTet::CreatePolyhedron() const
|
||||
{
|
||||
G4int index = 0;
|
||||
G4double array[12];
|
||||
GetShape()->GetParametersList(index, array);
|
||||
|
||||
G4Polyhedron *ph=new G4Polyhedron;
|
||||
G4double xyz[4][3];
|
||||
const G4int faces[4][4]={{1,3,2,0},{1,4,3,0},{1,2,4,0},{2,3,4,0}};
|
||||
xyz[0][0]=array[0]; xyz[0][1]=array[1]; xyz[0][2]=array[2]; // fAnchor
|
||||
xyz[1][0]=array[3]; xyz[1][1]=array[4]; xyz[1][2]=array[5]; // fP2
|
||||
xyz[2][0]=array[6]; xyz[2][1]=array[7]; xyz[2][2]=array[8]; // fP3
|
||||
xyz[3][0]=array[9]; xyz[3][1]=array[10]; xyz[3][2]=array[11]; // fP4
|
||||
|
||||
ph->createPolyhedron(4,4,xyz,faces);
|
||||
|
||||
return ph;
|
||||
}
|
||||
|
||||
#endif // G4GEOM_USE_USOLIDS
|
||||
|
||||
Reference in New Issue
Block a user