76 fSeg(0), fIz(0), fXc(0), fYc(0), fPoly(0)
132 std::vector<ThreadData_t*>::iterator i =
fThreadData.begin();
150 for (
Int_t tid=0; tid<nthreads; tid++) {
162 Error(
"DefinePolygon",
"Shape %s of type XTRU has an illegal polygon.",
GetName());
223 Error(
"ctor",
"Cannot create TGeoXtru %s with less than 2 Z planes",
GetName());
306 if (
fX) {
delete[]
fX;
fX = 0;}
307 if (
fY) {
delete[]
fY;
fY = 0;}
308 if (
fZ) {
delete[]
fZ;
fZ = 0;}
327 for (iz=0; iz<
fNz-1; iz++) {
328 dz =
fZ[iz+1]-
fZ[iz];
332 capacity += (area*dz/3.)*(sc1*sc1+sc1*sc2+sc2*sc2);
344 Error(
"ComputeBBox",
"In shape %s polygon not defined",
GetName());
357 if (td.
fXc[j]<xmin) xmin=td.
fXc[j];
358 if (td.
fXc[j]>xmax) xmax=td.
fXc[j];
359 if (td.
fYc[j]<ymin) ymin=td.
fYc[j];
360 if (td.
fYc[j]>ymax) ymax=td.
fYc[j];
368 fDZ = 0.5*(zmax-zmin);
379 norm[2] = (dir[2]>0)?1:-1;
385 Double_t ndotd = norm[0]*dir[0]+norm[1]*dir[1]+norm[2]*dir[2];
456 snext = (
fZ[iz]-point[2])/dir[2];
458 pt[0] = point[0]+snext*dir[0];
459 pt[1] = point[1]+snext*dir[1];
460 pt[2] = point[2]+snext*dir[2];
468 Double_t ndotd = norm[0]*dir[0]+norm[1]*dir[1]+norm[2]*dir[2];
471 safe = (vert[0]-point[0])*norm[0]+
472 (vert[1]-point[1])*norm[1]+
473 (vert[2]-point[2])*norm[2];
478 safe = (point[0]-vert[0])*norm[0]+
479 (point[1]-vert[1])*norm[1]+
480 (point[2]-vert[2])*norm[2];
485 if (
fZ[iz]<
fZ[iz+1]) {
486 znew = point[2] + snext*dir[2];
490 pt[0] = point[0]+snext*dir[0];
491 pt[1] = point[1]+snext*dir[1];
492 pt[2] = point[2]+snext*dir[2];
504 if (iact<3 && safe) {
538 Int_t iv, ipl, inext;
541 for (iv=0; iv<
fNvert; iv++) {
547 if (convex)
return snext;
550 if (snext < 1.E10)
return snext;
555 Int_t incseg = (dir[2]>0)?1:-1;
558 while (iz>=0 && iz<
fNz-1) {
560 ipl = iz+((incseg+1)>>1);
562 sz = (
fZ[ipl]-point[2])/dir[2];
566 pt[0] = point[0]+sz*dir[0];
567 pt[1] = point[1]+sz*dir[1];
571 if (ipl==0 || ipl==
fNz-1) {
573 if (convex)
return sz;
583 if (convex)
return sz;
595 for (iv=0; iv<
fNvert; iv++) {
601 if (convex)
return snext;
605 if (zexit)
return snext;
618 if (iact<3 && safe) {
632 memcpy(pt,point,3*
sizeof(
Double_t));
639 snext = (
fZ[0] - point[2])/dir[2];
641 for (i=0; i<3; i++) pt[i] = point[i] + snext*dir[i];
653 snext = (
fZ[
fNz-1] - point[2])/dir[2];
655 for (i=0; i<3; i++) pt[i] = point[i] + snext*dir[i];
669 if (dist>1
E-6) dist-=1
E-6;
671 for (i=0; i<3; i++) pt[i] += dist*dir[i];
674 else if (iz==
fNz-1) iz =
fNz-2;
686 for (iv=0; iv<
fNvert; iv++) {
690 if (convex)
return (snext+dist);
695 if (hit)
return (snext+stepmax);
699 Int_t incseg = (dir[2]>0)?1:-1;
700 while (iz>=0 && iz<
fNz-1) {
704 for (iv=0; iv<
fNvert; iv++) {
709 if (convex)
return (snext+dist);
714 if (hit)
return (snext+stepmax);
731 Error(
"DefinePolygon",
"In shape %s cannot create polygon with less than 3 vertices",
GetName());
735 for (
Int_t i=0; i<nvert-1; i++) {
736 for (
Int_t j=i+1; j<nvert; j++) {
739 Error(
"DefinePolygon",
"In shape %s 2 vertices cannot be identical",
GetName());
746 if (
fX)
delete []
fX;
748 if (
fY)
delete []
fY;
763 if ((snum<0) || (snum>=
fNz))
return;
769 if (
fZ[snum]<
fZ[snum-1]) {
770 Warning(
"DefineSection",
"In shape: %s, Z position of section " 771 "%i, z=%e, not in increasing order, %i, z=%e",
787 if (ipl<0 || ipl>(
fNz-1)) {
788 Error(
"GetZ",
"In shape %s, ipl=%i out of range (0,%i)",
GetName(),ipl,
fNz-1);
801 v1[0] = vert[9]-vert[0];
802 v1[1] = vert[10]-vert[1];
803 v1[2] = vert[11]-vert[2];
804 v2[0] = vert[3]-vert[0];
805 v2[1] = vert[4]-vert[1];
806 v2[2] = vert[5]-vert[2];
807 norm[0] = v1[1]*v2[2]-v1[2]*v2[1];
808 cross += norm[0]*norm[0];
809 norm[1] = v1[2]*v2[0]-v1[0]*v2[2];
810 cross += norm[1]*norm[1];
811 norm[2] = v1[0]*v2[1]-v1[1]*v2[0];
812 cross += norm[2]*norm[2];
815 for (
Int_t i=0; i<3; i++) norm[i] *= cross;
846 x =
fX[ivert]*
fScale[iz+1]+fX0[iz+1];
847 y =
fY[ivert]*
fScale[iz+1]+fY0[iz+1];
862 x =
fX[ivert]*
fScale[iz+1]+fX0[iz+1];
863 y =
fY[ivert]*
fScale[iz+1]+fY0[iz+1];
882 for (
Int_t i=0; i<4; i++) {
885 v1[0] = point[0]-vert[j];
886 v1[1] = point[1]-vert[j+1];
887 v1[2] = point[2]-vert[j+2];
888 v2[0] = vert[k]-vert[j];
889 v2[1] = vert[k+1]-vert[j+1];
890 v2[2] = vert[k+2]-vert[j+2];
891 cross = (v1[1]*v2[2]-v1[2]*v2[1])*norm[0]+
892 (v1[2]*v2[0]-v1[0]*v2[2])*norm[1]+
893 (v1[0]*v2[1]-v1[1]*v2[0])*norm[2];
894 if (cross<0)
return kFALSE;
904 printf(
"*** Shape %s: TGeoXtru ***\n",
GetName());
905 printf(
" Nz = %i\n",
fNz);
906 printf(
" List of (x,y) of polygon vertices:\n");
908 printf(
" x = %11.5f y = %11.5f\n",
fX[ivert],
fY[ivert]);
910 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]);
911 printf(
" Bounding box:\n");
923 Int_t nbPnts = nz*nvert;
924 Int_t nbSegs = nvert*(2*nz-1);
925 Int_t nbPols = nvert*(nz-1)+2;
928 nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, nbPols, 6*(nbPols-2)+2*(2+nvert));
948 Int_t indx, indx2, k;
950 for (i=0; i<nz; i++) {
954 for (j=0; j<nvert; j++) {
957 buff.
fSegs[indx++] = indx2+j;
958 buff.
fSegs[indx++] = indx2+k;
961 for (i=0; i<nz-1; i++) {
965 for (j=0; j<nvert; j++) {
968 buff.
fSegs[indx++] = indx2+j;
969 buff.
fSegs[indx++] = indx2+k;
976 for (i=0; i<nz-1; i++) {
978 for (j=0; j<nvert; j++) {
980 buff.
fPols[indx++] = c+j%3;
981 buff.
fPols[indx++] = 4;
982 buff.
fPols[indx++] = indx2+j;
983 buff.
fPols[indx++] = nz*nvert+indx2+k;
984 buff.
fPols[indx++] = indx2+nvert+j;
985 buff.
fPols[indx++] = nz*nvert+indx2+j;
988 buff.
fPols[indx++] = c+2;
989 buff.
fPols[indx++] = nvert;
991 for (j = nvert - 1; j >= 0; --j) {
992 buff.
fPols[indx++] = indx2+j;
996 buff.
fPols[indx++] = nvert;
997 indx2 = (nz-1)*nvert;
999 for (j=0; j<nvert; j++) {
1000 buff.
fPols[indx++] = indx2+j;
1026 if ((in1&!in2)|(in2&!in1)) {
1036 safz =
fZ[iz]-point[2];
1039 saf1 = point[2]-
fZ[iz+1];
1053 for (iseg=0; iseg<
fNvert; iseg++) {
1056 saf1 = (point[0]-vert[0])*norm[0]+(point[1]-vert[1])*norm[1]+(point[2]-vert[2])*norm[2];
1057 if (in) saf1 = -saf1;
1059 if (saf1<-1.
E-8)
continue;
1062 if (safe>safmin)
continue;
1066 if (found)
return safmin;
1084 for (iz=0; iz<
fNz-1; iz++) {
1086 if (safe<safmin) safmin = safe;
1095 safz =
fZ[0] - point[2];
1099 safz = point[2] -
fZ[
fNz-1];
1104 for (i=iz; i<
fNz-1; i++) {
1106 if (safe<safmin) safmin=safe;
1109 for (i=iz-1; i>=0; i--) {
1111 if (safe<safmin) safmin=safe;
1123 out <<
" // Shape: " <<
GetName() <<
" type: " <<
ClassName() << std::endl;
1124 out <<
" nz = " <<
fNz <<
";" << std::endl;
1125 out <<
" nvert = " <<
fNvert <<
";" << std::endl;
1126 out <<
" TGeoXtru *xtru = new TGeoXtru(nz);" << std::endl;
1127 out <<
" xtru->SetName(\"" <<
GetName() <<
"\");" << std::endl;
1129 for (i=0; i<
fNvert; i++) {
1130 out <<
" xvert[" << i <<
"] = " <<
fX[i] <<
"; yvert[" << i <<
"] = " <<
fY[i] <<
";" << std::endl;
1132 out <<
" xtru->DefinePolygon(nvert,xvert,yvert);" << std::endl;
1133 for (i=0; i<
fNz; i++) {
1134 out <<
" zsect = " <<
fZ[i] <<
";" << std::endl;
1135 out <<
" x0 = " <<
fX0[i] <<
";" << std::endl;
1136 out <<
" y0 = " <<
fY0[i] <<
";" << std::endl;
1137 out <<
" scale0 = " <<
fScale[i] <<
";" << std::endl;
1138 out <<
" xtru->DefineSection(" << i <<
",zsect,x0,y0,scale0);" << std::endl;
1140 out <<
" TGeoShape *" <<
GetPointerName() <<
" = xtru;" << std::endl;
1154 a = (
fX0[ind1]*
fZ[ind2]-
fX0[ind2]*
fZ[ind1])*invdz;
1155 b = (
fX0[ind2]-
fX0[ind1])*invdz;
1157 a = (
fY0[ind1]*
fZ[ind2]-
fY0[ind2]*
fZ[ind1])*invdz;
1158 b = (
fY0[ind2]-
fY0[ind1])*invdz;
1173 td.
fXc[i] = scale*
fX[i] + x0;
1174 td.
fYc[i] = scale*
fY[i] + y0;
1195 Error(
"SetDimensions",
"Cannot create TGeoXtru %s with less than 2 Z planes",
GetName());
1199 if (
fZ)
delete []
fZ;
1209 DefineSection(i, param[1+4*i], param[2+4*i], param[3+4*i], param[4+4*i]);
1222 for (i = 0; i <
fNz; i++) {
1225 for (j = 0; j <
fNvert; j++) {
1226 points[indx++] = td.
fXc[j];
1227 points[indx++] = td.
fYc[j];
1228 points[indx++] =
fZ[i];
1231 for (j = 0; j <
fNvert; j++) {
1232 points[indx++] = td.
fXc[fNvert-1-j];
1233 points[indx++] = td.
fYc[fNvert-1-j];
1234 points[indx++] =
fZ[i];
1251 for (i = 0; i <
fNz; i++) {
1254 for (j = 0; j <
fNvert; j++) {
1255 points[indx++] = td.
fXc[j];
1256 points[indx++] = td.
fYc[j];
1257 points[indx++] =
fZ[i];
1260 for (j = 0; j <
fNvert; j++) {
1261 points[indx++] = td.
fXc[fNvert-1-j];
1262 points[indx++] = td.
fYc[fNvert-1-j];
1263 points[indx++] =
fZ[i];
1278 nsegs = nv*(2*nz-1);
1279 npols = nv*(nz-1)+2;
1310 Int_t nbPnts = nz*nvert;
1311 Int_t nbSegs = nvert*(2*nz-1);
1312 Int_t nbPols = nvert*(nz-1)+2;
1313 if (buffer.
SetRawSizes(nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, nbPols, 6*(nbPols-2)+2*(2+nvert))) {
1338 for (
Int_t i=0; i<vecsize; i++) inside[i] =
Contains(&points[3*i]);
1348 for (
Int_t i=0; i<vecsize; i++)
ComputeNormal(&points[3*i], &dirs[3*i], &norms[3*i]);
1356 for (
Int_t i=0; i<vecsize; i++) dists[i] =
DistFromInside(&points[3*i], &dirs[3*i], 3, step[i]);
1364 for (
Int_t i=0; i<vecsize; i++) dists[i] =
DistFromOutside(&points[3*i], &dirs[3*i], 3, step[i]);
1374 for (
Int_t i=0; i<vecsize; i++) safe[i] =
Safety(&points[3*i], inside[i]);
void SetSeg(Int_t iseg)
Set current segment.
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 specified by dirs. Store output in dist...
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 void Draw(Option_t *option="")
Draw the polygon.
double dist(Rotation3D const &r1, Rotation3D const &r2)
virtual const TBuffer3D & GetBuffer3D(Int_t reqSections, Bool_t localFrame) const
Fills a static 3D buffer and returns a reference.
#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...
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");
virtual TBuffer3D * MakeBuffer3D() const
Creates a TBuffer3D describing this shape.
ThreadData_t()
Constructor.
Bool_t TestBit(UInt_t f) const
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 ClearThreadData() 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.
Double_t Safety(const Double_t *point, Int_t &isegment) const
Compute minimum distance from POINT to any segment. Returns segment index.
virtual void Sizeof3D() const
fill size of this 3-D object
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.
An arbitrary polygon defined by vertices.
virtual void SetDimensions(Double_t *param)
virtual void GetMeshNumbers(Int_t &nvert, Int_t &nsegs, Int_t &npols) const
Returns numbers of vertices, segments and polygons composing the shape mesh.
void GetPlaneNormal(const Double_t *vert, Double_t *norm) const
Returns normal vector to the planar quadrilateral defined by vector VERT.
Short_t Min(Short_t a, Short_t b)
virtual void CreateThreadData(Int_t nthreads)
Create thread data for n threads max.
virtual void InspectShape() const
Prints shape parameters.
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...
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()
virtual void InspectShape() const
Print actual Xtru parameters.
virtual const char * ClassName() const
Returns name of class to which the object belongs.
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
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.
void SetSectionsValid(UInt_t mask)
const char * GetPointerName() const
Provide a pointer name containing uid.
virtual ~TGeoXtru()
destructor
virtual const char * GetName() const
Get the shape name.
Int_t ShapeDistancetoPrimitive(Int_t numpoints, Int_t px, Int_t py) const
Returns distance to shape primitive mesh.
Bool_t SectionsValid(UInt_t mask) const
TNamed & operator=(const TNamed &rhs)
TNamed assignment operator.
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 specified by dirs. Store output in dist...
void SetXY(Double_t *x, Double_t *y)
Set X/Y array pointer for the polygon and daughters.
virtual Bool_t Contains(const Double_t *point) const
test if point is inside this shape
void TransformPoints(Double_t *points, UInt_t NbPoints) const
Tranform a set of points (LocalToMaster)
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
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.
virtual Int_t GetNmeshVertices() const
Return number of vertices of the mesh representation.
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...
static Int_t Lock()
Static method to lock the main thread mutex.
virtual void ComputeBBox()
compute bounding box of the pcon
virtual Double_t Safety(const Double_t *point, Bool_t in=kTRUE) const
Computes the closest distance from given point to this shape.
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.
An extrusion with fixed outline shape in x-y and a sequence of z extents (segments).
static Int_t UnLock()
Static method to unlock the main thread mutex.
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 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.
Bool_t TestShapeBit(UInt_t f) const
void FinishPolygon()
Decompose polygon in a convex outscribed part and a list of daughter polygons that have to be subtrac...
Bool_t IsClockwise() const
~ThreadData_t()
Destructor.
ThreadData_t & GetThreadData() const
void DrawPolygon(Option_t *option="")
Draw the section polygon.
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.
you should not use this method at all Int_t Int_t z
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 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
static Int_t ThreadId()
Translates the current thread id to an ordinal number.
Short_t Max(Short_t a, Short_t b)
virtual void SetSegsAndPols(TBuffer3D &buff) const
Fill TBuffer3D structure for segments and polygons.
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
virtual Bool_t Contains(const Double_t *point) const
Test if point is inside this shape.
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.
virtual void SetPoints(Double_t *points) const
create polycone mesh points
Double_t Sqrt(Double_t x)
Double_t Area() const
Computes area of the polygon in [length^2].
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.
Int_t GetBasicColor() const
Get the basic color (0-7).
virtual Double_t Capacity() const
Compute capacity [length^3] of this shape.
Long64_t BinarySearch(Long64_t n, const T *array, T value)
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Bool_t DefinePolygon(Int_t nvert, const Double_t *xv, const Double_t *yv)
Creates the polygon representing the blueprint of any Xtru section.