68 TGeoXtru::ThreadData_t::ThreadData_t() :
69 fSeg(0), fIz(0), fXc(0), fYc(0), fPoly(0)
125 std::vector<ThreadData_t*>::iterator i =
fThreadData.begin();
143 for (
Int_t tid=0; tid<nthreads; tid++) {
155 Error(
"DefinePolygon",
"Shape %s of type XTRU has an illegal polygon.",
GetName());
216 Error(
"ctor",
"Cannot create TGeoXtru %s with less than 2 Z planes",
GetName());
299 if (
fX) {
delete[]
fX;
fX = 0;}
300 if (
fY) {
delete[]
fY;
fY = 0;}
301 if (
fZ) {
delete[]
fZ;
fZ = 0;}
320 for (iz=0; iz<
fNz-1; iz++) {
321 dz =
fZ[iz+1]-
fZ[iz];
325 capacity += (area*dz/3.)*(sc1*sc1+sc1*sc2+sc2*sc2);
337 Error(
"ComputeBBox",
"In shape %s polygon not defined",
GetName());
350 if (td.
fXc[j]<xmin) xmin=td.
fXc[j];
351 if (td.
fXc[j]>xmax) xmax=td.
fXc[j];
352 if (td.
fYc[j]<ymin) ymin=td.
fYc[j];
353 if (td.
fYc[j]>ymax) ymax=td.
fYc[j];
361 fDZ = 0.5*(zmax-zmin);
372 norm[2] = (dir[2]>0)?1:-1;
378 Double_t ndotd = norm[0]*dir[0]+norm[1]*dir[1]+norm[2]*dir[2];
449 snext = (
fZ[iz]-point[2])/dir[2];
451 pt[0] = point[0]+snext*dir[0];
452 pt[1] = point[1]+snext*dir[1];
453 pt[2] = point[2]+snext*dir[2];
461 Double_t ndotd = norm[0]*dir[0]+norm[1]*dir[1]+norm[2]*dir[2];
464 safe = (vert[0]-point[0])*norm[0]+
465 (vert[1]-point[1])*norm[1]+
466 (vert[2]-point[2])*norm[2];
471 safe = (point[0]-vert[0])*norm[0]+
472 (point[1]-vert[1])*norm[1]+
473 (point[2]-vert[2])*norm[2];
478 if (
fZ[iz]<
fZ[iz+1]) {
479 znew = point[2] + snext*dir[2];
483 pt[0] = point[0]+snext*dir[0];
484 pt[1] = point[1]+snext*dir[1];
485 pt[2] = point[2]+snext*dir[2];
497 if (iact<3 && safe) {
531 Int_t iv, ipl, inext;
534 for (iv=0; iv<
fNvert; iv++) {
540 if (convex)
return snext;
543 if (snext < 1.E10)
return snext;
548 Int_t incseg = (dir[2]>0)?1:-1;
551 while (iz>=0 && iz<
fNz-1) {
553 ipl = iz+((incseg+1)>>1);
555 sz = (
fZ[ipl]-point[2])/dir[2];
559 pt[0] = point[0]+sz*dir[0];
560 pt[1] = point[1]+sz*dir[1];
564 if (ipl==0 || ipl==
fNz-1) {
566 if (convex)
return sz;
576 if (convex)
return sz;
588 for (iv=0; iv<
fNvert; iv++) {
594 if (convex)
return snext;
598 if (zexit)
return snext;
611 if (iact<3 && safe) {
625 memcpy(pt,point,3*
sizeof(
Double_t));
632 snext = (
fZ[0] - point[2])/dir[2];
634 for (i=0; i<3; i++) pt[i] = point[i] + snext*dir[i];
646 snext = (
fZ[
fNz-1] - point[2])/dir[2];
648 for (i=0; i<3; i++) pt[i] = point[i] + snext*dir[i];
662 if (dist>1
E-6) dist-=1
E-6;
664 for (i=0; i<3; i++) pt[i] += dist*dir[i];
667 else if (iz==
fNz-1) iz =
fNz-2;
679 for (iv=0; iv<
fNvert; iv++) {
683 if (convex)
return (snext+dist);
688 if (hit)
return (snext+stepmax);
692 Int_t incseg = (dir[2]>0)?1:-1;
693 while (iz>=0 && iz<
fNz-1) {
697 for (iv=0; iv<
fNvert; iv++) {
702 if (convex)
return (snext+dist);
707 if (hit)
return (snext+stepmax);
723 Error(
"DefinePolygon",
"In shape %s cannot create polygon with less than 3 vertices",
GetName());
727 for (
Int_t i=0; i<nvert-1; i++) {
728 for (
Int_t j=i+1; j<nvert; j++) {
731 Error(
"DefinePolygon",
"In shape %s 2 vertices cannot be identical",
GetName());
738 if (
fX)
delete []
fX;
740 if (
fY)
delete []
fY;
755 if ((snum<0) || (snum>=
fNz))
return;
761 if (
fZ[snum]<
fZ[snum-1]) {
762 Warning(
"DefineSection",
"In shape: %s, Z position of section "
763 "%i, z=%e, not in increasing order, %i, z=%e",
779 if (ipl<0 || ipl>(
fNz-1)) {
780 Error(
"GetZ",
"In shape %s, ipl=%i out of range (0,%i)",
GetName(),ipl,
fNz-1);
793 v1[0] = vert[9]-vert[0];
794 v1[1] = vert[10]-vert[1];
795 v1[2] = vert[11]-vert[2];
796 v2[0] = vert[3]-vert[0];
797 v2[1] = vert[4]-vert[1];
798 v2[2] = vert[5]-vert[2];
799 norm[0] = v1[1]*v2[2]-v1[2]*v2[1];
800 cross += norm[0]*norm[0];
801 norm[1] = v1[2]*v2[0]-v1[0]*v2[2];
802 cross += norm[1]*norm[1];
803 norm[2] = v1[0]*v2[1]-v1[1]*v2[0];
804 cross += norm[2]*norm[2];
807 for (
Int_t i=0; i<3; i++) norm[i] *= cross;
838 x =
fX[ivert]*
fScale[iz+1]+fX0[iz+1];
839 y =
fY[ivert]*
fScale[iz+1]+fY0[iz+1];
854 x =
fX[ivert]*
fScale[iz+1]+fX0[iz+1];
855 y =
fY[ivert]*
fScale[iz+1]+fY0[iz+1];
874 for (
Int_t i=0; i<4; i++) {
877 v1[0] = point[0]-vert[j];
878 v1[1] = point[1]-vert[j+1];
879 v1[2] = point[2]-vert[j+2];
880 v2[0] = vert[k]-vert[j];
881 v2[1] = vert[k+1]-vert[j+1];
882 v2[2] = vert[k+2]-vert[j+2];
883 cross = (v1[1]*v2[2]-v1[2]*v2[1])*norm[0]+
884 (v1[2]*v2[0]-v1[0]*v2[2])*norm[1]+
885 (v1[0]*v2[1]-v1[1]*v2[0])*norm[2];
886 if (cross<0)
return kFALSE;
898 printf(
" List of (x,y) of polygon vertices:\n");
900 printf(
" x = %11.5f y = %11.5f\n",
fX[ivert],
fY[ivert]);
902 printf(
" plane %i: z=%11.5f x0=%11.5f y0=%11.5f scale=%11.5f\n", ipl,
fZ[ipl],
fX0[ipl],
fY0[ipl],
fScale[ipl]);
903 printf(
" Bounding box:\n");
915 Int_t nbPnts = nz*nvert;
916 Int_t nbSegs = nvert*(2*nz-1);
917 Int_t nbPols = nvert*(nz-1)+2;
920 nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, nbPols, 6*(nbPols-2)+2*(2+nvert));
940 Int_t indx, indx2, k;
942 for (i=0; i<nz; i++) {
946 for (j=0; j<nvert; j++) {
949 buff.
fSegs[indx++] = indx2+j;
950 buff.
fSegs[indx++] = indx2+k;
953 for (i=0; i<nz-1; i++) {
957 for (j=0; j<nvert; j++) {
960 buff.
fSegs[indx++] = indx2+j;
961 buff.
fSegs[indx++] = indx2+k;
968 for (i=0; i<nz-1; i++) {
970 for (j=0; j<nvert; j++) {
972 buff.
fPols[indx++] = c+j%3;
973 buff.
fPols[indx++] = 4;
974 buff.
fPols[indx++] = indx2+j;
975 buff.
fPols[indx++] = nz*nvert+indx2+k;
976 buff.
fPols[indx++] = indx2+nvert+j;
977 buff.
fPols[indx++] = nz*nvert+indx2+j;
980 buff.
fPols[indx++] = c+2;
981 buff.
fPols[indx++] = nvert;
983 for (j = nvert - 1; j >= 0; --j) {
984 buff.
fPols[indx++] = indx2+j;
988 buff.
fPols[indx++] = nvert;
989 indx2 = (nz-1)*nvert;
991 for (j=0; j<nvert; j++) {
992 buff.
fPols[indx++] = indx2+j;
1018 if ((in1&!in2)|(in2&!in1)) {
1028 safz =
fZ[iz]-point[2];
1031 saf1 = point[2]-
fZ[iz+1];
1045 for (iseg=0; iseg<
fNvert; iseg++) {
1048 saf1 = (point[0]-vert[0])*norm[0]+(point[1]-vert[1])*norm[1]+(point[2]-vert[2])*norm[2];
1049 if (in) saf1 = -saf1;
1051 if (saf1<-1.
E-8)
continue;
1054 if (safe>safmin)
continue;
1058 if (found)
return safmin;
1076 for (iz=0; iz<
fNz-1; iz++) {
1078 if (safe<safmin) safmin = safe;
1087 safz =
fZ[0] - point[2];
1091 safz = point[2] -
fZ[
fNz-1];
1096 for (i=iz; i<
fNz-1; i++) {
1098 if (safe<safmin) safmin=safe;
1101 for (i=iz-1; i>=0; i--) {
1103 if (safe<safmin) safmin=safe;
1115 out <<
" // Shape: " <<
GetName() <<
" type: " <<
ClassName() << std::endl;
1116 out <<
" nz = " <<
fNz <<
";" << std::endl;
1117 out <<
" nvert = " <<
fNvert <<
";" << std::endl;
1118 out <<
" TGeoXtru *xtru = new TGeoXtru(nz);" << std::endl;
1119 out <<
" xtru->SetName(\"" <<
GetName() <<
"\");" << std::endl;
1121 for (i=0; i<
fNvert; i++) {
1122 out <<
" xvert[" << i <<
"] = " <<
fX[i] <<
"; yvert[" << i <<
"] = " <<
fY[i] <<
";" << std::endl;
1124 out <<
" xtru->DefinePolygon(nvert,xvert,yvert);" << std::endl;
1125 for (i=0; i<
fNz; i++) {
1126 out <<
" zsect = " <<
fZ[i] <<
";" << std::endl;
1127 out <<
" x0 = " <<
fX0[i] <<
";" << std::endl;
1128 out <<
" y0 = " <<
fY0[i] <<
";" << std::endl;
1129 out <<
" scale0 = " <<
fScale[i] <<
";" << std::endl;
1130 out <<
" xtru->DefineSection(" << i <<
",zsect,x0,y0,scale0);" << std::endl;
1132 out <<
" TGeoShape *" <<
GetPointerName() <<
" = xtru;" << std::endl;
1146 a = (
fX0[ind1]*
fZ[ind2]-
fX0[ind2]*
fZ[ind1])*invdz;
1147 b = (
fX0[ind2]-
fX0[ind1])*invdz;
1149 a = (
fY0[ind1]*
fZ[ind2]-
fY0[ind2]*
fZ[ind1])*invdz;
1150 b = (
fY0[ind2]-
fY0[ind1])*invdz;
1165 td.
fXc[i] = scale*
fX[i] + x0;
1166 td.
fYc[i] = scale*
fY[i] + y0;
1187 Error(
"SetDimensions",
"Cannot create TGeoXtru %s with less than 2 Z planes",
GetName());
1191 if (
fZ)
delete []
fZ;
1201 DefineSection(i, param[1+4*i], param[2+4*i], param[3+4*i], param[4+4*i]);
1214 for (i = 0; i <
fNz; i++) {
1217 for (j = 0; j <
fNvert; j++) {
1218 points[indx++] = td.
fXc[j];
1219 points[indx++] = td.
fYc[j];
1220 points[indx++] =
fZ[i];
1223 for (j = 0; j <
fNvert; j++) {
1224 points[indx++] = td.
fXc[fNvert-1-j];
1225 points[indx++] = td.
fYc[fNvert-1-j];
1226 points[indx++] =
fZ[i];
1243 for (i = 0; i <
fNz; i++) {
1246 for (j = 0; j <
fNvert; j++) {
1247 points[indx++] = td.
fXc[j];
1248 points[indx++] = td.
fYc[j];
1249 points[indx++] =
fZ[i];
1252 for (j = 0; j <
fNvert; j++) {
1253 points[indx++] = td.
fXc[fNvert-1-j];
1254 points[indx++] = td.
fYc[fNvert-1-j];
1255 points[indx++] =
fZ[i];
1270 nsegs = nv*(2*nz-1);
1271 npols = nv*(nz-1)+2;
1309 Int_t nbPnts = nz*nvert;
1310 Int_t nbSegs = nvert*(2*nz-1);
1311 Int_t nbPols = nvert*(nz-1)+2;
1312 if (buffer.
SetRawSizes(nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, nbPols, 6*(nbPols-2)+2*(2+nvert))) {
1337 for (
Int_t i=0; i<vecsize; i++) inside[i] =
Contains(&points[3*i]);
1347 for (
Int_t i=0; i<vecsize; i++)
ComputeNormal(&points[3*i], &dirs[3*i], &norms[3*i]);
1355 for (
Int_t i=0; i<vecsize; i++) dists[i] =
DistFromInside(&points[3*i], &dirs[3*i], 3, step[i]);
1363 for (
Int_t i=0; i<vecsize; i++) dists[i] =
DistFromOutside(&points[3*i], &dirs[3*i], 3, step[i]);
1373 for (
Int_t i=0; i<vecsize; i++) safe[i] =
Safety(&points[3*i], inside[i]);
Double_t Area() const
Computes area of the polygon in [length^2].
void SetSeg(Int_t iseg)
Set current segment.
virtual void Draw(Option_t *option="")
Draw the polygon.
double dist(Rotation3D const &r1, Rotation3D const &r2)
#define snext(osub1, osub2)
virtual void ComputeNormal_v(const Double_t *points, const Double_t *dirs, Double_t *norms, Int_t vecsize)
Compute the normal for an array o points so that norm.dot.dir is positive Input: Arrays of point coor...
TVector3 cross(const TVector3 &v1, const TVector3 &v2)
Int_t GetBasicColor() const
Get the basic color (0-7).
virtual void DefineSection(Int_t snum, Double_t z, Double_t x0=0., Double_t y0=0., Double_t scale=1.)
defines z position of a section plane, rmin and rmax at this z.
virtual void SetDimensions(Double_t *param)
param[0] = nz // number of z planes
Short_t Min(Short_t a, Short_t b)
virtual void Safety_v(const Double_t *points, const Bool_t *inside, Double_t *safe, Int_t vecsize) const
Compute safe distance from each of the points in the input array.
virtual void CreateThreadData(Int_t nthreads)
Create thread data for n threads max.
virtual Double_t Safety(const Double_t *point, Bool_t in=kTRUE) const
computes the closest distance from given point to this shape, according to option.
virtual Double_t DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=0) const
Compute distance from outside point to surface of the box.
static Bool_t IsSameWithinTolerance(Double_t a, Double_t b)
Check if two numbers differ with less than a tolerance.
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
static Double_t Tolerance()
Bool_t IsIllegalCheck() const
Check for illegal crossings between non-consecutive segments.
void SetCurrentVertices(Double_t x0, Double_t y0, Double_t scale)
Set current vertex coordinates according X0, Y0 and SCALE.
Double_t SafetyToSector(const Double_t *point, Int_t iz, Double_t safmin, Bool_t in)
Compute safety to sector iz, returning also the closest segment index.
std::vector< ThreadData_t * > fThreadData
virtual void SetPoints(Double_t *points) const
create polycone mesh points
Double_t DistToPlane(const Double_t *point, const Double_t *dir, Int_t iz, Int_t ivert, Double_t stepmax, Bool_t in) const
Compute distance to a Xtru lateral surface.
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
void SetSectionsValid(UInt_t mask)
virtual void GetMeshNumbers(Int_t &nvert, Int_t &nsegs, Int_t &npols) const
Returns numbers of vertices, segments and polygons composing the shape mesh.
virtual TBuffer3D * MakeBuffer3D() const
Creates a TBuffer3D describing this shape.
virtual void Sizeof3D() const
virtual Int_t GetNmeshVertices() const
Return number of vertices of the mesh representation.
virtual ~TGeoXtru()
destructor
void TransformPoints(Double_t *points, UInt_t NbPoints) const
Tranform a set of points (LocalToMaster)
virtual void DistFromOutside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t *step) const
Compute distance from array of input points having directions specisied by dirs. Store output in dist...
virtual void InspectShape() const
Print actual Xtru parameters.
TNamed & operator=(const TNamed &rhs)
TNamed assignment operator.
virtual Double_t Capacity() const
Compute capacity [length^3] of this shape.
virtual Bool_t Contains(const Double_t *point) const
test if point is inside this shape
void SetXY(Double_t *x, Double_t *y)
Set X/Y array pointer for the polygon and daughters.
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Bool_t TestBit(UInt_t f) const
void GetPlaneVertices(Int_t iz, Int_t ivert, Double_t *vert) const
Returns (x,y,z) of 3 vertices of the surface defined by Z sections (iz, iz+1) and polygon vertices (i...
Bool_t SetRawSizes(UInt_t reqPnts, UInt_t reqPntsCapacity, UInt_t reqSegs, UInt_t reqSegsCapacity, UInt_t reqPols, UInt_t reqPolsCapacity)
Set kRaw tessellation section of buffer with supplied sizes.
Generic 3D primitive description class.
void SetCurrentZ(Double_t z, Int_t iz)
Recompute current section vertices for a given Z position within range of section iz...
virtual Double_t Safety(const Double_t *point, Bool_t in=kTRUE) const
Computes the closest distance from given point to this shape.
static Int_t Lock()
Static method to lock the main thread mutex.
virtual const char * GetName() const
Get the shape name.
virtual void ComputeBBox()
compute bounding box of the pcon
static Int_t UnLock()
Static method to unlock the main thread mutex.
virtual void InspectShape() const
Prints shape parameters.
Double_t Safety(const Double_t *point, Int_t &isegment) const
Compute minimum distance from POINT to any segment. Returns segment index.
virtual void FillBuffer3D(TBuffer3D &buffer, Int_t reqSections, Bool_t localFrame) const
Fills the supplied buffer, with sections in desired frame See TBuffer3D.h for explanation of sections...
virtual void ClearThreadData() const
ClassImp(TMCParticle) void TMCParticle printf(": p=(%7.3f,%7.3f,%9.3f) ;", fPx, fPy, fPz)
void FinishPolygon()
Decompose polygon in a convex outscribed part and a list of daughter polygons that have to be substra...
~ThreadData_t()
Destructor.
ThreadData_t & GetThreadData() const
Int_t ShapeDistancetoPrimitive(Int_t numpoints, Int_t px, Int_t py) const
Returns distance to shape primitive mesh.
virtual const TBuffer3D & GetBuffer3D(Int_t reqSections, Bool_t localFrame) const
Fills a static 3D buffer and returns a reference.
void DrawPolygon(Option_t *option="")
Draw the section polygon.
const char * GetPointerName() const
Provide a pointer name containing uid.
Bool_t IsClockwise() const
virtual void Contains_v(const Double_t *points, Bool_t *inside, Int_t vecsize) const
Check the inside status for each of the points in the array.
void GetPlaneNormal(const Double_t *vert, Double_t *norm) const
Returns normal vector to the planar quadrilateral defined by vector VERT.
virtual Int_t DistancetoPrimitive(Int_t px, Int_t py)
compute closest distance from point px,py to each corner
TGeoXtru & operator=(const TGeoXtru &)
assignment operator
void SetIz(Int_t iz)
Set current z-plane.
void SetShapeBit(UInt_t f, Bool_t set)
Equivalent of TObject::SetBit.
virtual void DistFromInside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t *step) const
Compute distance from array of input points having directions specisied by dirs. Store output in dist...
virtual Double_t DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=0) const
compute distance from outside point to surface of the tube Warning("DistFromOutside", "not implemented");
Bool_t TestShapeBit(UInt_t f) const
static Int_t ThreadId()
Translates the current thread id to an ordinal number.
Short_t Max(Short_t a, Short_t b)
Bool_t Contains(const Double_t *point) const
Check if a point given by X = point[0], Y = point[1] is inside the polygon.
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
Int_t fThreadSize
Navigation data per thread.
Double_t Sqrt(Double_t x)
double norm(double *x, double *p)
virtual void ComputeNormal(const Double_t *point, const Double_t *dir, Double_t *norm)
Compute normal to closest surface from POINT.
virtual Bool_t Contains(const Double_t *point) const
Test if point is inside this shape.
Long64_t BinarySearch(Long64_t n, const T *array, T value)
Bool_t DefinePolygon(Int_t nvert, const Double_t *xv, const Double_t *yv)
Creates the polygon representing the blueprint of any Xtru section.
virtual void SetSegsAndPols(TBuffer3D &buff) const
Fill TBuffer3D structure for segments and polygons.
Bool_t SectionsValid(UInt_t mask) const
ClassImp(TGeoXtru) TGeoXtru
Constructor.
Bool_t IsPointInsidePlane(const Double_t *point, Double_t *vert, Double_t *norm) const
Check if the quadrilateral defined by VERT contains a coplanar POINT.
virtual Double_t DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact=1, Double_t step=TGeoShape::Big(), Double_t *safe=0) const
compute distance from inside point to surface of the polycone locate Z segment
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.