Import Geant4 10.3.0.beta source tree

This commit is contained in:
Gabriele Cosmo
2016-06-30 14:12:05 +02:00
parent a654a7ab1f
commit 4ec577e5c4
2021 changed files with 100995 additions and 78277 deletions
@@ -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
+40 -1
View File
@@ -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