00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <stdlib.h>
00013
00014 #include "Riostream.h"
00015 #include "TROOT.h"
00016 #include "TLine.h"
00017 #include "TVirtualPad.h"
00018 #include "TClass.h"
00019 #include "TVirtualX.h"
00020 #include "TMath.h"
00021
00022
00023 ClassImp(TLine)
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 TLine::TLine(): TObject(), TAttLine()
00034 {
00035
00036
00037 fX1=0; fY1=0; fX2=0; fY2=0;
00038 }
00039
00040
00041
00042 TLine::TLine(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
00043 :TObject(), TAttLine()
00044 {
00045
00046
00047 fX1=x1; fY1=y1; fX2=x2; fY2=y2;
00048 }
00049
00050
00051
00052 TLine::~TLine()
00053 {
00054
00055 }
00056
00057
00058
00059 TLine::TLine(const TLine &line) : TObject(line), TAttLine(line)
00060 {
00061
00062
00063 fX1=0; fY1=0; fX2=0; fY2=0;
00064 ((TLine&)line).Copy(*this);
00065 }
00066
00067
00068
00069 void TLine::Copy(TObject &obj) const
00070 {
00071
00072
00073 TObject::Copy(obj);
00074 TAttLine::Copy(((TLine&)obj));
00075 ((TLine&)obj).fX1 = fX1;
00076 ((TLine&)obj).fY1 = fY1;
00077 ((TLine&)obj).fX2 = fX2;
00078 ((TLine&)obj).fY2 = fY2;
00079 }
00080
00081
00082
00083 Int_t TLine::DistancetoPrimitive(Int_t px, Int_t py)
00084 {
00085
00086
00087 if (!TestBit(kLineNDC)) return DistancetoLine(px,py,gPad->XtoPad(fX1),gPad->YtoPad(fY1),gPad->XtoPad(fX2),gPad->YtoPad(fY2));
00088 Double_t x1 = gPad->GetX1() + fX1*(gPad->GetX2()-gPad->GetX1());
00089 Double_t y1 = gPad->GetY1() + fY1*(gPad->GetY2()-gPad->GetY1());
00090 Double_t x2 = gPad->GetX1() + fX2*(gPad->GetX2()-gPad->GetX1());
00091 Double_t y2 = gPad->GetY1() + fY2*(gPad->GetY2()-gPad->GetY1());
00092 return DistancetoLine(px,py,x1,y1,x2,y2);
00093 }
00094
00095
00096
00097 TLine *TLine::DrawLine(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
00098 {
00099
00100
00101 TLine *newline = new TLine(x1, y1, x2, y2);
00102 TAttLine::Copy(*newline);
00103 newline->SetBit(kCanDelete);
00104 newline->AppendPad();
00105 return newline;
00106 }
00107
00108
00109
00110 TLine *TLine::DrawLineNDC(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
00111 {
00112
00113
00114 TLine *newline = DrawLine(x1, y1, x2, y2);
00115 newline->SetBit(kLineNDC);
00116 return newline;
00117 }
00118
00119
00120
00121 void TLine::ExecuteEvent(Int_t event, Int_t px, Int_t py)
00122 {
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132 Int_t kMaxDiff = 20;
00133 static Int_t d1,d2,px1,px2,py1,py2;
00134 static Int_t pxold, pyold, px1old, py1old, px2old, py2old;
00135 static Bool_t p1, p2, pL;
00136 Double_t dpx,dpy,xp1,yp1;
00137 Int_t dx, dy;
00138
00139 if (!gPad->IsEditable()) return;
00140
00141 switch (event) {
00142
00143 case kButton1Down:
00144 gVirtualX->SetLineColor(-1);
00145 TAttLine::Modify();
00146
00147
00148
00149 case kMouseMotion:
00150
00151 if (TestBit(kLineNDC)) {
00152 px1 = gPad->UtoPixel(fX1);
00153 py1 = gPad->VtoPixel(fY1);
00154 px2 = gPad->UtoPixel(fX2);
00155 py2 = gPad->VtoPixel(fY2);
00156 } else {
00157 px1 = gPad->XtoAbsPixel(gPad->XtoPad(fX1));
00158 py1 = gPad->YtoAbsPixel(gPad->YtoPad(fY1));
00159 px2 = gPad->XtoAbsPixel(gPad->XtoPad(fX2));
00160 py2 = gPad->YtoAbsPixel(gPad->YtoPad(fY2));
00161 }
00162 p1 = p2 = pL = kFALSE;
00163
00164 d1 = abs(px1 - px) + abs(py1-py);
00165 if (d1 < kMaxDiff) {
00166 px1old = px1; py1old = py1;
00167 p1 = kTRUE;
00168 gPad->SetCursor(kPointer);
00169 return;
00170 }
00171 d2 = abs(px2 - px) + abs(py2-py);
00172 if (d2 < kMaxDiff) {
00173 px2old = px2; py2old = py2;
00174 p2 = kTRUE;
00175 gPad->SetCursor(kPointer);
00176 return;
00177 }
00178
00179 pL = kTRUE;
00180 pxold = px; pyold = py;
00181 gPad->SetCursor(kMove);
00182
00183 break;
00184
00185 case kButton1Motion:
00186
00187 if (p1) {
00188 gVirtualX->DrawLine(px1old, py1old, px2, py2);
00189 gVirtualX->DrawLine(px, py, px2, py2);
00190 px1old = px;
00191 py1old = py;
00192 }
00193 if (p2) {
00194 gVirtualX->DrawLine(px1, py1, px2old, py2old);
00195 gVirtualX->DrawLine(px1, py1, px, py);
00196 px2old = px;
00197 py2old = py;
00198 }
00199 if (pL) {
00200 gVirtualX->DrawLine(px1, py1, px2, py2);
00201 dx = px-pxold; dy = py-pyold;
00202 px1 += dx; py1 += dy; px2 += dx; py2 += dy;
00203 gVirtualX->DrawLine(px1, py1, px2, py2);
00204 pxold = px;
00205 pyold = py;
00206 }
00207 break;
00208
00209 case kButton1Up:
00210
00211 if (gROOT->IsEscaped()) {
00212 gROOT->SetEscape(kFALSE);
00213 break;
00214 }
00215
00216 if (TestBit(kLineNDC)) {
00217 dpx = gPad->GetX2() - gPad->GetX1();
00218 dpy = gPad->GetY2() - gPad->GetY1();
00219 xp1 = gPad->GetX1();
00220 yp1 = gPad->GetY1();
00221 if (p1) {
00222 fX1 = (gPad->AbsPixeltoX(px)-xp1)/dpx;
00223 fY1 = (gPad->AbsPixeltoY(py)-yp1)/dpy;
00224 }
00225 if (p2) {
00226 fX2 = (gPad->AbsPixeltoX(px)-xp1)/dpx;
00227 fY2 = (gPad->AbsPixeltoY(py)-yp1)/dpy;
00228 }
00229 if (pL) {
00230 fX1 = (gPad->AbsPixeltoX(px1)-xp1)/dpx;
00231 fY1 = (gPad->AbsPixeltoY(py1)-yp1)/dpy;
00232 fX2 = (gPad->AbsPixeltoX(px2)-xp1)/dpx;
00233 fY2 = (gPad->AbsPixeltoY(py2)-yp1)/dpy;
00234 }
00235 } else {
00236 if (p1) {
00237 fX1 = gPad->PadtoX(gPad->AbsPixeltoX(px));
00238 fY1 = gPad->PadtoY(gPad->AbsPixeltoY(py));
00239 }
00240 if (p2) {
00241 fX2 = gPad->PadtoX(gPad->AbsPixeltoX(px));
00242 fY2 = gPad->PadtoY(gPad->AbsPixeltoY(py));
00243 }
00244 if (pL) {
00245 fX1 = gPad->PadtoX(gPad->AbsPixeltoX(px1));
00246 fY1 = gPad->PadtoY(gPad->AbsPixeltoY(py1));
00247 fX2 = gPad->PadtoX(gPad->AbsPixeltoX(px2));
00248 fY2 = gPad->PadtoY(gPad->AbsPixeltoY(py2));
00249 }
00250 }
00251 if (TestBit(kVertical)) {
00252 if (p1) fX2 = fX1;
00253 if (p2) fX1 = fX2;
00254 }
00255 if (TestBit(kHorizontal)) {
00256 if (p1) fY2 = fY1;
00257 if (p2) fY1 = fY2;
00258 }
00259 gPad->Modified(kTRUE);
00260 gVirtualX->SetLineColor(-1);
00261 break;
00262
00263 case kButton1Locate:
00264
00265 ExecuteEvent(kButton1Down, px, py);
00266 while (1) {
00267 px = py = 0;
00268 event = gVirtualX->RequestLocator(1,1,px,py);
00269
00270 ExecuteEvent(kButton1Motion, px, py);
00271
00272 if (event != -1) {
00273 ExecuteEvent(kButton1Up, px, py);
00274 return;
00275 }
00276 }
00277 }
00278 }
00279
00280
00281
00282 void TLine::ls(Option_t *) const
00283 {
00284
00285
00286 TROOT::IndentLevel();
00287 printf("%s X1=%f Y1=%f X2=%f Y2=%f\n",IsA()->GetName(),fX1,fY1,fX2,fY2);
00288 }
00289
00290
00291
00292 void TLine::Paint(Option_t *)
00293 {
00294
00295
00296 if (TestBit(kLineNDC)) PaintLineNDC(fX1,fY1,fX2,fY2);
00297 else PaintLine(gPad->XtoPad(fX1),gPad->YtoPad(fY1),gPad->XtoPad(fX2),gPad->YtoPad(fY2));
00298 }
00299
00300
00301
00302 void TLine::PaintLine(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
00303 {
00304
00305
00306 TAttLine::Modify();
00307 gPad->PaintLine(x1,y1,x2,y2);
00308 }
00309
00310
00311
00312 void TLine::PaintLineNDC(Double_t u1, Double_t v1, Double_t u2, Double_t v2)
00313 {
00314
00315
00316 TAttLine::Modify();
00317 gPad->PaintLineNDC(u1,v1,u2,v2);
00318 }
00319
00320
00321
00322 void TLine::Print(Option_t *) const
00323 {
00324
00325
00326 printf("%s X1=%f Y1=%f X2=%f Y2=%f",IsA()->GetName(),fX1,fY1,fX2,fY2);
00327 if (GetLineColor() != 1) printf(" Color=%d",GetLineColor());
00328 if (GetLineStyle() != 1) printf(" Style=%d",GetLineStyle());
00329 if (GetLineWidth() != 1) printf(" Width=%d",GetLineWidth());
00330 printf("\n");
00331 }
00332
00333
00334
00335 void TLine::SavePrimitive(ostream &out, Option_t * )
00336 {
00337
00338
00339 if (gROOT->ClassSaved(TLine::Class())) {
00340 out<<" ";
00341 } else {
00342 out<<" TLine *";
00343 }
00344 out<<"line = new TLine("<<fX1<<","<<fY1<<","<<fX2<<","<<fY2
00345 <<");"<<endl;
00346
00347 SaveLineAttributes(out,"line",1,1,1);
00348
00349 out<<" line->Draw();"<<endl;
00350 }
00351
00352
00353
00354 Bool_t TLine::IsHorizontal()
00355 {
00356
00357
00358 return TestBit(kHorizontal);
00359 }
00360
00361
00362
00363 Bool_t TLine::IsVertical()
00364 {
00365
00366
00367 return TestBit(kVertical);
00368 }
00369
00370
00371
00372 void TLine::SetHorizontal(Bool_t set )
00373 {
00374
00375
00376
00377
00378 SetBit(kHorizontal, set);
00379 if (set) {
00380 SetVertical(kFALSE);
00381 Int_t px1 = gPad->XtoAbsPixel(fX1);
00382 Int_t px2 = gPad->XtoAbsPixel(fX2);
00383 Int_t py1 = gPad->YtoAbsPixel(fY1);
00384 Int_t py2 = gPad->YtoAbsPixel(fY2);
00385 Int_t l = Int_t(TMath::Sqrt((px2-px1)*(px2-px1)+(py2-py1)*(py2-py1)));
00386 if (fX2 >= fX1) fX2 = gPad->AbsPixeltoX(px1+l);
00387 else fX2 = gPad->AbsPixeltoX(px1-l);
00388 fY2 = fY1;
00389 }
00390 }
00391
00392
00393
00394 void TLine::SetVertical(Bool_t set )
00395 {
00396
00397
00398
00399
00400 SetBit(kVertical, set);
00401 if (set) {
00402 SetHorizontal(kFALSE);
00403 Int_t px1 = gPad->XtoAbsPixel(fX1);
00404 Int_t px2 = gPad->XtoAbsPixel(fX2);
00405 Int_t py1 = gPad->YtoAbsPixel(fY1);
00406 Int_t py2 = gPad->YtoAbsPixel(fY2);
00407 Int_t l = Int_t(TMath::Sqrt((px2-px1)*(px2-px1)+(py2-py1)*(py2-py1)));
00408 if (fY2 >= fY1) fY2 = gPad->AbsPixeltoY(py1-l);
00409 else fY2 = gPad->AbsPixeltoY(py1+l);
00410 fX2 = fX1;
00411 }
00412 }
00413
00414
00415
00416 void TLine::Streamer(TBuffer &R__b)
00417 {
00418
00419
00420 if (R__b.IsReading()) {
00421 UInt_t R__s, R__c;
00422 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
00423 if (R__v > 1) {
00424 R__b.ReadClassBuffer(TLine::Class(), this, R__v, R__s, R__c);
00425 return;
00426 }
00427
00428 TObject::Streamer(R__b);
00429 TAttLine::Streamer(R__b);
00430 Float_t x1,y1,x2,y2;
00431 R__b >> x1; fX1 = x1;
00432 R__b >> y1; fY1 = y1;
00433 R__b >> x2; fX2 = x2;
00434 R__b >> y2; fY2 = y2;
00435
00436
00437 } else {
00438 R__b.WriteClassBuffer(TLine::Class(),this);
00439 }
00440 }