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 "TCurlyLine.h"
00029 #include "TROOT.h"
00030 #include "TVirtualPad.h"
00031 #include "TVirtualX.h"
00032 #include "TMath.h"
00033
00034 Double_t TCurlyLine::fgDefaultWaveLength = 0.02;
00035 Double_t TCurlyLine::fgDefaultAmplitude = 0.01;
00036 Bool_t TCurlyLine::fgDefaultIsCurly = kTRUE;
00037
00038 ClassImp(TCurlyLine)
00039
00040
00041
00042 TCurlyLine::TCurlyLine()
00043 {
00044
00045
00046 fX1 = 0.;
00047 fY1 = 0.;
00048 fX2 = 0.;
00049 fY2 = 0.;
00050 fWaveLength = 0.;
00051 fAmplitude = 0.;
00052 fIsCurly = fgDefaultIsCurly;
00053 fNsteps = 0;
00054 }
00055
00056
00057
00058 TCurlyLine::TCurlyLine(Double_t x1, Double_t y1, Double_t x2, Double_t y2, Double_t wl, Double_t amp)
00059 {
00060
00061
00062
00063 fX1 = x1;
00064 fY1 = y1;
00065 fX2 = x2;
00066 fY2 = y2;
00067 fWaveLength = wl;
00068 fAmplitude = amp;
00069 fIsCurly = fgDefaultIsCurly;
00070 Build();
00071 }
00072
00073
00074
00075 void TCurlyLine::Build()
00076 {
00077
00078
00079 Double_t pixeltoX = 1;
00080 Double_t pixeltoY = 1;
00081
00082 Double_t wavelengthPix,amplitudePix, lengthPix, hPix;
00083 Double_t px1, py1, px2, py2;
00084 if (gPad) {
00085 Double_t ww = (Double_t)gPad->GetWw();
00086 Double_t wh = (Double_t)gPad->GetWh();
00087 Double_t pxrange = gPad->GetAbsWNDC()*ww;
00088 Double_t pyrange = - gPad->GetAbsHNDC()*wh;
00089 Double_t xrange = gPad->GetX2() - gPad->GetX1();
00090 Double_t yrange = gPad->GetY2() - gPad->GetY1();
00091 pixeltoX = xrange / pxrange;
00092 pixeltoY = yrange/pyrange;
00093 hPix = TMath::Max(gPad->GetAbsHNDC() * gPad->GetWh(), gPad->GetAbsWNDC() * gPad->GetWw());
00094 px1 = gPad->XtoAbsPixel(fX1);
00095 py1 = gPad->YtoAbsPixel(fY1);
00096 px2 = gPad->XtoAbsPixel(fX2);
00097 py2 = gPad->YtoAbsPixel(fY2);
00098
00099 lengthPix = TMath::Sqrt((px2-px1)*(px2-px1) + (py1-py2)*(py1-py2));
00100 wavelengthPix = hPix*fWaveLength;
00101 amplitudePix = hPix*fAmplitude;
00102 } else {
00103 wavelengthPix = fWaveLength;
00104 amplitudePix = fAmplitude;
00105 px1 = fX1;
00106 py1 = fY1;
00107 px2 = fX2;
00108 py2 = fY2;
00109 lengthPix = TMath::Sqrt((px2-px1)*(px2-px1) + (py1-py2)*(py1-py2));
00110 }
00111 if(lengthPix <= wavelengthPix){
00112 Warning("Build","CurlyLine is too short, length %g is < wavelength: %g ",lengthPix,wavelengthPix);
00113 SetBit(kTooShort);
00114 return;
00115 }
00116
00117 Double_t anglestep = 40;
00118 Double_t phimaxle = TMath::Pi() * 2. / anglestep ;
00119 Double_t dx = wavelengthPix / 40;
00120 Double_t len2pi = dx * anglestep;
00121
00122
00123
00124 Double_t lengthcycle = 0.5 * len2pi + 2 * amplitudePix;
00125
00126 Int_t nperiods = (Int_t)((lengthPix - lengthcycle) / len2pi);
00127 Double_t restlength = 0.5 * (lengthPix - nperiods * len2pi - lengthcycle);
00128 fNsteps = (Int_t)(anglestep * nperiods + anglestep / 2 + 4);
00129 if(fNsteps < 1) fNsteps = 1;
00130 SetPolyLine(fNsteps);
00131 Double_t *xv = GetX();
00132 Double_t *yv = GetY();
00133 xv[0] = 0; yv[0] = 0;
00134 xv[1] = restlength; yv[1] = 0;
00135 Double_t phase = 1.5 * TMath::Pi();
00136 Double_t x0 = amplitudePix + restlength;
00137 Int_t i;
00138 for(i = 2; i < fNsteps-1; i++){
00139
00140 if(fIsCurly) xv[i] = x0 + amplitudePix * TMath::Sin(phase);
00141 else xv[i] = x0;
00142 yv[i] = amplitudePix*TMath::Cos(phase);
00143 phase += phimaxle;
00144 x0 += dx;
00145 }
00146 xv[fNsteps-1] = lengthPix; yv[fNsteps-1] = 0;
00147
00148 if (InheritsFrom("TCurlyArc")) return;
00149
00150
00151 Double_t angle = TMath::ATan2(py2-py1, px2-px1);
00152 if(angle < 0) angle += 2*TMath::Pi();
00153
00154 Double_t cosang = TMath::Cos(angle);
00155 Double_t sinang = TMath::Sin(angle);
00156 Double_t xx, yy;
00157
00158 for(i = 0; i < fNsteps; i++){
00159 xx = xv[i] * cosang - yv[i] * sinang;
00160 yy = xv[i] * sinang + yv[i] * cosang;
00161 if (gPad) {
00162 xx *= pixeltoX;
00163 yy *= pixeltoY;
00164 }
00165 xv[i] = xx + fX1;
00166 yv[i] = yy + fY1;
00167 }
00168 if (gPad) gPad->Modified();
00169 }
00170
00171
00172
00173 Int_t TCurlyLine::DistancetoPrimitive(Int_t px, Int_t py)
00174 {
00175
00176
00177 return DistancetoLine(px,py,fX1,fY1,fX2,fY2);
00178 }
00179
00180
00181
00182 void TCurlyLine::ExecuteEvent(Int_t event, Int_t px, Int_t py)
00183 {
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 Int_t kMaxDiff = 20;
00196 static Int_t d1,d2,px1,px2,py1,py2;
00197 static Int_t pxold, pyold, px1old, py1old, px2old, py2old;
00198 static Bool_t p1, p2, pL;
00199 Int_t dx, dy;
00200
00201
00202 switch (event) {
00203
00204 case kButton1Down:
00205 gVirtualX->SetLineColor(-1);
00206 TAttLine::Modify();
00207
00208
00209
00210 case kMouseMotion:
00211
00212 px1 = gPad->XtoAbsPixel(fX1);
00213 py1 = gPad->YtoAbsPixel(fY1);
00214 px2 = gPad->XtoAbsPixel(fX2);
00215 py2 = gPad->YtoAbsPixel(fY2);
00216
00217 p1 = p2 = pL = kFALSE;
00218
00219 d1 = TMath::Abs(px1 - px) + TMath::Abs(py1-py);
00220 if (d1 < kMaxDiff) {
00221 px1old = px1; py1old = py1;
00222 p1 = kTRUE;
00223 gPad->SetCursor(kPointer);
00224 return;
00225 }
00226 d2 = TMath::Abs(px2 - px) + TMath::Abs(py2-py);
00227 if (d2 < kMaxDiff) {
00228 px2old = px2; py2old = py2;
00229 p2 = kTRUE;
00230 gPad->SetCursor(kPointer);
00231 return;
00232 }
00233
00234 pL = kTRUE;
00235 pxold = px; pyold = py;
00236 gPad->SetCursor(kMove);
00237
00238 break;
00239
00240 case kButton1Motion:
00241
00242 if (p1) {
00243 gVirtualX->DrawLine(px1old, py1old, px2, py2);
00244 gVirtualX->DrawLine(px, py, px2, py2);
00245 px1old = px;
00246 py1old = py;
00247 }
00248 if (p2) {
00249 gVirtualX->DrawLine(px1, py1, px2old, py2old);
00250 gVirtualX->DrawLine(px1, py1, px, py);
00251 px2old = px;
00252 py2old = py;
00253 }
00254 if (pL) {
00255 gVirtualX->DrawLine(px1, py1, px2, py2);
00256 dx = px-pxold; dy = py-pyold;
00257 px1 += dx; py1 += dy; px2 += dx; py2 += dy;
00258 gVirtualX->DrawLine(px1, py1, px2, py2);
00259 pxold = px;
00260 pyold = py;
00261 }
00262 break;
00263
00264 case kButton1Up:
00265
00266 if (p1) {
00267 fX1 = gPad->AbsPixeltoX(px);
00268 fY1 = gPad->AbsPixeltoY(py);
00269 }
00270 if (p2) {
00271 fX2 = gPad->AbsPixeltoX(px);
00272 fY2 = gPad->AbsPixeltoY(py);
00273 }
00274 if (pL) {
00275 fX1 = gPad->AbsPixeltoX(px1);
00276 fY1 = gPad->AbsPixeltoY(py1);
00277 fX2 = gPad->AbsPixeltoX(px2);
00278 fY2 = gPad->AbsPixeltoY(py2);
00279 }
00280 Build();
00281 gPad->Modified();
00282 gVirtualX->SetLineColor(-1);
00283 }
00284 }
00285
00286
00287
00288 void TCurlyLine::SavePrimitive(ostream &out, Option_t * )
00289 {
00290
00291
00292 if (gROOT->ClassSaved(TCurlyLine::Class())) {
00293 out<<" ";
00294 } else {
00295 out<<" TCurlyLine *";
00296 }
00297 out<<"curlyline = new TCurlyLine("
00298 <<fX1<<","<<fY1<<","<<fX2<<","<<fY2<<","
00299 <<fWaveLength<<","<<fAmplitude<<");"<<endl;
00300 if (!fIsCurly) {
00301 out<<" curlyline->SetWavy();"<<endl;
00302 }
00303 SaveLineAttributes(out,"curlyline",1,1,1);
00304 out<<" curlyline->Draw();"<<endl;
00305 }
00306
00307
00308
00309 void TCurlyLine::SetCurly()
00310 {
00311
00312
00313 fIsCurly = kTRUE;
00314 Build();
00315 }
00316
00317
00318
00319 void TCurlyLine::SetWavy()
00320 {
00321
00322
00323 fIsCurly = kFALSE;
00324 Build();
00325 }
00326
00327
00328
00329 void TCurlyLine::SetWaveLength(Double_t x)
00330 {
00331
00332
00333 fWaveLength = x;
00334 Build();
00335 }
00336
00337
00338
00339 void TCurlyLine::SetAmplitude(Double_t x)
00340 {
00341
00342
00343 fAmplitude = x;
00344 Build();
00345 }
00346
00347
00348
00349 void TCurlyLine::SetStartPoint(Double_t x, Double_t y)
00350 {
00351
00352
00353 fX1 = x;
00354 fY1 = y;
00355 Build();
00356 }
00357
00358
00359
00360 void TCurlyLine::SetEndPoint(Double_t x, Double_t y)
00361 {
00362
00363
00364 fX2 = x;
00365 fY2 = y;
00366 Build();
00367 }
00368
00369
00370
00371 void TCurlyLine::SetDefaultWaveLength(Double_t WaveLength)
00372 {
00373
00374
00375 fgDefaultWaveLength = WaveLength;
00376 }
00377
00378
00379
00380 void TCurlyLine::SetDefaultAmplitude(Double_t Amplitude)
00381 {
00382
00383
00384 fgDefaultAmplitude = Amplitude;
00385 }
00386
00387
00388
00389 void TCurlyLine::SetDefaultIsCurly(Bool_t IsCurly)
00390 {
00391
00392
00393 fgDefaultIsCurly = IsCurly;
00394 }
00395
00396
00397
00398 Double_t TCurlyLine::GetDefaultWaveLength()
00399 {
00400
00401
00402 return fgDefaultWaveLength;
00403 }
00404
00405
00406
00407 Double_t TCurlyLine::GetDefaultAmplitude()
00408 {
00409
00410
00411 return fgDefaultAmplitude;
00412 }
00413
00414
00415
00416 Bool_t TCurlyLine::GetDefaultIsCurly()
00417 {
00418
00419
00420 return fgDefaultIsCurly;
00421 }