00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "TPolyLineShape.h"
00013
00014 #include "TPoints3D.h"
00015 #include "TVolume.h"
00016 #include "TVolumePosition.h"
00017 #include "TTUBE.h"
00018 #include "TBRIK.h"
00019 #include "TSPHE.h"
00020 #include "TView.h"
00021 #include "TVirtualPad.h"
00022 #include "TTablePadView3D.h"
00023 #include "TPoint.h"
00024 #include "TVirtualPS.h"
00025 #include "TMath.h"
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 ClassImp(TPolyLineShape)
00080
00081
00082 TPolyLineShape::TPolyLineShape()
00083 {
00084
00085 fShape = 0;
00086 fSmooth = kFALSE;
00087 fConnection= 0;
00088 fPoints=0;
00089 SetWidthFactor();
00090 fHasDrawn = kFALSE;
00091 fShapeType = kNULL;
00092 fSizeX3D = 0;
00093 fPointFlag = kFALSE;
00094 fLineFlag = kFALSE;
00095 }
00096
00097
00098 TPolyLineShape::TPolyLineShape(TPoints3DABC *points,Option_t* option)
00099 {
00100
00101 fShape = 0;
00102 fShapeType = kNULL;
00103 fSmooth = kFALSE;
00104 fConnection = 0;
00105 fPoints = points;
00106 fHasDrawn = kFALSE;
00107 fSizeX3D = 0;
00108
00109 if (!fPoints) {
00110 Error("TPolyLineShape","No polyline is defined");
00111 return;
00112 }
00113 fPointFlag = strchr(option,'P')?kTRUE:kFALSE;
00114 fLineFlag = strchr(option,'L')?kTRUE:kFALSE;
00115
00116 SetWidthFactor();
00117 Create();
00118 }
00119
00120
00121 TPolyLineShape::~TPolyLineShape()
00122 {
00123
00124 SafeDelete(fShape);
00125 SafeDelete(fSizeX3D);
00126 }
00127
00128
00129 void TPolyLineShape::Create()
00130 {
00131
00132 if (!fConnection) SetConnection(kBrik);
00133 }
00134
00135
00136 Size3D *TPolyLineShape::CreateX3DSize(Bool_t marker)
00137 {
00138
00139 if (!fSizeX3D) fSizeX3D = new Size3D;
00140 fSizeX3D->numPoints = 0;
00141 fSizeX3D->numSegs = 0;
00142 fSizeX3D->numPolys = 0;
00143 if (fPoints) {
00144 Int_t size = fPoints->Size();
00145 if (marker) {
00146 Int_t mode;
00147 if (size > 10000) mode = 1;
00148 else if (size > 3000) mode = 2;
00149 else mode = 3;
00150
00151 fSizeX3D->numSegs = size*mode;
00152 fSizeX3D->numPoints = size*mode*2;
00153 fSizeX3D->numPolys = 0;
00154 } else {
00155 fSizeX3D->numSegs = size-1;
00156 fSizeX3D->numPoints = size;
00157 }
00158 fSizeX3D->numPolys = 0;
00159 }
00160 return fSizeX3D;
00161 }
00162
00163
00164 Int_t TPolyLineShape::SetConnection(EShapeTypes connection)
00165 {
00166
00167 Float_t size = 0.5*GetWidthFactor()*GetLineWidth();
00168
00169 if (fShapeType != connection) {
00170 SafeDelete(fConnection);
00171 fShapeType = connection;
00172 switch (fShapeType) {
00173 case kSphere:
00174 SetConnection(new TSPHE("connection","sphere","void",0,size,0,90,0,360));
00175 break;
00176 default:
00177 SetConnection(new TBRIK("connection","brik","void",size,size,size));
00178 break;
00179 };
00180 }
00181 return 0;
00182 }
00183
00184
00185 Int_t TPolyLineShape::DistancetoPrimitive(Int_t px, Int_t py)
00186 {
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 if (fPoints) {
00197 Int_t ret = fPoints->DistancetoPrimitive( px, py);
00198 if (ret == -1) ret = PointDistancetoPrimitive(px, py);
00199 return ret;
00200 }
00201 return 999999;
00202 }
00203
00204
00205 Int_t TPolyLineShape::PointDistancetoPrimitive(Int_t px, Int_t py)
00206 {
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 const Int_t inaxis = 7;
00218 Float_t dist = 999999;
00219
00220 Int_t puxmin = gPad->XtoAbsPixel(gPad->GetUxmin());
00221 Int_t puymin = gPad->YtoAbsPixel(gPad->GetUymin());
00222 Int_t puxmax = gPad->XtoAbsPixel(gPad->GetUxmax());
00223 Int_t puymax = gPad->YtoAbsPixel(gPad->GetUymax());
00224
00225 TView *view = 0;
00226
00227 if (px < puxmin - inaxis) goto END;
00228 if (py > puymin + inaxis) goto END;
00229 if (px > puxmax + inaxis) goto END;
00230 if (py < puymax - inaxis) goto END;
00231
00232 view = gPad->GetView();
00233 if (view) {
00234 Int_t i;
00235 Float_t dpoint;
00236 Float_t xndc[3];
00237 Int_t x1,y1;
00238 Int_t pointSize = fPoints->Size();
00239 for (i=0;i<pointSize;i++) {
00240 Float_t thisPoints[3];
00241 view->WCtoNDC(fPoints->GetXYZ(thisPoints,i), xndc);
00242 x1 = gPad->XtoAbsPixel(xndc[0]);
00243 y1 = gPad->YtoAbsPixel(xndc[1]);
00244 dpoint = (px-x1)*(px-x1) + (py-y1)*(py-y1);
00245 if (dpoint < dist) dist = dpoint;
00246 }
00247 dist = (TMath::Sqrt(dist));
00248 }
00249 END:
00250 return Int_t(dist);
00251 }
00252
00253
00254 void TPolyLineShape::Draw(Option_t *)
00255 {
00256
00257 Create();
00258 AppendPad();
00259 }
00260
00261
00262 void TPolyLineShape::ExecuteEvent(Int_t event, Int_t px, Int_t py)
00263 {
00264
00265 if (fPoints) fPoints->ExecuteEvent(event,px, py);
00266 }
00267
00268
00269 Color_t TPolyLineShape::GetColorAttribute() const
00270 {
00271
00272 return ((TPolyLineShape *)this)->GetLineColor();
00273 }
00274
00275 const char *TPolyLineShape::GetName() const
00276 {
00277
00278 return fPoints ? fPoints->GetName() : TShape::GetName();
00279 }
00280
00281 char *TPolyLineShape::GetObjectInfo(Int_t px, Int_t py) const
00282 {
00283
00284 return fPoints ? fPoints->GetObjectInfo(px, py) : TShape::GetObjectInfo(px,py);
00285 }
00286
00287
00288 Size_t TPolyLineShape::GetSizeAttribute() const
00289 {
00290
00291 return ((TPolyLineShape *)this)->GetMarkerSize();
00292 }
00293
00294
00295 Style_t TPolyLineShape::GetStyleAttribute() const
00296 {
00297
00298 return ((TPolyLineShape *)this)->GetLineStyle();
00299 }
00300
00301
00302 const char *TPolyLineShape::GetTitle() const
00303 {
00304
00305 return fPoints ? fPoints->GetTitle() : TShape::GetTitle();
00306 }
00307
00308 void TPolyLineShape::PaintNode(Float_t *start,Float_t *end,Option_t *option)
00309 {
00310
00311
00312
00313
00314 const Int_t kDimension = 3;
00315 Double_t vector[kDimension];
00316 Double_t nodeposition[kDimension];
00317 Int_t i=0;
00318 for (i=0;i<kDimension;i++) {
00319 vector[i]=end[i]-start[i];
00320 nodeposition[i]=0.5*(start[i]+end[i]);
00321 }
00322 Double_t length = TMath::Normalize(vector);
00323
00324
00325
00326 Double_t oz[3]={0,0,1};
00327 Double_t rotate[3];
00328
00329 Double_t sina = TMath::Normalize(TMath::Cross(vector,oz,rotate));
00330 Double_t cosa = Product(vector,oz);
00331 Double_t mrot[3][3];
00332
00333 TShape *shape = fShape;
00334 if (!shape) shape = fConnection;
00335
00336 Gyrot(rotate,cosa,sina,mrot);
00337
00338 Float_t width = GetWidthFactor()*GetLineWidth();
00339
00340 mrot[0][0] *= width;
00341 mrot[0][1] *= width;
00342 mrot[0][2] *= width;
00343
00344 mrot[1][0] *= width;
00345 mrot[1][1] *= width;
00346 mrot[1][2] *= width;
00347
00348 mrot[2][0] *= length;
00349 mrot[2][1] *= length;
00350 mrot[2][2] *= length;
00351
00352 Color_t color = GetLineColor();
00353
00354 TVolume node("SegmentNode","SegmentNode", shape);
00355 node.SetLineColor(color);
00356 if (!fShape) node.SetVisibility();
00357 node.SetLineColor(color);
00358
00359 TRotMatrix matrix ("rotate","rotate",&mrot[0][0]);
00360 TVolumePosition position(&node,nodeposition[0],nodeposition[1]
00361 ,nodeposition[2],&matrix);
00362
00363 if (!(fSmooth || fConnection)) {
00364 node.PaintNodePosition(option, &position);
00365 return;
00366 }
00367
00368
00369
00370 memset(mrot,0,9*sizeof(Double_t));
00371
00372 length = width/length;
00373 mrot[2][2] = length;
00374 mrot[0][0] = 1;
00375 mrot[1][1] = 1;
00376
00377 TRotMatrix kneeMatrix("knee","knee",&mrot[0][0]);
00378 TVolume knee("ConnectionNode","ConnectionNode", fConnection);
00379 TVolumePosition kneePosition(&knee, 0, 0, 0.5, &kneeMatrix);
00380 knee.SetLineColor(color);
00381 node.Add(&knee,&kneePosition);
00382
00383 node.PaintNodePosition(option, &position);
00384 }
00385
00386
00387 void TPolyLineShape::Paint(Option_t *opt)
00388 {
00389
00390 if (!GetPoints()) return;
00391
00392 Bool_t rangeView = opt && opt[0] && strcmp(opt,"range")==0 ? kTRUE : kFALSE;
00393 TTablePadView3D *view3D = 0;
00394 if (!rangeView && (view3D = (TTablePadView3D*)gPad->GetView3D()) ) {
00395 TString mode;
00396
00397 mode="";
00398 if (fLineFlag) mode = "L";
00399 if (fPointFlag) mode += "P";
00400
00401 view3D->SetLineAttr(GetColorAttribute(), (Int_t)GetSizeAttribute());
00402 view3D->PaintPoints3D(GetPoints(), mode.Data());
00403 }
00404 if (opt && !strstr(opt, "x3d")) {
00405 if (fPointFlag) {
00406 SetMarkerColor(GetColorAttribute());
00407 SetMarkerSize(GetSizeAttribute());
00408 PaintPolyMarker(fPoints->Size());
00409 }
00410 if (fLineFlag) {
00411 SetLineColor(GetColorAttribute());
00412 SetLineWidth((Width_t)GetSizeAttribute());
00413 PaintPoints(fPoints->Size());
00414 }
00415
00416 } else {
00417 if (fLineFlag) {
00418 CreateX3DSize(kFALSE); PaintX3DLine(opt);
00419 } else {
00420 CreateX3DSize(kTRUE); PaintX3DMarker(opt);
00421 }
00422
00423 }
00424 }
00425
00426
00427 void TPolyLineShape::PaintPoints(Int_t n, Float_t *, Option_t *)
00428 {
00429
00430
00431 if (n < 2) return;
00432
00433 TAttLine::Modify();
00434
00435
00436 for (Int_t i=1;i<n;i++) {
00437 Float_t xyz[6];
00438 fPoints->GetXYZ(&xyz[0],i-1,2);
00439 gPad->PaintLine3D(xyz, &xyz[3]);
00440 }
00441 }
00442
00443
00444 void TPolyLineShape::PaintPolyMarker(Int_t n, Float_t *, Marker_t, Option_t *)
00445 {
00446
00447
00448
00449 if (n <= 0) return;
00450
00451 TView *view = gPad->GetView();
00452 if(!view) return;
00453
00454
00455 TPoint *pxy = new TPoint[n];
00456 Float_t *x = new Float_t[n];
00457 Float_t *y = new Float_t[n];
00458 Float_t xndc[3], ptr[3];
00459
00460
00461 Int_t nin = 0;
00462 for (Int_t i = 0; i < n; i++) {
00463 fPoints->GetXYZ(ptr,i);
00464 view->WCtoNDC(ptr, xndc);
00465 if (xndc[0] < gPad->GetX1() || xndc[0] > gPad->GetX2()) continue;
00466 if (xndc[1] < gPad->GetY1() || xndc[1] > gPad->GetY2()) continue;
00467 x[nin] = xndc[0];
00468 y[nin] = xndc[1];
00469 pxy[nin].fX = gPad->XtoPixel(x[nin]);
00470 pxy[nin].fY = gPad->YtoPixel(y[nin]);
00471 nin++;
00472 }
00473
00474 TAttMarker::Modify();
00475
00476
00477 if (!gPad->IsBatch()) gVirtualX->DrawPolyMarker(nin, pxy);
00478
00479
00480 if (gVirtualPS) {
00481 gVirtualPS->DrawPolyMarker(nin, x, y);
00482 }
00483 delete [] x;
00484 delete [] y;
00485
00486 delete [] pxy;
00487 }
00488
00489
00490 void TPolyLineShape::Paint3d(Option_t *opt)
00491 {
00492
00493 if (!fPoints) return;
00494
00495 Create();
00496
00497 struct XYZ { Float_t xyz[3]; } *points;
00498 points = (XYZ *)(fPoints->GetP());
00499 Int_t size = fPoints->GetN()-1;
00500
00501 for (Int_t i=0;i<size;i++)
00502 PaintNode((Float_t *)(points+i+1),(Float_t *)(points+i),opt);
00503 fHasDrawn = kTRUE;
00504 }
00505
00506
00507 void TPolyLineShape::PaintX3DLine(Option_t *)
00508 {
00509
00510 #ifndef WIN32
00511 Int_t size = 0;
00512 if (fPoints) size = fPoints->Size();
00513 if (!size) return;
00514
00515 X3DBuffer *buff = new X3DBuffer;
00516 if (!buff) return;
00517
00518 fSizeX3D->numPoints = buff->numPoints = size;
00519 fSizeX3D->numSegs = buff->numSegs = size-1;
00520 fSizeX3D->numPolys = buff->numPolys = 0;
00521
00522 buff->polys = 0;
00523 TPoints3D x3dPoints(size);
00524 buff->points = fPoints->GetXYZ(x3dPoints.GetP(),0,size);
00525
00526
00527 Int_t c = ((GetColorAttribute() % 8) - 1) * 4;
00528 if (c < 0) c = 0;
00529
00530
00531 buff->segs = new Int_t[buff->numSegs*3];
00532 if (buff->segs) {
00533 for (Int_t i = 0; i < buff->numSegs; i++) {
00534 buff->segs[3*i ] = c;
00535 buff->segs[3*i+1] = i;
00536 buff->segs[3*i+2] = i+1;
00537 }
00538 }
00539
00540
00541 if (buff && buff->points && buff->segs)
00542 FillX3DBuffer(buff);
00543 else {
00544 gSize3D.numPoints -= buff->numPoints;
00545 gSize3D.numSegs -= buff->numSegs;
00546 gSize3D.numPolys -= buff->numPolys;
00547 }
00548
00549 if (buff->segs) delete [] buff->segs;
00550 if (buff->polys) delete [] buff->polys;
00551 if (buff) delete buff;
00552 #endif
00553 }
00554
00555
00556 void TPolyLineShape::PaintX3DMarker(Option_t *)
00557 {
00558
00559 #ifndef WIN32
00560 Int_t size = 0;
00561 if (fPoints) size = fPoints->Size();
00562 if (!size) return;
00563 Int_t mode;
00564 Int_t i, j, k, n;
00565
00566 X3DBuffer *buff = new X3DBuffer;
00567 if(!buff) return;
00568
00569 if (size > 10000) mode = 1;
00570 else if (size > 3000) mode = 2;
00571 else mode = 3;
00572
00573 fSizeX3D->numSegs = buff->numSegs = size*mode;
00574 fSizeX3D->numPoints = buff->numPoints = buff->numSegs*2;
00575 fSizeX3D->numPolys = buff->numPolys = 0;
00576
00577 buff->polys = 0;
00578
00579
00580
00581 Float_t delta = 0.002;
00582
00583 buff->points = new Float_t[buff->numPoints*3];
00584 if (buff->points) {
00585 for (i = 0; i < size; i++) {
00586 for (j = 0; j < mode; j++) {
00587 for (k = 0; k < 2; k++) {
00588 delta *= -1;
00589 for (n = 0; n < 3; n++) {
00590 Float_t xyz[3];
00591 fPoints->GetXYZ(xyz,i);
00592 buff->points[mode*6*i+6*j+3*k+n] =
00593 xyz[n] * (1 + (j == n ? delta : 0));
00594 }
00595 }
00596 }
00597 }
00598 }
00599
00600 Int_t c = ((GetColorAttribute() % 8) - 1) * 4;
00601 if (c < 0) c = 0;
00602
00603
00604 buff->segs = new Int_t[buff->numSegs*3];
00605 if (buff->segs) {
00606 for (i = 0; i < buff->numSegs; i++) {
00607 buff->segs[3*i ] = c;
00608 buff->segs[3*i+1] = 2*i;
00609 buff->segs[3*i+2] = 2*i+1;
00610 }
00611 }
00612
00613 if (buff->points && buff->segs)
00614 FillX3DBuffer(buff);
00615 else {
00616 gSize3D.numPoints -= buff->numPoints;
00617 gSize3D.numSegs -= buff->numSegs;
00618 gSize3D.numPolys -= buff->numPolys;
00619 }
00620
00621 if (buff->points) delete [] buff->points;
00622 if (buff->segs) delete [] buff->segs;
00623 if (buff->polys) delete [] buff->polys;
00624 if (buff) delete buff;
00625 #endif
00626 }
00627
00628
00629 Float_t TPolyLineShape::Product(Float_t *v1, Float_t *v2,Int_t ndim)
00630 {
00631
00632 Float_t p = 0;
00633 if (v1 && v2 && ndim > 0)
00634 for (Int_t i=0; i<ndim; i++) p+= v1[i]*v2[i];
00635 return p;
00636 }
00637
00638
00639 Double_t TPolyLineShape::Product(Double_t *v1, Double_t *v2,Int_t ndim)
00640 {
00641
00642 Double_t p = 0;
00643 if (v1 && v2 && ndim > 0)
00644 for (Int_t i=0;i<ndim;i++) p+= v1[i]*v2[i];
00645 return p;
00646 }
00647
00648
00649 Double_t *TPolyLineShape::Gyrot(Double_t *dirc, Double_t cosang, Double_t sinang, Double_t trans[3][3])
00650 {
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667 Double_t ax[3];
00668
00669 memcpy(ax,dirc,3*sizeof(Double_t));
00670 TMath::Normalize(ax);
00671
00672 Double_t ca = cosang;
00673 Double_t sa = sinang;
00674 Double_t ca1;
00675
00676 if (ca < 0.5)
00677 ca1 = 1. - ca ;
00678 else
00679 ca1 = (sa*sa)/(1.+ca) ;
00680
00681 Int_t j1 = 0;
00682 Int_t j2 = 0;
00683 for(j1 = 0; j1 < 3; j1++) {
00684 for(j2 = 0; j2 < 3; j2++)
00685 trans[j1][j2] = ca1*ax[j1]*ax[j2];
00686 trans[j1][j1] += ca;
00687 }
00688
00689 trans[0][1] = trans[0][1] - sa*ax[2];
00690 trans[1][0] = trans[1][0] + sa*ax[2];
00691 trans[0][2] = trans[0][2] + sa*ax[1];
00692 trans[2][0] = trans[2][0] - sa*ax[1];
00693 trans[1][2] = trans[1][2] - sa*ax[0];
00694 trans[2][1] = trans[2][1] + sa*ax[0];
00695
00696 return (Double_t *)trans;
00697
00698 }
00699
00700
00701 Color_t TPolyLineShape::SetColorAttribute(Color_t color)
00702 {
00703
00704 Color_t currentColor = GetColorAttribute();
00705 if (color != currentColor) {
00706 SetLineColor(color);
00707 SetMarkerColor(color);
00708 }
00709 return currentColor;
00710 }
00711
00712
00713 Size_t TPolyLineShape::SetSizeAttribute(Size_t size)
00714 {
00715
00716 Size_t currentSize = GetSizeAttribute();
00717 if (size != currentSize) {
00718 SetLineWidth(Width_t(size));
00719 SetMarkerSize(size);
00720 }
00721 return currentSize;
00722 }
00723
00724
00725 Style_t TPolyLineShape::SetStyleAttribute(Style_t style)
00726 {
00727
00728
00729
00730
00731 Style_t s = 0;
00732 s = GetStyleAttribute();
00733 SetLineStyle(style);
00734 SetMarkerStyle(style);
00735 return s;
00736 }
00737
00738
00739 void TPolyLineShape::SetShape(TShape *shape)
00740 {
00741
00742 SafeDelete(fShape)
00743 fShape = shape;
00744 }
00745
00746
00747 Int_t TPolyLineShape::Size() const
00748 {
00749
00750 return fPoints ? fPoints->Size():0;
00751 }
00752
00753
00754 void TPolyLineShape::Sizeof3D() const
00755 {
00756
00757
00758 TPolyLineShape *line = (TPolyLineShape *)this;
00759 if (fLineFlag )
00760 line->CreateX3DSize(kFALSE);
00761 else
00762 line->CreateX3DSize(kTRUE);
00763 if (fSizeX3D) {
00764 gSize3D.numPoints += fSizeX3D->numPoints;
00765 gSize3D.numSegs += fSizeX3D->numSegs;
00766 gSize3D.numPolys += fSizeX3D->numPolys;
00767 }
00768 else Error("Sizeof3D()","buffer size has not been defined yet");
00769 }