TCurlyLine.cxx

Go to the documentation of this file.
00001 // @(#)root/graf:$Id: TCurlyLine.cxx 35127 2010-09-03 13:09:41Z couet $
00002 // Author: Otto Schaile   20/11/99
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //______________________________________________________________________________
00013 //
00014 // This class implements curly or wavy polylines typically used to draw Feynman diagrams.
00015 // Amplitudes and wavelengths may be specified in the constructors,
00016 // via commands or interactively from popup menus.
00017 // The class make use of TPolyLine by inheritance, ExecuteEvent methods
00018 // are highly inspired from the methods used in TPolyLine and TArc.
00019 // The picture below has been generated by the tutorial feynman.
00020 //Begin_Html
00021 /*
00022 <img src="gif/feynman.gif">
00023 */
00024 //End_Html
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    // Default constructor.
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    // Create a new TCurlyLine with starting point (x1, y1), end point (x2,y2).
00061    // The wavelength and amplitude are given in percent of the pad height.
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    // Create a curly (Gluon) or wavy (Gamma) line.
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    // construct the curly / wavy line in pixel coordinates at angle 0
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    // make sure there is a piece of straight line a both ends
00123 
00124    Double_t  lengthcycle = 0.5 * len2pi + 2 * amplitudePix;
00125    // if (fIsCurly) lengthcycle +=  amplitudePix;
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    // distinguish between curly and wavy
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;  // called by TCurlyArc
00149 
00150    // rotate object and transform back to user coordinates
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    // Compute distance from point px,py to a line.
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    // Execute action corresponding to one event.
00185    //
00186    //  This member function is called when a  TCurlyLine is clicked with the locator
00187    //
00188    //  If Left button clicked on one of the line end points, this point
00189    //     follows the cursor until button is released.
00190    //
00191    //  if Middle button clicked, the line is moved parallel to itself
00192    //     until the button is released.
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();  //Change line attributes only if necessary
00207 
00208       // No break !!!
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); //simply take sum of pixels differences
00220       if (d1 < kMaxDiff) { //*-*================>OK take point number 1
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); //simply take sum of pixels differences
00227       if (d2 < kMaxDiff) { //*-*================>OK take point number 2
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    // Save primitive as a C++ statement(s) on output stream out
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    // Set curly.
00312 
00313    fIsCurly = kTRUE;
00314    Build();
00315 }
00316 
00317 
00318 //______________________________________________________________________________
00319 void TCurlyLine::SetWavy()
00320 {
00321    // Set wavy.
00322 
00323    fIsCurly = kFALSE;
00324    Build();
00325 }
00326 
00327 
00328 //______________________________________________________________________________
00329 void TCurlyLine::SetWaveLength(Double_t x)
00330 {
00331    // Set wave length.
00332 
00333    fWaveLength = x;
00334    Build();
00335 }
00336 
00337 
00338 //______________________________________________________________________________
00339 void TCurlyLine::SetAmplitude(Double_t x)
00340 {
00341    // Set amplitude.
00342 
00343    fAmplitude = x;
00344    Build();
00345 }
00346 
00347 
00348 //______________________________________________________________________________
00349 void TCurlyLine::SetStartPoint(Double_t x, Double_t y)
00350 {
00351    // Set start point.
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    // Set edn point.
00363 
00364    fX2 = x;
00365    fY2 = y;
00366    Build();
00367 }
00368 
00369 
00370 //______________________________________________________________________________
00371 void TCurlyLine::SetDefaultWaveLength(Double_t WaveLength)
00372 {
00373    // Set default wave length.
00374 
00375    fgDefaultWaveLength = WaveLength;
00376 }
00377 
00378 
00379 //______________________________________________________________________________
00380 void TCurlyLine::SetDefaultAmplitude(Double_t Amplitude)
00381 {
00382    // Set default amplitude.
00383 
00384    fgDefaultAmplitude  = Amplitude;
00385 }
00386 
00387 
00388 //______________________________________________________________________________
00389 void TCurlyLine::SetDefaultIsCurly(Bool_t IsCurly)
00390 {
00391    // Set defaul "IsCurly".
00392 
00393    fgDefaultIsCurly    = IsCurly;
00394 }
00395 
00396 
00397 //______________________________________________________________________________
00398 Double_t TCurlyLine::GetDefaultWaveLength()
00399 {
00400    // Get default wave length.
00401 
00402    return fgDefaultWaveLength;
00403 }
00404 
00405 
00406 //______________________________________________________________________________
00407 Double_t TCurlyLine::GetDefaultAmplitude()
00408 {
00409    // Get default amplitude.
00410 
00411    return fgDefaultAmplitude;
00412 }
00413 
00414 
00415 //______________________________________________________________________________
00416 Bool_t TCurlyLine::GetDefaultIsCurly()
00417 {
00418    // Get default "IsCurly".
00419 
00420    return fgDefaultIsCurly;
00421 }

Generated on Tue Jul 5 14:14:27 2011 for ROOT_528-00b_version by  doxygen 1.5.1