248 lines
6.2 KiB
C++
248 lines
6.2 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: G4Ray.cc,v 1.6.2.1 2001/06/28 19:08:53 gunter Exp $
|
|
// GEANT4 tag $Name: $
|
|
//
|
|
// ----------------------------------------------------------------------
|
|
// GEANT 4 class source file
|
|
//
|
|
// G4Ray.cc
|
|
//
|
|
// ----------------------------------------------------------------------
|
|
|
|
#include "G4Ray.hh"
|
|
#include "G4PointRat.hh"
|
|
|
|
G4Ray::G4Ray()
|
|
{
|
|
}
|
|
|
|
G4Ray::G4Ray(const G4Point3D& start0, const G4Vector3D& dir0)
|
|
{
|
|
Init(start0, dir0);
|
|
}
|
|
|
|
G4Ray::~G4Ray()
|
|
{
|
|
}
|
|
|
|
|
|
const G4Plane& G4Ray::GetPlane(G4int number_of_plane) const
|
|
{
|
|
if(number_of_plane==1)
|
|
return plane2;
|
|
else
|
|
return plane1;
|
|
}
|
|
|
|
|
|
void G4Ray::CreatePlanes()
|
|
{
|
|
// Creates two orthogonal planes(plane1,plane2) the ray (rray)
|
|
// situated in the intersection of the planes. The planes are
|
|
// used to project the surface (nurb) in two dimensions.
|
|
|
|
G4Vector3D RayDir = dir;
|
|
G4Point3D RayOrigin = start;
|
|
|
|
G4Point3D p1, p2, p3, p4;
|
|
G4Vector3D dir1, dir2;
|
|
G4Vector3D invdir = G4Vector3D( PINFINITY );
|
|
|
|
if(!NearZero(RayDir.x(), SQRT_SMALL_FASTF))
|
|
invdir.setX(1.0 / RayDir.x());
|
|
|
|
if(!NearZero(RayDir.y(), SQRT_SMALL_FASTF))
|
|
invdir.setY(1.0 / RayDir.y());
|
|
|
|
if(!NearZero(RayDir.z(), SQRT_SMALL_FASTF))
|
|
invdir.setZ(1.0 / RayDir.z());
|
|
|
|
MatVecOrtho(dir1, RayDir);
|
|
|
|
Vcross( dir2, RayDir, dir1);
|
|
Vmove(p1, RayOrigin);
|
|
Vadd2(p2, RayOrigin, RayDir);
|
|
Vadd2(p3, RayOrigin, dir1);
|
|
Vadd2(p4, RayOrigin, dir2);
|
|
|
|
CalcPlane3Pts( plane1, p1, p3, p2);
|
|
CalcPlane3Pts( plane2, p1, p2, p4);
|
|
}
|
|
|
|
|
|
void G4Ray::MatVecOrtho(register G4Vector3D &out,
|
|
register const G4Vector3D in )
|
|
{
|
|
register G4double f;
|
|
G4int i_Which;
|
|
|
|
if(NearZero(in.x(), 0.0001) && NearZero(in.y(), 0.0001) &&
|
|
NearZero(in.z(), 0.0001) )
|
|
{
|
|
Vsetall( out, 0 );
|
|
return;
|
|
}
|
|
|
|
// Find component closest to zero
|
|
f = fabs(in.x());
|
|
i_Which=0;
|
|
|
|
if( fabs(in.y()) < f )
|
|
{
|
|
f = fabs(in.y());
|
|
i_Which=1;
|
|
}
|
|
|
|
if( fabs(in.z()) < f )
|
|
i_Which=2;
|
|
|
|
if(!i_Which)
|
|
f = sqrt((in.y())*(in.y())+(in.z())*(in.z())); // hypot(in.y(),in.z())
|
|
else
|
|
if(i_Which==1)
|
|
f = sqrt((in.z())*(in.z())+(in.x())*(in.x())); // hypot(in.z(),in.x())
|
|
else
|
|
f = sqrt((in.x())*(in.x())+(in.y())*(in.y())); // hypot(in.x(),in.y())
|
|
|
|
if( NearZero( f, SMALL ) )
|
|
{
|
|
Vsetall( out, 0 );
|
|
return;
|
|
}
|
|
|
|
f = 1.0/f;
|
|
|
|
if(!i_Which)
|
|
{
|
|
out.setX(0.0);
|
|
out.setY(-in.z()*f);
|
|
out.setZ( in.y()*f);
|
|
}
|
|
else
|
|
if(i_Which==1)
|
|
{
|
|
out.setY(0.0);
|
|
out.setZ(-in.x()*f);
|
|
out.setX( in.y()*f);
|
|
}
|
|
else
|
|
{
|
|
out.setZ(0.0);
|
|
out.setX(-in.z()*f);
|
|
out.setY( in.y()*f);
|
|
}
|
|
}
|
|
|
|
|
|
// CALC_PLANE_3PTS
|
|
//
|
|
// Find the equation of a G4Plane that contains three points.
|
|
// Note that Normal vector created is expected to point out (see vmath.h),
|
|
// so the vector from A to C had better be counter-clockwise
|
|
// (about the point A) from the vector from A to B.
|
|
// This follows the outward-pointing Normal convention, and the
|
|
// right-hand rule for cross products.
|
|
//
|
|
/*
|
|
C
|
|
*
|
|
|\
|
|
| \
|
|
^ N | \
|
|
| \ | \
|
|
| \ | \
|
|
|C-A \ | \
|
|
| \ | \
|
|
| \ | \
|
|
\| \
|
|
*---------*
|
|
A B
|
|
----->
|
|
B-A
|
|
*/
|
|
// If the points are given in the order A B C (eg, *counter*-clockwise),
|
|
// then the outward pointing surface Normal N = (B-A) x (C-A).
|
|
//
|
|
// Explicit Return -
|
|
// 0 OK
|
|
// -1 Failure. At least two of the points were not distinct,
|
|
// or all three were colinear.
|
|
//
|
|
// Implicit Return -
|
|
// G4Plane The G4Plane equation is stored here.
|
|
|
|
|
|
G4int G4Ray::CalcPlane3Pts(G4Plane &plane1,
|
|
const G4Point3D& a,
|
|
const G4Point3D& b,
|
|
const G4Point3D& c )
|
|
{
|
|
// Creates the two orthogonal planes which are needed in projecting the
|
|
// surface into 2D.
|
|
|
|
G4Vector3D B_A;
|
|
G4Vector3D C_A;
|
|
G4Vector3D C_B;
|
|
|
|
register G4double mag;
|
|
|
|
Vsub2( B_A, b, a );
|
|
Vsub2( C_A, c, a );
|
|
Vsub2( C_B, c, b );
|
|
|
|
Vcross( plane1, B_A, C_A );
|
|
|
|
// Ensure unit length Normal
|
|
mag = Magnitude(plane1);
|
|
if( mag <= SQRT_SMALL_FASTF )
|
|
return(-1);// FAIL
|
|
|
|
mag = 1/mag;
|
|
|
|
G4Plane pl2(plane1);
|
|
Vscale( plane1, pl2, mag );
|
|
|
|
// Find distance from the origin to the G4Plane
|
|
plane1.d = Vdot( plane1, a );
|
|
|
|
return(0); //ok
|
|
}
|
|
|
|
|
|
void G4Ray::RayCheck()
|
|
{
|
|
// Check that the ray has a G4Vector3D...
|
|
if (dir==G4Vector3D(0, 0, 0))
|
|
{
|
|
G4cout << "\nZero direction given. Exiting...\n";
|
|
exit(1);
|
|
}
|
|
|
|
// Make sure that the vector is unit length
|
|
dir= dir.unit();
|
|
r_min = 0;
|
|
r_max = 0;
|
|
}
|