77 : fNxy(0), fNxyAlloc(0), fNz(0), fNzAlloc(0), fXvtx(0), fYvtx(0),
78 fZ(0), fScale(0), fX0(0), fY0(0)
80 fPolygonShape = kUncheckedXY;
81 fZOrdering = kUncheckedZ;
82 fSplitConcave = kFALSE;
91 TXTRU::TXTRU(
const char *name,
const char *title,
const char *material,
93 : TShape (name,title,material)
107 fPolygonShape = kUncheckedXY;
108 fZOrdering = kUncheckedZ;
109 fSplitConcave = kFALSE;
112 Error(name,
"number of x-y points for %s must be at least three!",name);
116 Error(name,
"number of z points for %s must be at least two!",name);
123 fXvtx =
new Float_t [fNxyAlloc];
124 fYvtx =
new Float_t [fNxyAlloc];
127 for (i = 0; i < fNxyAlloc; i++) {
135 fZ =
new Float_t [fNzAlloc];
136 fScale =
new Float_t [fNzAlloc];
137 fX0 =
new Float_t [fNzAlloc];
138 fY0 =
new Float_t [fNzAlloc];
141 for (j = 0; j < fNzAlloc; j++) {
153 TXTRU::TXTRU(
const TXTRU &xtru) : TShape(xtru)
157 ((TXTRU&)xtru).Copy(*
this);
165 if (fXvtx)
delete [] fXvtx;
166 if (fYvtx)
delete [] fYvtx;
172 if (fZ)
delete [] fZ;
173 if (fScale)
delete [] fScale;
174 if (fX0)
delete [] fX0;
175 if (fY0)
delete [] fY0;
183 fPolygonShape = kUncheckedXY;
184 fZOrdering = kUncheckedZ;
190 TXTRU& TXTRU::operator=(
const TXTRU &rhs)
193 if (
this == &rhs)
return *
this;
205 ((TXTRU&)rhs).Copy(*
this);
213 void TXTRU::Copy(TObject &obj)
const
218 ((TXTRU&)obj).fNxy = fNxy;
219 ((TXTRU&)obj).fNxyAlloc = fNxyAlloc;
220 ((TXTRU&)obj).fXvtx =
new Float_t [fNxyAlloc];
221 ((TXTRU&)obj).fYvtx =
new Float_t [fNxyAlloc];
223 for (i = 0; i < fNxyAlloc; i++) {
224 ((TXTRU&)obj).fXvtx[i] = fXvtx[i];
225 ((TXTRU&)obj).fYvtx[i] = fYvtx[i];
228 ((TXTRU&)obj).fNz = fNz;
229 ((TXTRU&)obj).fNzAlloc = fNzAlloc;
230 ((TXTRU&)obj).fZ =
new Float_t [fNzAlloc];
231 ((TXTRU&)obj).fScale =
new Float_t [fNzAlloc];
232 ((TXTRU&)obj).fX0 =
new Float_t [fNzAlloc];
233 ((TXTRU&)obj).fY0 =
new Float_t [fNzAlloc];
235 for (j = 0; j < fNzAlloc; j++) {
236 ((TXTRU&)obj).fZ[j] = fZ[j];
237 ((TXTRU&)obj).fScale[j] = fScale[j];
238 ((TXTRU&)obj).fX0[j] = fX0[j];
239 ((TXTRU&)obj).fY0[j] = fY0[j];
242 ((TXTRU&)obj).fPolygonShape = fPolygonShape;
243 ((TXTRU&)obj).fZOrdering = fZOrdering;
250 void TXTRU::DefineSection(Int_t iz, Float_t z, Float_t scale, Float_t x0, Float_t y0)
255 fZOrdering = kUncheckedZ;
257 if (iz >= fNzAlloc) {
259 Int_t newNalloc = iz + 1;
260 Float_t *newZ =
new Float_t [newNalloc];
261 Float_t *newS =
new Float_t [newNalloc];
262 Float_t *newX =
new Float_t [newNalloc];
263 Float_t *newY =
new Float_t [newNalloc];
265 for (i = 0; i < newNalloc; i++) {
288 fNzAlloc = newNalloc;
292 fNz = TMath::Max(iz+1,fNz);
304 void TXTRU::DefineVertex(Int_t ipt, Float_t x, Float_t y) {
308 fPolygonShape = kUncheckedXY;
310 if (ipt >= fNxyAlloc) {
312 Int_t newNalloc = ipt + 1;
313 Float_t *newX =
new Float_t [newNalloc];
314 Float_t *newY =
new Float_t [newNalloc];
316 for (i = 0; i < newNalloc; i++) {
331 fNxyAlloc = newNalloc;
335 fNxy = TMath::Max(ipt+1,fNxy);
345 Int_t TXTRU::DistancetoPrimitive(Int_t px, Int_t py)
347 Int_t numPoints = fNz*fNxy;
348 return ShapeDistancetoPrimitive(numPoints,px,py);
354 Float_t TXTRU::GetOutlinePointX(Int_t n)
const {
355 if ((n < 0) || (n >= fNxy)) {
356 Error(fName,
"no such point %d [of %d]",n,fNxy);
365 Float_t TXTRU::GetOutlinePointY(Int_t n)
const {
366 if ((n < 0) || (n >= fNxy)) {
367 Error(fName,
"no such point %d [of %d]",n,fNxy);
376 Float_t TXTRU::GetSectionX0(Int_t n)
const {
377 if ((n < 0) || (n >= fNz)) {
378 Error(fName,
"no such section %d [of %d]",n,fNz);
387 Float_t TXTRU::GetSectionY0(Int_t n)
const {
388 if ((n < 0) || (n >= fNz)) {
389 Error(fName,
"no such section %d [of %d]",n,fNz);
398 Float_t TXTRU::GetSectionScale(Int_t n)
const {
399 if ((n < 0) || (n >= fNz)) {
400 Error(fName,
"no such section %d [of %d]",n,fNz);
409 Float_t TXTRU::GetSectionZ(Int_t n)
const {
410 if ((n < 0) || (n >= fNz)) {
411 Error(fName,
"no such section %d [of %d]",n,fNz);
424 void TXTRU::Print(Option_t *option)
const
426 TString opt = option;
429 printf(
"TXTRU %s Nxy=%d [of %d] Nz=%d [of %d] Option=%s\n",
430 GetName(),fNxy,fNxyAlloc,fNz,fNzAlloc,option);
432 const char *shape = 0;
433 const char *zorder = 0;
435 switch (fPolygonShape) {
436 case kUncheckedXY: shape =
"Unchecked ";
break;
437 case kMalformedXY: shape =
"Malformed ";
break;
438 case kConvexCCW: shape =
"Convex CCW ";
break;
439 case kConvexCW: shape =
"Convex CW ";
break;
440 case kConcaveCCW: shape =
"Concave CCW";
break;
441 case kConcaveCW: shape =
"Concave CW ";
break;
444 switch (fZOrdering) {
445 case kUncheckedZ: zorder =
"Unchecked Z";
break;
446 case kMalformedZ: zorder =
"Malformed Z";
break;
447 case kConvexIncZ: zorder =
"Convex Increasing Z";
break;
448 case kConvexDecZ: zorder =
"Convex Decreasing Z";
break;
449 case kConcaveIncZ: zorder =
"Concave Increasing Z";
break;
450 case kConcaveDecZ: zorder =
"Concave Decreasing Z";
break;
453 printf(
" XY shape '%s', '%s'\n",shape,zorder);
457 if (opt.Contains(
"alloc")) {
465 const char *name = 0;
468 Bool_t print_vtx = opt.Contains(
"xy");
469 Bool_t print_z = opt.Contains(
"z");
472 for (ixyz=0; ixyz<6; ixyz++) {
474 case 0: p = fXvtx; name =
"x"; nlimit = nxy;
break;
475 case 1: p = fYvtx; name =
"y"; nlimit = nxy;
break;
476 case 2: p = fZ; name =
"z"; nlimit = nz;
break;
477 case 3: p = fScale; name =
"scale"; nlimit = nz;
break;
478 case 4: p = fX0; name =
"x0"; nlimit = nz;
break;
479 case 5: p = fY0; name =
"y0"; nlimit = nz;
break;
481 if (ixyz<=1 && !print_vtx)
continue;
482 if (ixyz>=2 && !print_z)
continue;
484 printf(
" Float_t %s[] = \n { %10g",name,*p++);
486 for (i=1;i<nlimit;i++) {
487 printf(
", %10g",*p++);
488 if (i%6==5) printf(
"\n ");
499 void TXTRU::SetPoints(Double_t *points)
const
502 Int_t ipt, ixy, iz, ioff;
506 Bool_t iscw = (fPolygonShape == kConvexCW ||
507 fPolygonShape == kConcaveCW );
510 Bool_t reversez = (fZOrdering == kConvexDecZ ||
511 fZOrdering == kConcaveDecZ );
515 for (i=0; i<fNz; i++) {
516 iz = (reversez) ? fNz-1 - i : i;
518 for (j=0; j<fNxy; j++) {
519 ixy = (iscw) ? fNxy-1 - j : j;
523 points[ioff ] = x*fScale[iz] + fX0[iz];
524 points[ioff+1] = y*fScale[iz] + fY0[iz];
525 points[ioff+2] = fZ[iz];
535 void TXTRU::Sizeof3D()
const
537 gSize3D.numPoints += fNz*fNxy;
538 gSize3D.numSegs += (2*fNz-1)*fNxy;
539 gSize3D.numPolys += (fNz-1)*fNxy+2;
550 void TXTRU::SplitConcavePolygon(Bool_t split)
552 fSplitConcave = split;
556 fSplitConcave = kFALSE;
557 std::cout << TNamed::GetName()
558 <<
" TXTRU::SplitConcavePolygon is not yet implemented" << std::endl;
566 void TXTRU::TruncateNxy(Int_t npts) {
567 if ((npts < 0) || (npts > fNxy)) {
568 Error(fName,
"truncate to %d impossible on %d points",npts,fNxy);
578 void TXTRU::TruncateNz(Int_t nz) {
579 if ((nz < 0) || (nz > fNz)) {
580 Error(fName,
"truncate to %d impossible on %d points",nz,fNz);
592 void TXTRU::CheckOrdering()
594 Float_t plus, minus, zero;
598 plus = minus = zero = 0;
600 for (ixy=0; ixy<fNxy; ixy++) {
604 Int_t ixyprev = (ixy + fNxy - 1)%fNxy;
605 Int_t ixynext = (ixy + fNxy + 1)%fNxy;
607 Float_t dxprev = fXvtx[ixy] - fXvtx[ixyprev];
608 Float_t dyprev = fYvtx[ixy] - fYvtx[ixyprev];
609 Float_t dxnext = fXvtx[ixynext] - fXvtx[ixy];
610 Float_t dynext = fYvtx[ixynext] - fYvtx[ixy];
612 Float_t xprod = dxprev*dynext - dxnext*dyprev;
616 }
else if (xprod < 0) {
625 fPolygonShape = kMalformedXY;
627 if (plus==0 || minus==0) {
630 fPolygonShape = kConvexCCW;
632 fPolygonShape = kConvexCW;
637 fPolygonShape = kConcaveCCW;
639 fPolygonShape = kConcaveCW;
646 plus = minus = zero = 0;
647 Bool_t scaleSignChange = kFALSE;
649 for (iz=0; iz<fNz; iz++) {
653 Int_t izprev = (iz + fNz - 1)%fNz;
654 Int_t iznext = (iz + fNz + 1)%fNz;
656 Float_t dzprev = fZ[iz] - fZ[izprev];
657 Float_t dsprev = fScale[iz] - fScale[izprev];
658 Float_t dznext = fZ[iznext] - fZ[iz];
659 Float_t dsnext = fScale[iznext] - fScale[iz];
665 }
else if (iz==fNz-1) {
667 dsnext = -fScale[iz];
670 Float_t xprod = dznext*dsprev - dzprev*dsnext;
674 }
else if (xprod < 0) {
680 if (fScale[iz]*fScale[iznext] < 0) scaleSignChange = kTRUE;
683 if (fNz<1 || scaleSignChange) {
685 fZOrdering = kMalformedZ;
687 if (plus==0 || minus==0) {
690 fZOrdering = kConvexIncZ;
692 fZOrdering = kConvexDecZ;
697 fZOrdering = kConcaveIncZ;
699 fZOrdering = kConcaveDecZ;
708 void TXTRU::DumpPoints(
int npoints,
float *pointbuff)
const
710 std::cout <<
"TXTRU::DumpPoints - " << npoints <<
" points" << std::endl;
714 for (ipt=0; ipt<npoints; ipt++) {
715 x = pointbuff[ioff++];
716 y = pointbuff[ioff++];
717 z = pointbuff[ioff++];
718 printf(
" [%4d] %6.1f %6.1f %6.1f \n",ipt,x,y,z);
725 void TXTRU::DumpSegments(
int nsegments,
int *segbuff)
const
727 std::cout <<
"TXTRU::DumpSegments - " << nsegments <<
" segments" << std::endl;
731 for (iseg=0; iseg<nsegments; iseg++) {
732 icol = segbuff[ioff++];
733 p1 = segbuff[ioff++];
734 p2 = segbuff[ioff++];
735 printf(
" [%4d] %3d (%4d,%4d)\n",iseg,icol,p1,p2);
742 void TXTRU::DumpPolygons(
int npolygons,
int *polybuff,
int buffsize)
const
744 std::cout <<
"TXTRU::DumpPolygons - " << npolygons <<
" polygons" << std::endl;
746 int icol, nseg, iseg;
748 for (ipoly=0; ipoly<npolygons; ipoly++) {
749 icol = polybuff[ioff++];
750 nseg = polybuff[ioff++];
752 std::cout <<
" [" << std::setw(4) << ipoly <<
"] icol " << std::setw(3) << icol
753 <<
" nseg " << std::setw(3) << nseg <<
" (";
755 printf(
" [%d4] icol %d3 nseg %d3 (", ipoly, icol, nseg);
757 for (iseg=0; iseg<nseg-1; iseg++) {
758 std::cout << polybuff[ioff++] <<
",";
760 std::cout << polybuff[ioff++] <<
")" << std::endl;
762 std::cout <<
" buffer size " << buffsize <<
" last used " << --ioff << std::endl;
768 const TBuffer3D & TXTRU::GetBuffer3D(Int_t reqSections)
const
770 static TBuffer3D buffer(TBuffer3DTypes::kGeneric);
772 TShape::FillBuffer3D(buffer, reqSections);
774 if (reqSections & TBuffer3D::kRawSizes) {
778 if (fPolygonShape == kUncheckedXY ||
779 fZOrdering == kUncheckedZ) {
780 const_cast<TXTRU *
>(
this)->CheckOrdering();
782 Int_t nbPnts = fNz*fNxy;
783 Int_t nbSegs = fNxy*(2*fNz-1);
784 Int_t nbPols = fNxy*(fNz-1)+2;
785 if (buffer.SetRawSizes(nbPnts, 3*nbPnts, nbSegs, 3*nbSegs, nbPols, 6*(nbPols-2)+2*(2+fNxy))) {
786 buffer.SetSectionsValid(TBuffer3D::kRawSizes);
789 if (reqSections & TBuffer3D::kRaw) {
791 SetPoints(buffer.fPnts);
792 if (!buffer.fLocalFrame) {
793 TransformPoints(buffer.fPnts, buffer.NbPnts());
796 Int_t c = GetBasicColor();
803 for (i=0; i<fNz; i++) {
807 for (j=0; j<fNxy; j++) {
809 buffer.fSegs[indx++] = c;
810 buffer.fSegs[indx++] = indx2+j;
811 buffer.fSegs[indx++] = indx2+k;
814 for (i=0; i<fNz-1; i++) {
818 for (j=0; j<fNxy; j++) {
820 buffer.fSegs[indx++] = c;
821 buffer.fSegs[indx++] = indx2+j;
822 buffer.fSegs[indx++] = indx2+k;
830 for (i=0; i<fNz-1; i++) {
832 for (j=0; j<fNxy; j++) {
834 buffer.fPols[indx++] = c+j%3;
835 buffer.fPols[indx++] = 4;
836 buffer.fPols[indx++] = indx2+j;
837 buffer.fPols[indx++] = fNz*fNxy+indx2+k;
838 buffer.fPols[indx++] = indx2+fNxy+j;
839 buffer.fPols[indx++] = fNz*fNxy+indx2+j;
842 buffer.fPols[indx++] = c+2;
843 buffer.fPols[indx++] = fNxy;
845 for (j = fNxy - 1; j >= 0; --j) {
846 buffer.fPols[indx++] = indx2+j;
849 buffer.fPols[indx++] = c;
850 buffer.fPols[indx++] = fNxy;
851 indx2 = (fNz-1)*fNxy;
853 for (j=0; j<fNxy; j++) {
854 buffer.fPols[indx++] = indx2+j;
857 buffer.SetSectionsValid(TBuffer3D::kRaw);