415 lines
12 KiB
C++
415 lines
12 KiB
C++
//
|
|
// ********************************************************************
|
|
// * DISCLAIMER *
|
|
// * *
|
|
// * The following disclaimer summarizes all the specific disclaimers *
|
|
// * of contributors to this software. The specific disclaimers,which *
|
|
// * govern, are listed with their locations in: *
|
|
// * http://cern.ch/geant4/license *
|
|
// * *
|
|
// * Neither the authors of this software system, nor their employing *
|
|
// * institutes,nor the agencies providing financial support for this *
|
|
// * work make any representation or warranty, express or implied, *
|
|
// * regarding this software system or assume any liability for its *
|
|
// * use. *
|
|
// * *
|
|
// * This code implementation is the intellectual property of the *
|
|
// * GEANT4 collaboration. *
|
|
// * By copying, distributing or modifying the Program (or any work *
|
|
// * based on the Program) you indicate your acceptance of this *
|
|
// * statement, and all its terms. *
|
|
// ********************************************************************
|
|
//
|
|
//
|
|
// $Id: G4Surface.cc,v 1.9 2001/07/11 09:59:47 gunter Exp $
|
|
// GEANT4 tag $Name: geant4-04-00 $
|
|
//
|
|
// ----------------------------------------------------------------------
|
|
// GEANT 4 class source file
|
|
//
|
|
// G4Surface.cc
|
|
//
|
|
// ----------------------------------------------------------------------
|
|
|
|
#include "G4Surface.hh"
|
|
#include "G4CompositeCurve.hh"
|
|
|
|
G4Surface::G4Surface()
|
|
: FLT_MAXX(kInfinity), FLT_EPSILO(0.0001)
|
|
{
|
|
AdvancedFace=0;
|
|
active = 1;
|
|
distance = 1.0e20;
|
|
Type=0;
|
|
bbox = (G4BoundingBox3D*)0;
|
|
}
|
|
|
|
G4Surface::~G4Surface()
|
|
{
|
|
}
|
|
|
|
G4int G4Surface::operator==( const G4Surface& s )
|
|
{
|
|
return origin == s.origin;
|
|
}
|
|
|
|
G4String G4Surface::GetEntityType() const
|
|
{
|
|
return G4String("Surface");
|
|
}
|
|
|
|
const char* G4Surface::Name() const
|
|
{
|
|
return "G4Surface";
|
|
}
|
|
|
|
G4int G4Surface::MyType() const
|
|
{
|
|
return Type;
|
|
}
|
|
|
|
void G4Surface::InitBounded()
|
|
{
|
|
}
|
|
|
|
G4double G4Surface::GetUHit() const
|
|
{
|
|
return uhit;
|
|
}
|
|
|
|
G4double G4Surface::GetVHit() const
|
|
{
|
|
return vhit;
|
|
}
|
|
|
|
//void G4Surface::read_surface(fstream& tmp){;}
|
|
|
|
G4Point3D G4Surface::Evaluation(const G4Ray& rayref)
|
|
{
|
|
return closest_hit;
|
|
}
|
|
|
|
G4int G4Surface::Evaluate(const G4Ray& rayref)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
void G4Surface::Reset()
|
|
{
|
|
Intersected = 0;
|
|
active = 1;
|
|
distance = kInfinity;
|
|
}
|
|
|
|
void G4Surface::SetBoundaries(G4CurveVector* boundaries)
|
|
{
|
|
surfaceBoundary.Init(*boundaries);
|
|
InitBounded();
|
|
}
|
|
|
|
void G4Surface::CalcBBox()
|
|
{
|
|
// Finds the bounds of the surface iow
|
|
// calculates the bounds for a bounding box
|
|
// to the surface. The bounding box is used
|
|
// for a preliminary check of intersection.
|
|
|
|
bbox = new G4BoundingBox3D(surfaceBoundary.BBox().GetBoxMin(),
|
|
surfaceBoundary.BBox().GetBoxMax());
|
|
// old implementation
|
|
// G4Point3d BoundaryMax = OuterBoundary->GetBoundsMax();
|
|
// G4Point3d BoundaryMin = OuterBoundary->GetBoundsMin();
|
|
// bbox = new G4BoundingBox( BoundaryMin, BoundaryMax);
|
|
// return;
|
|
}
|
|
|
|
G4Vector3D G4Surface::Normal( const G4Vector3D& ) const
|
|
{ // return the Normal unit vector to a Surface at the point p on
|
|
// (or nearly on) the Surface.
|
|
// The default is not well defined, so return ( 0, 0, 0 ).
|
|
return G4Vector3D( 0.0, 0.0, 0.0 );
|
|
}
|
|
|
|
|
|
G4int G4Surface::Intersect(const G4Ray& rayref)
|
|
{
|
|
G4int Result = 0;
|
|
|
|
G4Exception("G4Surface::Intersect is not implemented. It should not be called. ");
|
|
|
|
#ifdef NEW_IMPLEMENTATION
|
|
// get the intersection
|
|
// Result = Intersect(rayref);
|
|
|
|
// Check that the point is within the polyline
|
|
// Get Normal at Hitpoint
|
|
const G4Vector3D& Vec = Normal(closest_hit);
|
|
G4Ray Normal(closest_hit, Vec);
|
|
|
|
// Project points & Hit
|
|
// OuterBoundary->ProjectBoundaryTo2D(Normal.GetPlane(1),
|
|
// Normal.GetPlane(2), 0);
|
|
|
|
|
|
|
|
|
|
G4Point3D Hit = closest_hit.Project(Normal.GetPlane(1),
|
|
Normal.GetPlane(2) );
|
|
// Check point in polygon
|
|
// Result = OuterBoundary->Inside(Hit, rayref);
|
|
|
|
#endif
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
|
G4double G4Surface::ClosestDistanceToPoint(const G4Point3D& Pt)
|
|
{
|
|
// in fact, a squared distance is returned
|
|
|
|
// a bit suspicious, this function
|
|
// the distance is almost always an overestimate
|
|
G4double pointDistance= kInfinity;
|
|
G4double tmpDistance;
|
|
const G4CurveVector& bounds= surfaceBoundary.GetBounds();
|
|
|
|
G4int entr = bounds.size();
|
|
|
|
for (G4int i=0; i<entr; i++)
|
|
{
|
|
G4Curve* c= bounds[i];
|
|
|
|
if (c->GetEntityType() == "G4CompositeCurve")
|
|
{
|
|
G4CompositeCurve* cc= (G4CompositeCurve*)c;
|
|
const G4CurveVector& segments= cc->GetSegments();
|
|
for (size_t i=0; i<segments.size(); i++)
|
|
{
|
|
G4Curve* ccc= segments[i];
|
|
tmpDistance= (G4Point3D(Pt.x(), Pt.y(), Pt.z())-ccc->GetEnd()).mag2();
|
|
if (pointDistance > tmpDistance)
|
|
{
|
|
pointDistance= tmpDistance;
|
|
}
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
tmpDistance= (G4Point3D(Pt.x(), Pt.y(), Pt.z())-c->GetEnd()).mag2();
|
|
if (pointDistance > tmpDistance)
|
|
{
|
|
pointDistance= tmpDistance;
|
|
}
|
|
}
|
|
}
|
|
|
|
// L. Broglia
|
|
// Be carreful ! pointdistance is the squared distance
|
|
return sqrt(pointDistance);
|
|
|
|
// G4double PointDistance=kInfinity;
|
|
// G4double TmpDistance=0;
|
|
// PointDistance = OuterBoundary->ClosestDistanceToPoint(Pt);
|
|
// TmpDistance =0;
|
|
// for(G4int a=0;a<NumberOfInnerBoundaries;a++)
|
|
// {
|
|
// TmpDistance = InnerBoundary[a]->ClosestDistanceToPoint(Pt);
|
|
// if(PointDistance > TmpDistance) PointDistance = TmpDistance;
|
|
// }
|
|
// return PointDistance;
|
|
|
|
//G4double G4Boundary::ClosestDistanceToPoint(const G4ThreeVec& Pt)
|
|
//{
|
|
// G4double PointDistance = kInfinity;
|
|
// G4double TmpDistance = 0;
|
|
// for(G4int a =0; a < NumberOfPoints;a++)
|
|
// {
|
|
// G4Point3d& Pt2 = GetPoint(a);
|
|
// TmpDistance = Pt2.Distance(Pt);
|
|
// if(PointDistance > TmpDistance)PointDistance = TmpDistance;
|
|
// }
|
|
// return PointDistance;
|
|
//}
|
|
}
|
|
|
|
|
|
G4std::ostream& operator<<( G4std::ostream& os, const G4Surface& s )
|
|
{
|
|
// overwrite output operator << to Print out Surface objects
|
|
// using the PrintOn function defined below
|
|
// s.PrintOn( os );
|
|
return os;
|
|
}
|
|
|
|
|
|
G4double G4Surface::HowNear( const G4Vector3D& x ) const
|
|
{
|
|
// Distance from the point x to a Surface.
|
|
// The default for a Surface is the distance from the point to the origin.
|
|
G4Vector3D p = G4Vector3D( x - origin );
|
|
return p.mag();
|
|
}
|
|
|
|
void G4Surface::Project()
|
|
{
|
|
}
|
|
|
|
void G4Surface::CalcNormal()
|
|
{
|
|
}
|
|
|
|
G4int G4Surface::IsConvex() const
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
G4int G4Surface::GetConvex() const
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
G4int G4Surface::GetNumberOfPoints() const
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
const G4Point3D& G4Surface::GetPoint(G4int) const
|
|
{
|
|
const G4Point3D* tmp= new G4Point3D(0,0,0);
|
|
return *tmp;
|
|
}
|
|
|
|
G4Ray* G4Surface::Norm()
|
|
{
|
|
return (G4Ray*)0;
|
|
}
|
|
|
|
/*
|
|
G4double G4Surface::distanceAlongRay( G4int which_way, const G4Ray* ry,
|
|
G4ThreeVec& p ) const
|
|
{ // Distance along a Ray (straight line with G4ThreeVec) to leave or enter
|
|
// a Surface. The input variable which_way should be set to +1 to indicate
|
|
// leaving a Surface, -1 to indicate entering a Surface.
|
|
// p is the point of intersection of the Ray with the Surface.
|
|
// This is a default function which just gives the distance
|
|
// between the origin of the Ray and the origin of the Surface.
|
|
// Since a generic Surface doesn't have a well-defined Normal, no
|
|
// further checks are Done.
|
|
|
|
// This should always be overwritten for derived classes so Print out
|
|
// a warning message if this is called.
|
|
G4cout << "WARNING from Surface::distanceAlongRay\n"
|
|
<< " This function should be overwritten by a derived class.\n"
|
|
<< " Using the Surface base class default.\n";
|
|
p = GetOrigin();
|
|
G4ThreeVec d = ry->Position() - p;
|
|
return d.Magnitude();
|
|
}
|
|
|
|
G4double G4Surface::distanceAlongHelix( G4int which_way, const Helix* hx,
|
|
G4ThreeVec& p ) const
|
|
{ // Distance along a Helix to leave or enter a Surface.
|
|
// The input variable which_way should be set to +1 to indicate
|
|
// leaving a Surface, -1 to indicate entering a Surface.
|
|
// p is the point of intersection of the Helix with the Surface.
|
|
// This is a default function which just gives the distance
|
|
// between the origin of the Helix and the origin of the Surface.
|
|
// Since a generic Surface doesn't have a well-defined Normal, no
|
|
// further checks are Done.
|
|
|
|
// This should always be overwritten for derived classes so Print out
|
|
// a warning message if this is called.
|
|
G4cout << "WARNING from Surface::distanceAlongHelix\n"
|
|
<< " This function should be overwritten by a derived class.\n"
|
|
<< " Using the Surface base class default.\n";
|
|
p = GetOrigin();
|
|
G4ThreeVec d = hx->position() - p;
|
|
return d.Magnitude();
|
|
}
|
|
|
|
|
|
G4ThreeVec G4Surface::Normal() const
|
|
{ // return the Normal unit vector to a Surface
|
|
// (This is only meaningful for Surfaces for which the Normal does
|
|
// not depend on location on the Surface).
|
|
// The default is not well defined, so return ( 0, 0, 0 ).
|
|
return G4ThreeVec( 0.0, 0.0, 0.0 );
|
|
}
|
|
|
|
|
|
G4ThreeVec G4Surface::Normal( const G4ThreeVec& ) const
|
|
{ // return the Normal unit vector to a Surface at the point p on
|
|
// (or nearly on) the Surface.
|
|
// The default is not well defined, so return ( 0, 0, 0 ).
|
|
return G4ThreeVec( 0.0, 0.0, 0.0 );
|
|
}
|
|
|
|
G4int G4Surface::Inside( const G4ThreeVec& ) const
|
|
{ // return 0 if point p is outside Surface, 1 if Inside
|
|
// default is not well defined, so return 0
|
|
return 0;
|
|
}
|
|
|
|
void G4Surface::move( const G4ThreeVec& p )
|
|
{ // translate origin of Surface by vector p
|
|
origin += p;
|
|
}
|
|
|
|
void G4Surface::rotate( G4double alpha, G4double beta,
|
|
G4double gamma, G4ThreeMat& m, G4int inverse )
|
|
{ // rotate Surface first about global x-axis by angle alpha,
|
|
// second about global y-axis by angle beta,
|
|
// and third about global z-axis by angle gamma
|
|
// by creating and using G4ThreeMat objects
|
|
// angles are assumed to be given in radians
|
|
// returns also the overall rotation matrix for use by subclasses
|
|
// if inverse is non-zero, the order of rotations is reversed
|
|
// for a generic Surface, only the origin is rotated
|
|
// G4double ax[3][3] = { 0., 0., 0., 0., 0., 0., 0., 0., 0. };
|
|
G4double ax[3][3];
|
|
G4double ay[3][3];
|
|
G4double az[3][3];
|
|
// G4double ay[3][3] = { 0., 0., 0., 0., 0., 0., 0., 0., 0. };
|
|
// G4double az[3][3] = { 0., 0., 0., 0., 0., 0., 0., 0., 0. };
|
|
ax[0][0] = 1.;
|
|
ax[1][1] = cos( alpha );
|
|
ax[2][2] = ax[1][1];
|
|
ax[2][1] = sin( alpha );
|
|
ax[1][2] = -ax[2][1];
|
|
ay[1][1] = 1.;
|
|
ay[0][0] = cos( beta );
|
|
ay[2][2] = ay[0][0];
|
|
ay[0][2] = sin( beta );
|
|
ay[2][0] = -ay[0][2];
|
|
az[2][2] = 1.;
|
|
az[0][0] = cos( gamma );
|
|
az[1][1] = az[0][0];
|
|
az[1][0] = sin( gamma );
|
|
az[0][1] = -az[1][0];
|
|
G4ThreeMat &Rx = *new G4ThreeMat( ax ); // x-rotation matrix
|
|
G4ThreeMat &Ry = *new G4ThreeMat( ay ); // y-rotation matrix
|
|
G4ThreeMat &Rz = *new G4ThreeMat( az ); // z-rotation matrix
|
|
if ( inverse )
|
|
m = Rx * ( Ry * Rz );
|
|
else
|
|
m = Rz * ( Ry * Rx );
|
|
origin = m * origin;
|
|
}
|
|
|
|
void G4Surface::rotate( G4double alpha, G4double beta,
|
|
G4double gamma, G4int inverse )
|
|
{ // rotate Surface first about global x-axis by angle alpha,
|
|
// second about global y-axis by angle beta,
|
|
// and third about global z-axis by angle gamma
|
|
// by creating and using G4ThreeMat objects
|
|
// angles are assumed to be given in radians
|
|
// if inverse is non-zero, the order of rotations is reversed
|
|
G4ThreeMat m;
|
|
// Just call the above function to do this rotation
|
|
rotate( alpha, beta, gamma, m, inverse );
|
|
}
|
|
|
|
*/
|