TLine.cxx

Go to the documentation of this file.
00001 // @(#)root/graf:$Id: TLine.cxx 35161 2010-09-06 10:25:40Z couet $
00002 // Author: Rene Brun   12/12/94
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 <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 // A Graphical line
00029 //
00030 
00031 
00032 //______________________________________________________________________________
00033 TLine::TLine(): TObject(), TAttLine()
00034 {
00035    // Line default constructor.
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    // Line normal constructor.
00046 
00047    fX1=x1; fY1=y1; fX2=x2; fY2=y2;
00048 }
00049 
00050 
00051 //______________________________________________________________________________
00052 TLine::~TLine()
00053 {
00054    // Line default destructor.
00055 }
00056 
00057 
00058 //______________________________________________________________________________
00059 TLine::TLine(const TLine &line) : TObject(line), TAttLine(line)
00060 {
00061    // Line copy constructor.
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    // Copy this line to line.
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    // Compute distance from point px,py to a line.
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    // Draw this line with new coordinates.
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    // Draw this line with new coordinates in NDC.
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    // Execute action corresponding to one event.
00124    //  This member function is called when a line is clicked with the locator
00125    //
00126    //  If Left button clicked on one of the line end points, this point
00127    //     follows the cursor until button is released.
00128    //
00129    //  if Middle button clicked, the line is moved parallel to itself
00130    //     until the button is released.
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();  //Change line attributes only if necessary
00146 
00147       // No break !!!
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); //simply take sum of pixels differences
00165       if (d1 < kMaxDiff) { //*-*================>OK take point number 1
00166          px1old = px1; py1old = py1;
00167          p1 = kTRUE;
00168          gPad->SetCursor(kPointer);
00169          return;
00170       }
00171       d2  = abs(px2 - px) + abs(py2-py); //simply take sum of pixels differences
00172       if (d2 < kMaxDiff) { //*-*================>OK take point number 2
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) {                     // button is released
00273             ExecuteEvent(kButton1Up, px, py);
00274             return;
00275          }
00276       }
00277    }
00278 }
00279 
00280 
00281 //______________________________________________________________________________
00282 void TLine::ls(Option_t *) const
00283 {
00284    // List this line with its attributes.
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    // Paint this line with its current attributes.
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    // Draw this line with new coordinates.
00305 
00306    TAttLine::Modify();  //Change line attributes only if necessary
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    // Draw this line with new coordinates in NDC.
00315 
00316    TAttLine::Modify();  //Change line attributes only if necessary
00317    gPad->PaintLineNDC(u1,v1,u2,v2);
00318 }
00319 
00320 
00321 //______________________________________________________________________________
00322 void TLine::Print(Option_t *) const
00323 {
00324    // Dump this line with its attributes.
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     // Save primitive as a C++ statement(s) on output stream out
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    // Check whether this line is to be drawn horizontally.
00357 
00358    return TestBit(kHorizontal);
00359 }
00360 
00361 
00362 //______________________________________________________________________________
00363 Bool_t TLine::IsVertical()
00364 {
00365    // Check whether this line is to be drawn vertically.
00366 
00367    return TestBit(kVertical);
00368 }
00369 
00370 
00371 //______________________________________________________________________________
00372 void TLine::SetHorizontal(Bool_t set /*= kTRUE*/)
00373 {
00374    // Force the line to be drawn horizontally.
00375    // Makes fY2 equal to fY1. The line length is kept.
00376    // TArrow and TGaxis also get this function by inheritance.
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 /*= kTRUE*/)
00395 {
00396    // Force the line to be drawn vertically.
00397    // Makes fX2 equal to fX1. The line length is kept.
00398    // TArrow and TGaxis also get this function by inheritance.
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    // Stream an object of class TLine.
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       //====process old versions before automatic schema evolution
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       //====end of old versions
00436 
00437    } else {
00438       R__b.WriteClassBuffer(TLine::Class(),this);
00439    }
00440 }

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