00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "BesVisLib/BesView.h"
00010 #include "BesVisLib/BesPolygon2D.h"
00011 #include <iostream>
00012
00013 #include <math.h>
00014 #include <TMath.h>
00015 #ifndef ROOT_TPad
00016 #include <TPad.h>
00017 #endif
00018
00019 #ifndef ROOT_TString
00020 #include <TString.h>
00021 #endif
00022
00023 #ifndef ROOT_TView
00024 #include <TView.h>
00025 #endif
00026
00027 #ifndef ROOT_TGeometry
00028 #include <TGeometry.h>
00029 #endif
00030
00031 #ifndef ROOT_TPaveText
00032 #include <TPaveText.h>
00033 #endif
00034
00035 using namespace std;
00036
00037 #ifndef __CINT__
00038 ClassImp(BesPolygon2D)
00039 #endif
00040
00041
00042
00043
00044
00045
00046
00047 int BesPolygon2D::num = 0;
00048 BesPolygon2D::BesPolygon2D() {
00049
00050
00051
00052
00053
00054
00055 fInfoBox = 0;
00056 fN = 0;
00057 fP = NULL;
00058 fPBackUp = NULL;
00059 fRotatable = false;
00060 f_xx = NULL;
00061 f_yy = NULL;
00062
00063 }
00064
00065
00066
00067 BesPolygon2D::BesPolygon2D(const char* name, const char* title,
00068 Int_t N, Double_t *P) :
00069 TNamed(name, title), TAttLine(), TAttFill() {
00070
00071
00072
00073
00074
00075
00076 fN = N;
00077 fP = new Double_t[fN*3];
00078 fPBackUp = new Double_t[fN*3];
00079 f_xx = NULL;
00080 f_yy = NULL;
00081
00082 fInfoBox = 0;
00083 if (P!=NULL){
00084 SetPoints(P);
00085 }
00086
00087 for ( Int_t i = 0; i < fN*3; i++ ) {
00088 fPBackUp[i] = fP[i];
00089 }
00090
00091 for (Int_t j = 0; j < 3; j++) {
00092 fCenter[j] = 0.0;
00093 for ( Int_t i = 0; i < fN; i++) {
00094 fCenter[j] += fP[3*i+j];
00095 }
00096 fCenter[j] /= fN;
00097 }
00098
00099 for ( Int_t i = 0; i < fN; i++ ) {
00100 }
00101
00102 fRotatable = false;
00103 }
00104
00105
00106
00107 BesPolygon2D::~BesPolygon2D() {
00108
00109
00110
00111
00112
00113
00114 if ( fP) delete [] fP;
00115 if ( fPBackUp) delete [] fPBackUp;
00116 }
00117
00118
00119
00120 void BesPolygon2D::Draw(Option_t *option) {
00121
00122
00123 TString opt = option;
00124 opt.ToUpper();
00125
00126 AppendPad(option);
00127 }
00128
00129
00130
00131 void BesPolygon2D::Paint(Option_t *option) {
00132
00133
00134 TString opt = option;
00135 opt.ToUpper();
00136
00137
00138 BesView *view = (BesView*)gPad->GetView();
00139 if (view == 0) cout << "no view found" << endl;
00140 Double_t viewPhi = view->GetLongitude();
00141 if (IsRotatable()) RotatePhi(viewPhi-180.0);
00142
00143 if (f_xx) {
00144 delete [] f_xx;
00145 f_xx = NULL;
00146 }
00147 if (f_yy) {
00148 delete [] f_yy;
00149 f_yy = NULL;
00150 }
00151
00152 f_xx = new Double_t[fN+1];
00153 f_yy = new Double_t[fN+1];
00154 Double_t Pndc[3];
00155
00156 for ( Int_t i = 0; i < fN; i++ ) {
00157 view->WCtoNDC(&fP[i*3], Pndc);
00158 f_xx[i] = Pndc[0];
00159 f_yy[i] = Pndc[1];
00160 }
00161
00162
00163 f_xx[fN] = f_xx[0];
00164 f_yy[fN] = f_yy[0];
00165
00166 TAttLine::Modify();
00167 TAttFill::Modify();
00168
00169 gPad->PaintFillArea(fN, f_xx, f_yy);
00170 gPad->PaintPolyLine(fN+1, f_xx, f_yy);
00171 if (IsRotatable()) Restore();
00172 }
00173
00174
00175
00176 Int_t BesPolygon2D::DistancetoPrimitive(Int_t px, Int_t py) {
00177
00178
00179
00180
00181
00182 const Int_t inaxis = 7;
00183 Int_t dist = 9999;
00184
00185 if (this->IsRotatable()) return dist;
00186
00187 Int_t puxmin = gPad->XtoAbsPixel(gPad->GetUxmin());
00188 Int_t puymin = gPad->YtoAbsPixel(gPad->GetUymin());
00189 Int_t puxmax = gPad->XtoAbsPixel(gPad->GetUxmax());
00190 Int_t puymax = gPad->YtoAbsPixel(gPad->GetUymax());
00191
00192
00193 if (px < puxmin - inaxis) return dist;
00194 if (py > puymin + inaxis) return dist;
00195 if (px > puxmax + inaxis) return dist;
00196 if (py < puymax - inaxis) return dist;
00197
00198
00199
00200
00201 BesView *view = (BesView*)gPad->GetView();
00202 if (!view) return dist;
00203
00204 Bool_t inPolygon = true;
00205 Int_t x1, y1, x2, y2, cx, cy;
00206 Double_t Pndc[3], k, b, pb, cb;
00207
00208 view->WCtoNDC(&fCenter[0], Pndc);
00209 cx = gPad->XtoAbsPixel(Pndc[0]);
00210 cy = gPad->YtoAbsPixel(Pndc[1]);
00211
00212
00213
00214
00215 for (Int_t i = 0; i < fN; i++) {
00216 view->WCtoNDC(&fP[3*i], Pndc);
00217 x1 = gPad->XtoAbsPixel(Pndc[0]);
00218 y1 = gPad->YtoAbsPixel(Pndc[1]);
00219
00220 if (i != fN-1) {
00221 view->WCtoNDC(&fP[3*(i+1)], Pndc);
00222 }
00223 else
00224 view->WCtoNDC(&fP[0], Pndc);
00225
00226 x2 = gPad->XtoAbsPixel(Pndc[0]);
00227 y2 = gPad->YtoAbsPixel(Pndc[1]);
00228
00229
00230
00231 if (x1 == x2) {
00232 if ((px-x1)*(cx-x1) <= 0) {
00233 inPolygon = false;
00234 break;
00235 }
00236 }
00237 else {
00238 k = Double_t(y2-y1)/(x2-x1);
00239 b = y1-k*x1;
00240 pb = py-k*px;
00241 cb = cy-k*cx;
00242 if ((pb-b)*(cb-b) <= 0) {
00243 inPolygon = false;
00244 break;
00245 }
00246 }
00247 }
00248
00249 if (inPolygon == true) {
00250
00251
00252 return 0;
00253 }
00254 else return 9999;
00255
00256
00257
00258 }
00259
00260
00261
00262 void BesPolygon2D::ExecuteEvent(Int_t event, Int_t px, Int_t py) {
00263
00264
00265 BesView *view = (BesView*)gPad->GetView();
00266 if (view) view->ExecuteEvent(event, px, py);
00267 }
00268
00269
00270
00271 void BesPolygon2D::SetInfoBox() {
00272
00273
00274 TView *view = (TView*)gPad->GetView();
00275 Double_t Pndc[3];
00276 view->WCtoNDC(&fP[0], Pndc);
00277
00278 if (fInfoBox){
00279 delete fInfoBox;
00280 fInfoBox = 0;
00281 }
00282 fInfoBox = new TPaveText(Pndc[0], Pndc[1],
00283 Pndc[0]+0.4, Pndc[1]+0.1);
00284 fInfoBox->SetBorderSize(1);
00285 fInfoBox->SetFillColor(191);
00286 fInfoBox->AddText(GetTitle());
00287 fInfoBox->AddText(GetObjectInfo(0,0));
00288 fInfoBox->Draw();
00289 }
00290
00291
00292
00293 char *BesPolygon2D::GetObjectInfo(Int_t px, Int_t py) const {
00294
00295 BesView *view = (BesView*)gPad->GetView();
00296 if (view) return view->GetObjectInfo(px, py);
00297 else return TObject::GetObjectInfo(px, py);
00298 }
00299
00300
00301
00302 void BesPolygon2D::SetZRSign(Int_t sign) {
00303
00304
00305
00306 for ( Int_t i = 0; i < fN; i++ ) {
00307
00308 fP[(i*3)+1] = TMath::Sign(1.,Double_t(fP[(i*3)+1])) * fP[(i*3)+1];
00309
00310
00311 fP[(i*3)+1] = TMath::Sign(1,sign) * fP[(i*3)+1];
00312 }
00313
00314 }
00315
00316
00317
00318 void BesPolygon2D::Resize(Double_t ScaleFactor) {
00319
00320
00321
00322
00323 Double_t C[3];
00324 GetCenter(C);
00325
00326
00327 for ( Int_t i = 0; i < 3; i++ ) {
00328 for ( Int_t j = 0; j < fN; j++ ) {
00329 fP[3*j+i] = C[i] + ScaleFactor*(fP[3*j+i]-C[i]);
00330 }
00331 }
00332 }
00333
00334
00335
00336 void BesPolygon2D::GetCenter(Double_t *Center) const {
00337
00338
00339 for ( Int_t i = 0; i < 3; i++ ) {
00340 Center[i] = 0;
00341 for ( Int_t j = 0; j < fN; j++ ) Center[i] += fP[3*j+i];
00342 Center[i] /= fN;
00343 }
00344 }
00345
00346
00347
00348 void BesPolygon2D::RotatePhi(Double_t phi) {
00349
00350
00351 for (Int_t i = 0; i < fN; i++) {
00352 TVector3 vec(fP[i*3], fP[i*3+1], fP[i*3+2]);
00353 Double_t r = vec.Pt();
00354 Double_t newPhi = vec.Phi() + phi*TMath::DegToRad();
00355 fP[i*3] = r * cos(newPhi);
00356 fP[i*3+1] = r * sin(newPhi);
00357 }
00358 }
00359
00360
00361
00362 void BesPolygon2D::Restore() {
00363
00364 for (Int_t i = 0; i < fN*3; i++) {
00365 fP[i] = fPBackUp[i];
00366 }
00367 }
00368
00369
00370
00371 void BesPolygon2D::SetSize(Double_t size) {
00372
00373 if (size > 0.95) size = 0.98;
00374 if (size < 0.15) size = 0.2;
00375
00376 for (Int_t i = 0; i < 3; i++) {
00377 for (Int_t j = 0; j < fN; j++) {
00378 fP[3*j+i] = size * fP[3*j+i] + (1.0-size) * fCenter[i];
00379 }
00380 }
00381 }
00382