TArrow.cxx

Go to the documentation of this file.
00001 // @(#)root/graf:$Id: TArrow.cxx 35162 2010-09-06 10:28:43Z couet $
00002 // Author: Rene Brun   17/10/95
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 #include "Riostream.h"
00013 #include "TROOT.h"
00014 #include "TMath.h"
00015 #include "TArrow.h"
00016 #include "TVirtualPad.h"
00017 
00018 Float_t TArrow::fgDefaultAngle      = 60;
00019 Float_t TArrow::fgDefaultArrowSize  = 0.05;
00020 TString TArrow::fgDefaultOption     = ">";
00021 
00022 ClassImp(TArrow)
00023 
00024 //______________________________________________________________________________
00025 /* Begin_Html
00026 <center><h2>TArrow : to draw all kinds of arrows</h2></center>
00027 The different arrow's formats are explained in TArrow::TArrow.
00028 The picture below gives some examples.
00029 <P>
00030 Once an arrow is drawn on the screen:
00031 <ul>
00032 <li> One can click on one of the edges and move this edge.</li>
00033 <li> One can click on any other arrow part to move the entire arrow.</li>
00034 </ul>
00035 End_Html
00036 Begin_Macro(source)
00037 ../../../tutorials/graphics/arrow.C
00038 End_Macro */
00039 
00040 //______________________________________________________________________________
00041 TArrow::TArrow(): TLine(),TAttFill()
00042 {
00043    // Arrow default constructor.
00044 
00045    fAngle     = fgDefaultAngle;
00046    fArrowSize = 0.;
00047 }
00048 
00049 //______________________________________________________________________________
00050 TArrow::TArrow(Double_t x1, Double_t y1,Double_t x2, Double_t  y2,
00051              Float_t arrowsize ,Option_t *option)
00052        :TLine(x1,y1,x2,y2), TAttFill(0,1001)
00053 {
00054    // Arrow normal constructor.
00055    //
00056    // Define an arrow between points x1,y1 and x2,y2
00057    // the arrowsize is in percentage of the pad height
00058    // Opening angle between the two sides of the arrow is fAngle (60 degrees)
00059    //
00060    //  option = ">"      -------->
00061    //  option = "|->"    |------->
00062    //  option = "<"      <--------
00063    //  option = "<-|"    <-------|
00064    //  option = "->-"    ---->----
00065    //  option = "-<-"    ----<----
00066    //  option = "-|>-"   ---|>----
00067    //  option = "<>"     <------->
00068    //  option = "<|>"    <|-----|>  arrow defined by a triangle
00069    //
00070    //  Note:
00071    //  - If FillColor == 0 draw open triangle else  draw full triangle with fillcolor
00072    //    default is filled with LineColor
00073    //  - "Begin" and "end" bars can be combined with any other options.
00074 
00075    fAngle       = fgDefaultAngle;
00076    fArrowSize   = arrowsize;
00077    fOption      = option;
00078    SetFillColor(this->GetLineColor());
00079 }
00080 
00081 //______________________________________________________________________________
00082 TArrow::~TArrow()
00083 {
00084    // Arrow default destructor.
00085 }
00086 
00087 //______________________________________________________________________________
00088 TArrow::TArrow(const TArrow &arrow) : TLine(arrow), TAttFill(arrow)
00089 {
00090    // Copy constructor.
00091 
00092    fAngle     = fgDefaultAngle;
00093    fArrowSize = 0.;
00094    ((TArrow&)arrow).Copy(*this);
00095 }
00096 
00097 //______________________________________________________________________________
00098 void TArrow::Copy(TObject &obj) const
00099 {
00100    // Copy this arrow to arrow.
00101 
00102    TLine::Copy(obj);
00103    TAttFill::Copy(((TArrow&)obj));
00104    ((TArrow&)obj).fAngle      = fAngle;
00105    ((TArrow&)obj).fArrowSize  = fArrowSize;
00106    ((TArrow&)obj).fOption     = fOption;
00107 }
00108 
00109 //______________________________________________________________________________
00110 void TArrow::Draw(Option_t *option)
00111 {
00112    // Draw this arrow with its current attributes.
00113 
00114    Option_t *opt;
00115    if (option && strlen(option)) opt = option;
00116    else                          opt = (char*)GetOption();
00117 
00118    AppendPad(opt);
00119 
00120 }
00121 
00122 //______________________________________________________________________________
00123 void TArrow::DrawArrow(Double_t x1, Double_t y1,Double_t x2, Double_t  y2,
00124                      Float_t arrowsize ,Option_t *option)
00125 {
00126    // Draw this arrow with new coordinates.
00127    //
00128    // if arrowsize is <= 0, arrowsize will be the current arrow size
00129    // if option="", option will be the current arrow option
00130 
00131    Float_t size = arrowsize;
00132    if (size <= 0) size = fArrowSize;
00133    if (size <= 0) size = 0.05;
00134    const char* opt = option;
00135    if (!opt || strlen(opt) == 0) opt = fOption.Data();
00136    if (!opt || strlen(opt) == 0) opt = "|>";
00137    TArrow *newarrow = new TArrow(x1,y1,x2,y2,size,opt);
00138    newarrow->SetAngle(fAngle);
00139    TAttLine::Copy(*newarrow);
00140    TAttFill::Copy(*newarrow);
00141    newarrow->SetBit(kCanDelete);
00142    newarrow->AppendPad(opt);
00143 }
00144 
00145 //______________________________________________________________________________
00146 void TArrow::Paint(Option_t *option)
00147 {
00148    // Paint this arrow with its current attributes.
00149 
00150    Option_t *opt;
00151    if (option && strlen(option)) opt = option;
00152    else                          opt = (char*)GetOption();
00153    PaintArrow(gPad->XtoPad(fX1),gPad->YtoPad(fY1),gPad->XtoPad(fX2),gPad->YtoPad(fY2), fArrowSize, opt);
00154 }
00155 
00156 
00157 //______________________________________________________________________________
00158 void TArrow::PaintArrow(Double_t x1, Double_t y1, Double_t x2, Double_t y2,
00159                         Float_t arrowsize, Option_t *option)
00160 {
00161    // Draw this arrow
00162    //
00163    //
00164    //                             +
00165    //                             |.
00166    //                             | .
00167    //                             |  .
00168    //     +-----------------------|---+------------------+
00169    //  (x1,y1)                    |  .                (x2,y2)
00170    //                             | .
00171    //                             |.
00172    //                             +
00173 
00174    Int_t i;
00175 
00176    // Option and attributes
00177    TString opt = option;
00178    opt.ToLower();
00179    TAttLine::Modify();
00180    TAttFill::Modify();
00181 
00182    // Compute the gPad coordinates in TRUE normalized space (NDC)
00183    Int_t ix1,iy1,ix2,iy2;
00184    Int_t iw = gPad->GetWw();
00185    Int_t ih = gPad->GetWh();
00186    Double_t x1p,y1p,x2p,y2p;
00187    gPad->GetPadPar(x1p,y1p,x2p,y2p);
00188    ix1 = (Int_t)(iw*x1p);
00189    iy1 = (Int_t)(ih*y1p);
00190    ix2 = (Int_t)(iw*x2p);
00191    iy2 = (Int_t)(ih*y2p);
00192    Double_t wndc  = TMath::Min(1.,(Double_t)iw/(Double_t)ih);
00193    Double_t hndc  = TMath::Min(1.,(Double_t)ih/(Double_t)iw);
00194    Double_t rh    = hndc/(Double_t)ih;
00195    Double_t rw    = wndc/(Double_t)iw;
00196    Double_t x1ndc = (Double_t)ix1*rw;
00197    Double_t y1ndc = (Double_t)iy1*rh;
00198    Double_t x2ndc = (Double_t)ix2*rw;
00199    Double_t y2ndc = (Double_t)iy2*rh;
00200 
00201    // Ratios to convert user space in TRUE normalized space (NDC)
00202    Double_t rx1,ry1,rx2,ry2;
00203    gPad->GetRange(rx1,ry1,rx2,ry2);
00204    Double_t rx = (x2ndc-x1ndc)/(rx2-rx1);
00205    Double_t ry = (y2ndc-y1ndc)/(ry2-ry1);
00206 
00207    // Arrow position and arrow's middle in NDC space
00208    Double_t x1n, y1n, x2n, y2n, xm, ym;
00209    x1n = rx*(x1-rx1)+x1ndc;
00210    x2n = rx*(x2-rx1)+x1ndc;
00211    y1n = ry*(y1-ry1)+y1ndc;
00212    y2n = ry*(y2-ry1)+y1ndc;
00213    xm  = (x1n+x2n)/2;
00214    ym  = (y1n+y2n)/2;
00215 
00216    // Arrow heads size
00217    Double_t length = TMath::Sqrt(Double_t((x2n-x1n)*(x2n-x1n)+(y2n-y1n)*(y2n-y1n)));
00218    Double_t rSize  = 0.7*arrowsize;
00219    Double_t dSize  = rSize*TMath::Tan(TMath::Pi()*fAngle/360);
00220    Double_t cosT   = 1;
00221    Double_t sinT   = 0;
00222    if (length > 0) {
00223       cosT   = (x2n-x1n)/length;
00224       sinT   = (y2n-y1n)/length;
00225    }
00226    // Arrays holding the arrows coordinates
00227    Double_t x1ar[4], y1ar[4];
00228    Double_t x2ar[4], y2ar[4];
00229 
00230    // Draw the start and end bars if needed
00231    if (opt.BeginsWith("|-")) {
00232       x1ar[0] = x1n-sinT*dSize;
00233       y1ar[0] = y1n+cosT*dSize;
00234       x1ar[1] = x1n+sinT*dSize;
00235       y1ar[1] = y1n-cosT*dSize;
00236       // NDC to user coordinates
00237       for (i=0; i<2; i++) {
00238          x1ar[i] = (1/rx)*(x1ar[i]-x1ndc)+rx1;
00239          y1ar[i] = (1/ry)*(y1ar[i]-y1ndc)+ry1;
00240       }
00241       gPad->PaintLine(x1ar[0],y1ar[0],x1ar[1],y1ar[1]);
00242       opt(0) = ' ';
00243    }
00244    if (opt.EndsWith("-|")) {
00245       x2ar[0] = x2n-sinT*dSize;
00246       y2ar[0] = y2n+cosT*dSize;
00247       x2ar[1] = x2n+sinT*dSize;
00248       y2ar[1] = y2n-cosT*dSize;
00249       // NDC to user coordinates
00250       for (i=0; i<2; i++) {
00251          x2ar[i] = (1/rx)*(x2ar[i]-x1ndc)+rx1;
00252          y2ar[i] = (1/ry)*(y2ar[i]-y1ndc)+ry1;
00253       }
00254       gPad->PaintLine(x2ar[0],y2ar[0],x2ar[1],y2ar[1]);
00255       opt(opt.Length()-1) = ' ';
00256    }
00257 
00258    // Move arrow head's position if needed
00259    Double_t x1h = x1n;
00260    Double_t y1h = y1n;
00261    Double_t x2h = x2n;
00262    Double_t y2h = y2n;
00263    if (opt.Contains("->-") || opt.Contains("-|>-")) {
00264       x2h = xm + cosT*rSize/2;
00265       y2h = ym + sinT*rSize/2;
00266    }
00267    if (opt.Contains("-<-") || opt.Contains("-<|-")) {
00268       x1h = xm - cosT*rSize/2;
00269       y1h = ym - sinT*rSize/2;
00270    }
00271 
00272    // Define the arrow's head coordinates
00273    if (opt.Contains(">")) {
00274       x2ar[0] = x2h - rSize*cosT - sinT*dSize;
00275       y2ar[0] = y2h - rSize*sinT + cosT*dSize;
00276       x2ar[1] = x2h;
00277       y2ar[1] = y2h;
00278       x2ar[2] = x2h - rSize*cosT + sinT*dSize;
00279       y2ar[2] = y2h - rSize*sinT - cosT*dSize;
00280       x2ar[3] = x2ar[0];
00281       y2ar[3] = y2ar[0];
00282    }
00283 
00284    if (opt.Contains("<")) {
00285       x1ar[0] = x1h + rSize*cosT + sinT*dSize;
00286       y1ar[0] = y1h + rSize*sinT - cosT*dSize;
00287       x1ar[1] = x1h;
00288       y1ar[1] = y1h;
00289       x1ar[2] = x1h + rSize*cosT - sinT*dSize;
00290       y1ar[2] = y1h + rSize*sinT + cosT*dSize;
00291       x1ar[3] = x1ar[0];
00292       y1ar[3] = y1ar[0];
00293    }
00294 
00295    // Paint Arrow body
00296    if (opt.Contains("|>") && !opt.Contains("-|>-")) {
00297       x2n = x2n-cosT*rSize;
00298       y2n = y2n-sinT*rSize;
00299    }
00300    if (opt.Contains("<|") && !opt.Contains("-<|-")) {
00301       x1n = x1n+cosT*rSize;
00302       y1n = y1n+sinT*rSize;
00303    }
00304    x1n = (1/rx)*(x1n-x1ndc)+rx1;
00305    y1n = (1/ry)*(y1n-y1ndc)+ry1;
00306    x2n = (1/rx)*(x2n-x1ndc)+rx1;
00307    y2n = (1/ry)*(y2n-y1ndc)+ry1;
00308    gPad->PaintLine(x1n,y1n,x2n,y2n);
00309 
00310    // Draw the arrow's head(s)
00311    if (opt.Contains(">")) {
00312       // NDC to user coordinates
00313       for (i=0; i<4; i++) {
00314          x2ar[i] = (1/rx)*(x2ar[i]-x1ndc)+rx1;
00315          y2ar[i] = (1/ry)*(y2ar[i]-y1ndc)+ry1;
00316       }
00317       if (opt.Contains("|>")) {
00318          if (GetFillColor()) {
00319             gPad->PaintFillArea(3,x2ar,y2ar);
00320             gPad->PaintPolyLine(4,x2ar,y2ar);
00321          } else {
00322             gPad->PaintPolyLine(4,x2ar,y2ar);
00323          }
00324       } else {
00325          gPad->PaintPolyLine(3,x2ar,y2ar);
00326       }
00327    }
00328    if (opt.Contains("<")) {
00329       // NDC to user coordinates
00330       for (i=0; i<4; i++) {
00331          x1ar[i] = (1/rx)*(x1ar[i]-x1ndc)+rx1;
00332          y1ar[i] = (1/ry)*(y1ar[i]-y1ndc)+ry1;
00333       }
00334       if (opt.Contains("<|")) {
00335          if (GetFillColor()) {
00336             gPad->PaintFillArea(3,x1ar,y1ar);
00337             gPad->PaintPolyLine(4,x1ar,y1ar);
00338          } else {
00339             gPad->PaintPolyLine(4,x1ar,y1ar);
00340          }
00341       } else {
00342          gPad->PaintPolyLine(3,x1ar,y1ar);
00343       }
00344    }
00345 }
00346 
00347 //______________________________________________________________________________
00348 void TArrow::SavePrimitive(ostream &out, Option_t * /*= ""*/)
00349 {
00350     // Save primitive as a C++ statement(s) on output stream out
00351 
00352    char quote = '"';
00353    if (gROOT->ClassSaved(TArrow::Class())) {
00354       out<<"   ";
00355    } else {
00356       out<<"   TArrow *";
00357    }
00358    out<<"arrow = new TArrow("<<fX1<<","<<fY1<<","<<fX2<<","<<fY2
00359       <<","<<fArrowSize<<","<<quote<<GetDrawOption()<<quote<<");"<<endl;
00360 
00361    SaveFillAttributes(out,"arrow",0,1);
00362    SaveLineAttributes(out,"arrow",1,1,1);
00363 
00364    if (fAngle !=60) {
00365       out << "   arrow->SetAngle(" << GetAngle() << ");" << endl;
00366    }
00367 
00368    out<<"   arrow->Draw();"<<endl;
00369 }
00370 
00371 
00372 //______________________________________________________________________________
00373 void TArrow::SetDefaultAngle(Float_t Angle)
00374 {
00375    // Set default angle.
00376 
00377    fgDefaultAngle = Angle;
00378 }
00379 
00380 
00381 //______________________________________________________________________________
00382 void TArrow::SetDefaultArrowSize (Float_t ArrowSize)
00383 {
00384    // Set default arrow sive.
00385 
00386    fgDefaultArrowSize = ArrowSize;
00387 }
00388 
00389 
00390 //______________________________________________________________________________
00391 void TArrow::SetDefaultOption(Option_t *Option)
00392 {
00393    // Set default option.
00394 
00395    fgDefaultOption = Option;
00396 }
00397 
00398 
00399 //______________________________________________________________________________
00400 Float_t TArrow::GetDefaultAngle()
00401 {
00402    // Get default angle.
00403 
00404    return fgDefaultAngle;
00405 }
00406 
00407 
00408 //______________________________________________________________________________
00409 Float_t TArrow::GetDefaultArrowSize()
00410 {
00411    // Get default arrow size.
00412 
00413    return fgDefaultArrowSize;
00414 }
00415 
00416 
00417 //______________________________________________________________________________
00418 Option_t *TArrow::GetDefaultOption()
00419 {
00420    // Get default option.
00421 
00422    return fgDefaultOption.Data();
00423 }

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