261 lines
7.4 KiB
C++
261 lines
7.4 KiB
C++
// This code implementation is the intellectual property of
|
|
// the RD44 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: G4PTrap.cc,v 2.1 1998/07/12 03:01:29 urbi Exp $
|
|
// GEANT4 tag $Name: geant4-00 $
|
|
//
|
|
// class G4PTrap
|
|
//
|
|
// Implementation for G4PTrap class
|
|
//
|
|
// History:
|
|
// 19.06.98 A.Kimura Converted G4Trap.cc
|
|
|
|
#include <math.h>
|
|
|
|
#include "G4VSolid.hh"
|
|
#include "G4PTrap.hh"
|
|
#include "G4Trap.hh"
|
|
|
|
#include "G4AffineTransform.hh"
|
|
|
|
const G4double kCoplanar_Tolerance=1E-4;
|
|
|
|
// Destructor
|
|
|
|
G4PTrap::~G4PTrap()
|
|
{
|
|
;
|
|
}
|
|
|
|
// make a transient object
|
|
G4VSolid* G4PTrap::MakeTransientObject() const {
|
|
G4VSolid* transientObject = new G4Trap(GetName(),
|
|
fDx1, fDx2,
|
|
fDy1, fDy2,
|
|
fDz);
|
|
return transientObject;
|
|
}
|
|
|
|
// Constructor for G4Trd
|
|
|
|
G4PTrap::G4PTrap(const G4Trap* theTrap)
|
|
: G4PCSGSolid(theTrap->GetName()) {
|
|
|
|
G4double pDx1 = theTrap->GetXHalfLength1();
|
|
G4double pDx2 = theTrap->GetXHalfLength2();
|
|
G4double pDy1 = theTrap->GetYHalfLength1();
|
|
G4double pDy2 = theTrap->GetYHalfLength2();
|
|
G4double pDz = theTrap->GetZHalfLength();
|
|
|
|
G4bool good;
|
|
|
|
if (pDz>0 && pDy1>0 && pDx1>0 && pDx2>0 && pDy2>0 )
|
|
{
|
|
fDz = pDz;
|
|
fTthetaCphi = 0 ;
|
|
fTthetaSphi = 0 ;
|
|
|
|
fDy1 = pDy1 ;
|
|
fDx1 = pDx1 ;
|
|
fDx2 = pDx1 ;
|
|
fTalpha1 = 0 ;
|
|
|
|
fDy2 = pDy2 ;
|
|
fDx3 = pDx2 ;
|
|
fDx4 = pDx2 ;
|
|
fTalpha2 = 0 ;
|
|
|
|
G4ThreeVector pt[8] ;
|
|
|
|
pt[0]=G4ThreeVector(-fDz*fTthetaCphi-fDy1*fTalpha1-fDx1,-fDz*fTthetaSphi-fDy1,-fDz);
|
|
pt[1]=G4ThreeVector(-fDz*fTthetaCphi-fDy1*fTalpha1+fDx1,-fDz*fTthetaSphi-fDy1,-fDz);
|
|
pt[2]=G4ThreeVector(-fDz*fTthetaCphi+fDy1*fTalpha1-fDx2,-fDz*fTthetaSphi+fDy1,-fDz);
|
|
pt[3]=G4ThreeVector(-fDz*fTthetaCphi+fDy1*fTalpha1+fDx2,-fDz*fTthetaSphi+fDy1,-fDz);
|
|
pt[4]=G4ThreeVector(+fDz*fTthetaCphi-fDy2*fTalpha2-fDx3,+fDz*fTthetaSphi-fDy2,+fDz);
|
|
pt[5]=G4ThreeVector(+fDz*fTthetaCphi-fDy2*fTalpha2+fDx3,+fDz*fTthetaSphi-fDy2,+fDz);
|
|
pt[6]=G4ThreeVector(+fDz*fTthetaCphi+fDy2*fTalpha2-fDx4,+fDz*fTthetaSphi+fDy2,+fDz);
|
|
pt[7]=G4ThreeVector(+fDz*fTthetaCphi+fDy2*fTalpha2+fDx4,+fDz*fTthetaSphi+fDy2,+fDz);
|
|
// Bottom side with normal approx. -Y
|
|
good=MakePlane(pt[0],pt[4],pt[5],pt[1],fPlanes[0]);
|
|
if (!good)
|
|
{
|
|
G4Exception("G4PTrap::G4PTrap - face at ~-Y not planar");
|
|
|
|
}
|
|
// Top side with normal approx. +Y
|
|
good=MakePlane(pt[2],pt[3],pt[7],pt[6],fPlanes[1]);
|
|
if (!good)
|
|
{
|
|
G4Exception("G4PTrap::G4PTrap - face at ~+Y not planar");
|
|
}
|
|
// Front side with normal approx. -X
|
|
good=MakePlane(pt[0],pt[2],pt[6],pt[4],fPlanes[2]);
|
|
if (!good)
|
|
{
|
|
G4Exception("G4PTrap::G4PTrap - face at ~-X not planar");
|
|
}
|
|
// Back side iwth normal approx. +X
|
|
good=MakePlane(pt[1],pt[5],pt[7],pt[3],fPlanes[3]);
|
|
if (!good)
|
|
{
|
|
G4Exception("G4PTrap::G4PTrap - face at ~+X not planar");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
G4Exception("Error in G4PTrap::G4PTrap - Invalid Length G4PTrapmeters");
|
|
}
|
|
}
|
|
|
|
// Set all parameters, as for constructor - check and set half-widths
|
|
// as well as angles: final check of coplanarity
|
|
|
|
void G4PTrap::SetAllParameters ( G4double pDz,
|
|
G4double pTheta,
|
|
G4double pPhi,
|
|
G4double pDy1,
|
|
G4double pDx1,
|
|
G4double pDx2,
|
|
G4double pAlp1,
|
|
G4double pDy2,
|
|
G4double pDx3,
|
|
G4double pDx4,
|
|
G4double pAlp2)
|
|
{
|
|
if (pDz>0 && pDy1>0 && pDx1>0 && pDx2>0 && pDy2>0 && pDx3>0 && pDx4>0)
|
|
{
|
|
fDz=pDz;
|
|
fTthetaCphi=tan(pTheta)*cos(pPhi);
|
|
fTthetaSphi=tan(pTheta)*sin(pPhi);
|
|
|
|
fDy1=pDy1;
|
|
fDx1=pDx1;
|
|
fDx2=pDx2;
|
|
fTalpha1=tan(pAlp1);
|
|
|
|
fDy2=pDy2;
|
|
fDx3=pDx3;
|
|
fDx4=pDx4;
|
|
fTalpha2=tan(pAlp2);
|
|
|
|
MakePlanes();
|
|
}
|
|
else
|
|
{
|
|
G4Exception("Error in G4PTrap::SetAll - Invalid Length G4PTrapmeters");
|
|
}
|
|
}
|
|
|
|
G4bool G4PTrap::MakePlanes()
|
|
{
|
|
G4bool good = true;
|
|
|
|
G4ThreeVector pt[8] ;
|
|
|
|
pt[0]=G4ThreeVector(-fDz*fTthetaCphi-fDy1*fTalpha1-fDx1,-fDz*fTthetaSphi-fDy1,-fDz);
|
|
pt[1]=G4ThreeVector(-fDz*fTthetaCphi-fDy1*fTalpha1+fDx1,-fDz*fTthetaSphi-fDy1,-fDz);
|
|
pt[2]=G4ThreeVector(-fDz*fTthetaCphi+fDy1*fTalpha1-fDx2,-fDz*fTthetaSphi+fDy1,-fDz);
|
|
pt[3]=G4ThreeVector(-fDz*fTthetaCphi+fDy1*fTalpha1+fDx2,-fDz*fTthetaSphi+fDy1,-fDz);
|
|
pt[4]=G4ThreeVector(+fDz*fTthetaCphi-fDy2*fTalpha2-fDx3,+fDz*fTthetaSphi-fDy2,+fDz);
|
|
pt[5]=G4ThreeVector(+fDz*fTthetaCphi-fDy2*fTalpha2+fDx3,+fDz*fTthetaSphi-fDy2,+fDz);
|
|
pt[6]=G4ThreeVector(+fDz*fTthetaCphi+fDy2*fTalpha2-fDx4,+fDz*fTthetaSphi+fDy2,+fDz);
|
|
pt[7]=G4ThreeVector(+fDz*fTthetaCphi+fDy2*fTalpha2+fDx4,+fDz*fTthetaSphi+fDy2,+fDz);
|
|
// Bottom side with normal approx. -Y
|
|
good=MakePlane(pt[0],pt[4],pt[5],pt[1],fPlanes[0]);
|
|
if (!good)
|
|
{
|
|
G4Exception("G4PTrap::G4PTrap - face at ~-Y not planar");
|
|
}
|
|
// Top side with normal approx. +Y
|
|
good=MakePlane(pt[2],pt[3],pt[7],pt[6],fPlanes[1]);
|
|
if (!good)
|
|
{
|
|
G4Exception("G4PTrap::G4PTrap - face at ~+Y not planar");
|
|
}
|
|
// Front side with normal approx. -X
|
|
good=MakePlane(pt[0],pt[2],pt[6],pt[4],fPlanes[2]);
|
|
if (!good)
|
|
{
|
|
G4Exception("G4PTrap::G4PTrap - face at ~-X not planar");
|
|
}
|
|
// Back side iwth normal approx. +X
|
|
good=MakePlane(pt[1],pt[5],pt[7],pt[3],fPlanes[3]);
|
|
if (!good)
|
|
{
|
|
G4Exception("G4PTrap::G4PTrap - face at ~+X not planar");
|
|
}
|
|
return good;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
// Calculate the coef's of the plane p1->p2->p3->p4->p1
|
|
// where the ThreeVectors 1-4 are in anti-clockwise order when viewed from
|
|
// infront of the plane.
|
|
//
|
|
// Return true if the ThreeVectors are coplanar + set coef;s
|
|
// false if ThreeVectors are not coplanar
|
|
|
|
G4bool G4PTrap::MakePlane( const G4ThreeVector& p1,
|
|
const G4ThreeVector& p2,
|
|
const G4ThreeVector& p3,
|
|
const G4ThreeVector& p4,
|
|
PTrapSidePlane& plane )
|
|
{
|
|
G4double a,b,c,s;
|
|
G4ThreeVector v12,v13,v14,Vcross;
|
|
|
|
G4bool good;
|
|
|
|
v12 = p2-p1;
|
|
v13 = p3-p1;
|
|
v14 = p4-p1;
|
|
Vcross=v12.cross(v13);
|
|
|
|
if (fabs(Vcross.dot(v14)/(Vcross.mag()*v14.mag()))>kCoplanar_Tolerance)
|
|
{
|
|
good=false;
|
|
}
|
|
else
|
|
{
|
|
|
|
// a,b,c correspond to the x/y/z components of the normal vector to the plane
|
|
|
|
// a=(p2.y()-p1.y())*(p1.z()+p2.z())+(p3.y()-p2.y())*(p2.z()+p3.z());
|
|
// a+=(p4.y()-p3.y())*(p3.z()+p4.z())+(p1.y()-p4.y())*(p4.z()+p1.z()); // may be delete ?
|
|
|
|
// b=(p2.z()-p1.z())*(p1.x()+p2.x())+(p3.z()-p2.z())*(p2.x()+p3.x());
|
|
// b+=(p4.z()-p3.z())*(p3.x()+p4.x())+(p1.z()-p4.z())*(p4.x()+p1.x()); // ?
|
|
|
|
// c=(p2.x()-p1.x())*(p1.y()+p2.y())+(p3.x()-p2.x())*(p2.y()+p3.y());
|
|
// c+=(p4.x()-p3.x())*(p3.y()+p4.y())+(p1.x()-p4.x())*(p4.y()+p1.y()); // ?
|
|
// Let create diagonals 4-2 and 3-1 than (4-2)x(3-1) provides vector perpendicular to the
|
|
// plane directed to outside !!! and a,b,c, = f(1,2,3,4)
|
|
a = +(p4.y() - p2.y())*(p3.z() - p1.z()) - (p3.y() - p1.y())*(p4.z() - p2.z()) ;
|
|
b = -(p4.x() - p2.x())*(p3.z() - p1.z()) + (p3.x() - p1.x())*(p4.z() - p2.z()) ;
|
|
c = +(p4.x() - p2.x())*(p3.y() - p1.y()) - (p3.x() - p1.x())*(p4.y() - p2.y()) ;
|
|
s=sqrt(a*a+b*b+c*c); // so now vector plane.(a,b,c) is unit
|
|
plane.a=a/s;
|
|
plane.b=b/s;
|
|
plane.c=c/s;
|
|
// Calculate D: p1 in in plane so D=-n.p1.Vect()
|
|
|
|
plane.d=-(plane.a*p1.x()+plane.b*p1.y()+plane.c*p1.z());
|
|
good=true;
|
|
}
|
|
return good;
|
|
}
|
|
|
|
|
|
// ******************************** End of G4PTrap.cc ********************************
|
|
|
|
|
|
|
|
|
|
|