#include "Riostream.h"
#include "TGeoHalfSpace.h"
#include "TMath.h"
ClassImp(TGeoHalfSpace)
TGeoHalfSpace::TGeoHalfSpace()
{
SetShapeBit(TGeoShape::kGeoHalfSpace);
SetShapeBit(TGeoShape::kGeoInvalidShape);
memset(fP, 0, 3*sizeof(Double_t));
memset(fN, 0, 3*sizeof(Double_t));
}
TGeoHalfSpace::TGeoHalfSpace(const char *name, Double_t *p, Double_t *n)
:TGeoBBox(name, 0,0,0)
{
SetShapeBit(TGeoShape::kGeoHalfSpace);
SetShapeBit(TGeoShape::kGeoInvalidShape);
Double_t param[6];
memcpy(param, p, 3*sizeof(Double_t));
memcpy(¶m[3], n, 3*sizeof(Double_t));
SetDimensions(param);
}
TGeoHalfSpace::TGeoHalfSpace(Double_t *param)
:TGeoBBox(0,0,0)
{
SetShapeBit(TGeoShape::kGeoHalfSpace);
SetShapeBit(TGeoShape::kGeoInvalidShape);
SetDimensions(param);
}
TGeoHalfSpace::~TGeoHalfSpace()
{
}
void TGeoHalfSpace::ComputeNormal(Double_t * , Double_t *dir, Double_t *norm)
{
memcpy(norm, fN, 3*sizeof(Double_t));
if (norm[0]*dir[0]+norm[1]*dir[1]+norm[2]*dir[2]<0) {
norm[0] = -norm[0];
norm[1] = -norm[1];
norm[2] = -norm[2];
}
}
Bool_t TGeoHalfSpace::Contains(Double_t *point) const
{
Double_t r[3];
r[0] = fP[0]-point[0];
r[1] = fP[1]-point[1];
r[2] = fP[2]-point[2];
Double_t rdotn = r[0]*fN[0]+r[1]*fN[1]+r[2]*fN[2];
if (rdotn < 0) return kFALSE;
return kTRUE;
}
Int_t TGeoHalfSpace::DistancetoPrimitive(Int_t , Int_t )
{
return 999;
}
Double_t TGeoHalfSpace::DistFromInside(Double_t *point, Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
{
Double_t r[3];
r[0] = fP[0]-point[0];
r[1] = fP[1]-point[1];
r[2] = fP[2]-point[2];
Double_t rdotn = r[0]*fN[0]+r[1]*fN[1]+r[2]*fN[2];
if (iact<3 && safe) {
*safe = rdotn;
if (iact==0) return TGeoShape::Big();
if ((iact==1) && (*safe>step)) return TGeoShape::Big();
}
Double_t snxt = TGeoShape::Big();
Double_t ddotn = dir[0]*fN[0]+dir[1]*fN[1]+dir[2]*fN[2];
if (TMath::Abs(ddotn)<TGeoShape::Tolerance()) return snxt;
snxt = rdotn/ddotn;
if (snxt<0) return TGeoShape::Big();
return snxt;
}
Double_t TGeoHalfSpace::DistFromOutside(Double_t *point, Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
{
Double_t r[3];
r[0] = fP[0]-point[0];
r[1] = fP[1]-point[1];
r[2] = fP[2]-point[2];
Double_t rdotn = r[0]*fN[0]+r[1]*fN[1]+r[2]*fN[2];
if (iact<3 && safe) {
*safe = -rdotn;
if (iact==0) return TGeoShape::Big();
if ((iact==1) && (step<*safe)) return TGeoShape::Big();
}
Double_t snxt = TGeoShape::Big();
Double_t ddotn = dir[0]*fN[0]+dir[1]*fN[1]+dir[2]*fN[2];
if (TMath::Abs(ddotn)<TGeoShape::Tolerance()) return snxt;
snxt = rdotn/ddotn;
if (snxt<0) return TGeoShape::Big();
return snxt;
}
TGeoVolume *TGeoHalfSpace::Divide(TGeoVolume * , const char * , Int_t , Int_t ,
Double_t , Double_t )
{
Error("Divide", "Half-spaces cannot be divided");
return 0;
}
void TGeoHalfSpace::GetMeshNumbers(Int_t &nvert, Int_t &nsegs, Int_t &npols) const
{
nvert = 0;
nsegs = 0;
npols = 0;
}
void TGeoHalfSpace::InspectShape() const
{
printf("*** Shape %s: TGeoHalfSpace ***\n", GetName());
printf(" Point : %11.5f, %11.5f, %11.5f\n", fP[0], fP[1], fP[2]);
printf(" Normal : %11.5f, %11.5f, %11.5f\n", fN[0], fN[1], fN[2]);
}
Double_t TGeoHalfSpace::Safety(Double_t *point, Bool_t ) const
{
Double_t r[3];
r[0] = fP[0]-point[0];
r[1] = fP[1]-point[1];
r[2] = fP[2]-point[2];
Double_t rdotn = r[0]*fN[0]+r[1]*fN[1]+r[2]*fN[2];
return TMath::Abs(rdotn);
}
void TGeoHalfSpace::SavePrimitive(ostream &out, Option_t * )
{
if (TObject::TestBit(kGeoSavePrimitive)) return;
out << " // Shape: " << GetName() << " type: " << ClassName() << endl;
out << " point[0] = " << fP[0] << ";" << endl;
out << " point[1] = " << fP[1] << ";" << endl;
out << " point[2] = " << fP[2] << ";" << endl;
out << " norm[0] = " << fN[0] << ";" << endl;
out << " norm[1] = " << fN[1] << ";" << endl;
out << " norm[2] = " << fN[2] << ";" << endl;
out << " TGeoShape *" << GetPointerName() << " = new TGeoHalfSpace(\"" << GetName() << "\", point,norm);" << endl;
TObject::SetBit(TGeoShape::kGeoSavePrimitive);
}
void TGeoHalfSpace::SetDimensions(Double_t *param)
{
memcpy(fP, param, 3*sizeof(Double_t));
memcpy(fN, ¶m[3], 3*sizeof(Double_t));
Double_t nsq = TMath::Sqrt(fN[0]*fN[0]+fN[1]*fN[1]+fN[2]*fN[2]);
fN[0] /= nsq;
fN[1] /= nsq;
fN[2] /= nsq;
}