00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "Riostream.h"
00028 #include "TCurlyArc.h"
00029 #include "TROOT.h"
00030 #include "TVirtualPad.h"
00031 #include "TVirtualX.h"
00032 #include "TMath.h"
00033
00034 Double_t TCurlyArc::fgDefaultWaveLength = 0.02;
00035 Double_t TCurlyArc::fgDefaultAmplitude = 0.01;
00036 Bool_t TCurlyArc::fgDefaultIsCurly = kTRUE;
00037
00038 ClassImp(TCurlyArc)
00039
00040
00041
00042 TCurlyArc::TCurlyArc(Double_t x1, Double_t y1,
00043 Double_t rad, Double_t phimin, Double_t phimax,
00044 Double_t wl, Double_t amp)
00045 : fR1(rad), fPhimin(phimin),fPhimax(phimax)
00046 {
00047
00048
00049
00050
00051 fX1 = x1;
00052 fY1 = y1;
00053 fIsCurly = fgDefaultIsCurly;
00054 fAmplitude = amp;
00055 fWaveLength = wl;
00056 fTheta = 0;
00057 Build();
00058 }
00059
00060
00061
00062 void TCurlyArc::Build()
00063 {
00064
00065
00066 Double_t pixeltoX = 1;
00067 Double_t pixeltoY = 1;
00068 Double_t rPix = fR1;
00069 if (gPad) {
00070 Double_t ww = (Double_t)gPad->GetWw();
00071 Double_t wh = (Double_t)gPad->GetWh();
00072 Double_t pxrange = gPad->GetAbsWNDC()*ww;
00073 Double_t pyrange = - gPad->GetAbsHNDC()*wh;
00074 Double_t xrange = gPad->GetX2() - gPad->GetX1();
00075 Double_t yrange = gPad->GetY2() - gPad->GetY1();
00076 pixeltoX = xrange / pxrange;
00077 pixeltoY = yrange/pyrange;
00078 rPix = fR1 / pixeltoX;
00079 }
00080 Double_t dang = fPhimax - fPhimin;
00081 if(dang < 0) dang += 360;
00082 Double_t length = TMath::Pi() * fR1 * dang/180;
00083 Double_t x1sav = fX1;
00084 Double_t y1sav = fY1;
00085 fX1 = fY1 = 0;
00086 fX2 = length;
00087 fY2 = 0;
00088 TCurlyLine::Build();
00089 fX1 = x1sav;
00090 fY1 = y1sav;
00091 Double_t *xv= GetX();
00092 Double_t *yv= GetY();
00093 Double_t xx, yy, angle;
00094 for(Int_t i = 0; i < fNsteps; i++){
00095 angle = xv[i] / rPix + fPhimin * TMath::Pi()/180;
00096 xx = (yv[i] + rPix) * cos(angle);
00097 yy = (yv[i] + rPix) * sin(angle);
00098 xx *= pixeltoX;
00099 yy *= TMath::Abs(pixeltoY);
00100 xv[i] = xx + fX1;
00101 yv[i] = yy + fY1;
00102 }
00103 if (gPad) gPad->Modified();
00104 }
00105
00106
00107
00108 Int_t TCurlyArc::DistancetoPrimitive(Int_t px, Int_t py)
00109 {
00110
00111
00112
00113
00114
00115
00116
00117 Int_t pxc = gPad->XtoAbsPixel(fX1);
00118 Int_t pyc = gPad->YtoAbsPixel(fY1);
00119 Double_t dist = TMath::Sqrt(Double_t((pxc-px)*(pxc-px)+(pyc-py)*(pyc-py)));
00120 Double_t cosa = (px - pxc)/dist;
00121 Double_t sina = (pyc - py)/dist;
00122 Double_t phi = TMath::ATan2(sina,cosa);
00123 if(phi < 0) phi += 2 * TMath::Pi();
00124 phi = phi * 180 / TMath::Pi();
00125 if(fPhimax > fPhimin){
00126 if(phi < fPhimin || phi > fPhimax) return 9999;
00127 } else {
00128 if(phi > fPhimin && phi < fPhimax) return 9999;
00129 }
00130 Int_t pxr = gPad->XtoPixel(fR1)- gPad->XtoPixel(0);
00131 Double_t distr = TMath::Abs(dist-pxr);
00132 return Int_t(distr);
00133 }
00134
00135
00136
00137 void TCurlyArc::ExecuteEvent(Int_t event, Int_t px, Int_t py)
00138 {
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 Int_t kMaxDiff = 10;
00150 const Int_t np = 10;
00151 const Double_t pi = 3.141592;
00152 static Int_t x[np+3], y[np+3];
00153 static Int_t px1,py1,npe,r1;
00154 static Int_t pxold, pyold;
00155 Int_t i, dpx, dpy;
00156 Double_t angle,dx,dy,dphi,rTy,rBy,rLx,rRx;
00157 Double_t phi0;
00158 static Bool_t pTop, pL, pR, pBot, pINSIDE;
00159 static Int_t pTx,pTy,pLx,pLy,pRx,pRy,pBx,pBy;
00160
00161 switch (event) {
00162
00163 case kButton1Down:
00164 gVirtualX->SetLineColor(-1);
00165 TAttLine::Modify();
00166 dphi = (fPhimax-fPhimin) * pi / 180;
00167 if(dphi<0) dphi += 2 * pi;
00168 dphi /= np;
00169 phi0 = fPhimin * pi / 180;
00170 for (i=0;i<=np;i++) {
00171 angle = Double_t(i)*dphi + phi0;
00172 dx = fR1*TMath::Cos(angle);
00173 dy = fR1*TMath::Sin(angle);
00174 Int_t rpixY = gPad->XtoAbsPixel(dy) - gPad->XtoAbsPixel(0);
00175 x[i] = gPad->XtoAbsPixel(fX1 + dx);
00176 y[i] = gPad->YtoAbsPixel(fY1) + rpixY;
00177 }
00178 if (fPhimax-fPhimin >= 360 ) {
00179 x[np+1] = x[0];
00180 y[np+1] = y[0];
00181 npe = np;
00182 } else {
00183 x[np+1] = gPad->XtoAbsPixel(fX1);
00184 y[np+1] = gPad->YtoAbsPixel(fY1);
00185 x[np+2] = x[0];
00186 y[np+2] = y[0];
00187 npe = np + 2;
00188 }
00189 px1 = gPad->XtoAbsPixel(fX1);
00190 py1 = gPad->YtoAbsPixel(fY1);
00191 pTx = pBx = px1;
00192 pLy = pRy = py1;
00193 pLx = gPad->XtoAbsPixel(-fR1+fX1);
00194 pRx = gPad->XtoAbsPixel( fR1+fX1);
00195 r1 = TMath::Abs(pLx-pRx)/2;
00196
00197 pTy = gPad->YtoAbsPixel(fY1) + r1;
00198 pBy = gPad->YtoAbsPixel(fY1) - r1;
00199
00200 gVirtualX->DrawLine(pRx+4, py1+4, pRx-4, py1+4);
00201 gVirtualX->DrawLine(pRx-4, py1+4, pRx-4, py1-4);
00202 gVirtualX->DrawLine(pRx-4, py1-4, pRx+4, py1-4);
00203 gVirtualX->DrawLine(pRx+4, py1-4, pRx+4, py1+4);
00204 gVirtualX->DrawLine(pLx+4, py1+4, pLx-4, py1+4);
00205 gVirtualX->DrawLine(pLx-4, py1+4, pLx-4, py1-4);
00206 gVirtualX->DrawLine(pLx-4, py1-4, pLx+4, py1-4);
00207 gVirtualX->DrawLine(pLx+4, py1-4, pLx+4, py1+4);
00208 gVirtualX->DrawLine(px1+4, pBy+4, px1-4, pBy+4);
00209 gVirtualX->DrawLine(px1-4, pBy+4, px1-4, pBy-4);
00210 gVirtualX->DrawLine(px1-4, pBy-4, px1+4, pBy-4);
00211 gVirtualX->DrawLine(px1+4, pBy-4, px1+4, pBy+4);
00212 gVirtualX->DrawLine(px1+4, pTy+4, px1-4, pTy+4);
00213 gVirtualX->DrawLine(px1-4, pTy+4, px1-4, pTy-4);
00214 gVirtualX->DrawLine(px1-4, pTy-4, px1+4, pTy-4);
00215 gVirtualX->DrawLine(px1+4, pTy-4, px1+4, pTy+4);
00216
00217
00218 case kMouseMotion:
00219 px1 = gPad->XtoAbsPixel(fX1);
00220 py1 = gPad->YtoAbsPixel(fY1);
00221 pTx = pBx = px1;
00222 pLy = pRy = py1;
00223 pLx = gPad->XtoAbsPixel(-fR1+fX1);
00224 pRx = gPad->XtoAbsPixel( fR1+fX1);
00225
00226 pTy = gPad->YtoAbsPixel(fY1) + TMath::Abs(pLx-pRx)/2;
00227 pBy = gPad->YtoAbsPixel(fY1) - TMath::Abs(pLx-pRx)/2;
00228
00229 pTop = pL = pR = pBot = pINSIDE = kFALSE;
00230 if ((TMath::Abs(px - pTx) < kMaxDiff) &&
00231 (TMath::Abs(py - pTy) < kMaxDiff)) {
00232 pTop = kTRUE;
00233 gPad->SetCursor(kTopSide);
00234 }
00235 else
00236 if ((TMath::Abs(px - pBx) < kMaxDiff) &&
00237 (TMath::Abs(py - pBy) < kMaxDiff)) {
00238 pBot = kTRUE;
00239 gPad->SetCursor(kBottomSide);
00240 }
00241 else
00242 if ((TMath::Abs(py - pLy) < kMaxDiff) &&
00243 (TMath::Abs(px - pLx) < kMaxDiff)) {
00244 pL = kTRUE;
00245 gPad->SetCursor(kLeftSide);
00246 }
00247 else
00248 if ((TMath::Abs(py - pRy) < kMaxDiff) &&
00249 (TMath::Abs(px - pRx) < kMaxDiff)) {
00250 pR = kTRUE;
00251 gPad->SetCursor(kRightSide);
00252 }
00253 else {pINSIDE= kTRUE; gPad->SetCursor(kMove); }
00254 pxold = px; pyold = py;
00255
00256 break;
00257
00258 case kButton1Motion:
00259 gVirtualX->DrawLine(pRx+4, py1+4, pRx-4, py1+4);
00260 gVirtualX->DrawLine(pRx-4, py1+4, pRx-4, py1-4);
00261 gVirtualX->DrawLine(pRx-4, py1-4, pRx+4, py1-4);
00262 gVirtualX->DrawLine(pRx+4, py1-4, pRx+4, py1+4);
00263 gVirtualX->DrawLine(pLx+4, py1+4, pLx-4, py1+4);
00264 gVirtualX->DrawLine(pLx-4, py1+4, pLx-4, py1-4);
00265 gVirtualX->DrawLine(pLx-4, py1-4, pLx+4, py1-4);
00266 gVirtualX->DrawLine(pLx+4, py1-4, pLx+4, py1+4);
00267 gVirtualX->DrawLine(px1+4, pBy+4, px1-4, pBy+4);
00268 gVirtualX->DrawLine(px1-4, pBy+4, px1-4, pBy-4);
00269 gVirtualX->DrawLine(px1-4, pBy-4, px1+4, pBy-4);
00270 gVirtualX->DrawLine(px1+4, pBy-4, px1+4, pBy+4);
00271 gVirtualX->DrawLine(px1+4, pTy+4, px1-4, pTy+4);
00272 gVirtualX->DrawLine(px1-4, pTy+4, px1-4, pTy-4);
00273 gVirtualX->DrawLine(px1-4, pTy-4, px1+4, pTy-4);
00274 gVirtualX->DrawLine(px1+4, pTy-4, px1+4, pTy+4);
00275 for (i=0;i<npe;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
00276 if (pTop) {
00277 r1 -= (py - pyold);
00278 }
00279 if (pBot) {
00280 r1 += (py - pyold);
00281 }
00282 if (pL) {
00283 r1 -= (px - pxold);
00284 }
00285 if (pR) {
00286 r1 += (px - pxold);
00287 }
00288 if (pTop || pBot || pL || pR) {
00289 gVirtualX->SetLineColor(-1);
00290 TAttLine::Modify();
00291 dphi = (fPhimax-fPhimin) * pi / 180;
00292 if(dphi<0) dphi += 2 * pi;
00293 dphi /= np;
00294 phi0 = fPhimin * pi / 180;
00295 Double_t ur1 = r1;
00296 Int_t pX1 = gPad->XtoAbsPixel(fX1);
00297 Int_t pY1 = gPad->YtoAbsPixel(fY1);
00298 for (i=0;i<=np;i++) {
00299 angle = Double_t(i)*dphi + phi0;
00300 dx = ur1 * TMath::Cos(angle);
00301 dy = ur1 * TMath::Sin(angle);
00302 x[i] = pX1 + (Int_t)dx;
00303 y[i] = pY1 + (Int_t)dy;
00304 }
00305 if (fPhimax-fPhimin >= 360 ) {
00306 x[np+1] = x[0];
00307 y[np+1] = y[0];
00308 npe = np;
00309 } else {
00310 x[np+1] = pX1;
00311 y[np+1] = pY1;
00312 x[np+2] = x[0];
00313 y[np+2] = y[0];
00314 npe = np + 2;
00315 }
00316 for (i=0;i<npe;i++) {
00317 gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
00318 }
00319 }
00320 if (pINSIDE) {
00321 dpx = px-pxold; dpy = py-pyold;
00322 px1 += dpx; py1 += dpy;
00323 for (i=0;i<=npe;i++) { x[i] += dpx; y[i] += dpy;}
00324 for (i=0;i<npe;i++) gVirtualX->DrawLine(x[i], y[i], x[i+1], y[i+1]);
00325 }
00326 pTx = pBx = px1;
00327 pRx = px1+r1;
00328 pLx = px1-r1;
00329 pRy = pLy = py1;
00330 pTy = py1-r1;
00331 pBy = py1+r1;
00332 gVirtualX->DrawLine(pRx+4, py1+4, pRx-4, py1+4);
00333 gVirtualX->DrawLine(pRx-4, py1+4, pRx-4, py1-4);
00334 gVirtualX->DrawLine(pRx-4, py1-4, pRx+4, py1-4);
00335 gVirtualX->DrawLine(pRx+4, py1-4, pRx+4, py1+4);
00336 gVirtualX->DrawLine(pLx+4, py1+4, pLx-4, py1+4);
00337 gVirtualX->DrawLine(pLx-4, py1+4, pLx-4, py1-4);
00338 gVirtualX->DrawLine(pLx-4, py1-4, pLx+4, py1-4);
00339 gVirtualX->DrawLine(pLx+4, py1-4, pLx+4, py1+4);
00340 gVirtualX->DrawLine(px1+4, pBy+4, px1-4, pBy+4);
00341 gVirtualX->DrawLine(px1-4, pBy+4, px1-4, pBy-4);
00342 gVirtualX->DrawLine(px1-4, pBy-4, px1+4, pBy-4);
00343 gVirtualX->DrawLine(px1+4, pBy-4, px1+4, pBy+4);
00344 gVirtualX->DrawLine(px1+4, pTy+4, px1-4, pTy+4);
00345 gVirtualX->DrawLine(px1-4, pTy+4, px1-4, pTy-4);
00346 gVirtualX->DrawLine(px1-4, pTy-4, px1+4, pTy-4);
00347 gVirtualX->DrawLine(px1+4, pTy-4, px1+4, pTy+4);
00348 pxold = px;
00349 pyold = py;
00350 break;
00351
00352 case kButton1Up:
00353 fX1 = gPad->AbsPixeltoX(px1);
00354 fY1 = gPad->AbsPixeltoY(py1);
00355 rBy = gPad->AbsPixeltoY(py1+r1);
00356 rTy = gPad->AbsPixeltoY(py1-r1);
00357 rLx = gPad->AbsPixeltoX(px1+r1);
00358 rRx = gPad->AbsPixeltoX(px1-r1);
00359 fR1 = TMath::Abs(rRx-rLx)/2;
00360 Build();
00361 gPad->Modified(kTRUE);
00362 gVirtualX->SetLineColor(-1);
00363 }
00364 }
00365
00366
00367
00368 void TCurlyArc::SavePrimitive(ostream &out, Option_t * )
00369 {
00370
00371
00372 if (gROOT->ClassSaved(TCurlyArc::Class())) {
00373 out<<" ";
00374 } else {
00375 out<<" TCurlyArc *";
00376 }
00377 out<<"curlyarc = new TCurlyArc("
00378 <<fX1<<","<<fY1<<","<<fR1<<","<<fPhimin<<","<<fPhimax<<","
00379 <<fWaveLength<<","<<fAmplitude<<");"<<endl;
00380 if (!fIsCurly) {
00381 out<<" curlyarc->SetWavy();"<<endl;
00382 }
00383 SaveLineAttributes(out,"curlyarc",1,1,1);
00384 out<<" curlyarc->Draw();"<<endl;
00385 }
00386
00387
00388
00389 void TCurlyArc::SetCenter(Double_t x, Double_t y)
00390 {
00391
00392
00393 fX1 = x;
00394 fY1 = y;
00395 Build();
00396 }
00397
00398
00399
00400 void TCurlyArc::SetRadius(Double_t x)
00401 {
00402
00403
00404 fR1 = x;
00405 Build();
00406 }
00407
00408
00409
00410 void TCurlyArc::SetPhimin(Double_t x)
00411 {
00412
00413
00414 fPhimin = x;
00415 Build();
00416 }
00417
00418
00419
00420 void TCurlyArc::SetPhimax(Double_t x)
00421 {
00422
00423
00424 fPhimax = x;
00425 Build();
00426 }
00427
00428
00429
00430 void TCurlyArc::SetDefaultWaveLength(Double_t WaveLength)
00431 {
00432
00433
00434 fgDefaultWaveLength = WaveLength;
00435 }
00436
00437
00438
00439 void TCurlyArc::SetDefaultAmplitude(Double_t Amplitude)
00440 {
00441
00442
00443 fgDefaultAmplitude = Amplitude ;
00444 }
00445
00446
00447
00448 void TCurlyArc::SetDefaultIsCurly(Bool_t IsCurly)
00449 {
00450
00451
00452 fgDefaultIsCurly = IsCurly;
00453 }
00454
00455
00456
00457 Double_t TCurlyArc::GetDefaultWaveLength()
00458 {
00459
00460
00461 return fgDefaultWaveLength;
00462 }
00463
00464
00465
00466 Double_t TCurlyArc::GetDefaultAmplitude()
00467 {
00468
00469
00470 return fgDefaultAmplitude;
00471 }
00472
00473
00474
00475 Bool_t TCurlyArc::GetDefaultIsCurly()
00476 {
00477
00478
00479 return fgDefaultIsCurly;
00480 }