00001
00002
00003
00004
00005
00006
00007
00008
00009
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
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 TArrow::TArrow(): TLine(),TAttFill()
00042 {
00043
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
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 fAngle = fgDefaultAngle;
00076 fArrowSize = arrowsize;
00077 fOption = option;
00078 SetFillColor(this->GetLineColor());
00079 }
00080
00081
00082 TArrow::~TArrow()
00083 {
00084
00085 }
00086
00087
00088 TArrow::TArrow(const TArrow &arrow) : TLine(arrow), TAttFill(arrow)
00089 {
00090
00091
00092 fAngle = fgDefaultAngle;
00093 fArrowSize = 0.;
00094 ((TArrow&)arrow).Copy(*this);
00095 }
00096
00097
00098 void TArrow::Copy(TObject &obj) const
00099 {
00100
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
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
00127
00128
00129
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
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
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 Int_t i;
00175
00176
00177 TString opt = option;
00178 opt.ToLower();
00179 TAttLine::Modify();
00180 TAttFill::Modify();
00181
00182
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
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
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
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
00227 Double_t x1ar[4], y1ar[4];
00228 Double_t x2ar[4], y2ar[4];
00229
00230
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
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
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
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
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
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
00311 if (opt.Contains(">")) {
00312
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
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
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
00376
00377 fgDefaultAngle = Angle;
00378 }
00379
00380
00381
00382 void TArrow::SetDefaultArrowSize (Float_t ArrowSize)
00383 {
00384
00385
00386 fgDefaultArrowSize = ArrowSize;
00387 }
00388
00389
00390
00391 void TArrow::SetDefaultOption(Option_t *Option)
00392 {
00393
00394
00395 fgDefaultOption = Option;
00396 }
00397
00398
00399
00400 Float_t TArrow::GetDefaultAngle()
00401 {
00402
00403
00404 return fgDefaultAngle;
00405 }
00406
00407
00408
00409 Float_t TArrow::GetDefaultArrowSize()
00410 {
00411
00412
00413 return fgDefaultArrowSize;
00414 }
00415
00416
00417
00418 Option_t *TArrow::GetDefaultOption()
00419 {
00420
00421
00422 return fgDefaultOption.Data();
00423 }