[ROOT] Bug in TEllipse::DistancetoPrimitive

From: Brett Viren (bv@bnl.gov)
Date: Fri Mar 23 2001 - 13:58:48 MET


Hi,

I guess I found a bug in TEllipse::DistancetoPrimitive (v3.00/06 from
CVS of a week ago or so) It does not seem to correctly calculate what
it should.  I can't quite figure out what it is trying to do, but it
does fail to return the correct determination of whether the pointer
is inside or outside the ellipse.  This is only noticeable on
non-circular ellipses.

See appended code (particularly method MyThing::DistancetoPrimitive)
for a test case and possible fix.  Compile w/ and w/out -DUSE_TELLIPSE
to get the two different versions.  When compiling with
-DUSE_TELLIPSE, squash the ellipse first to see the bug.


Regards,
-Brett.

//////////////////////////////////////////////
// drawstuff.cxx - simple ROOT drawing example
// to compile:
// g++ -g -Wall -O -o drawstuff drawstuff.cxx `root-config --cflags --glibs`
//
#include "TROOT.h"
#include "TApplication.h"
#include "TCanvas.h"
#include "TEllipse.h"

#include <iostream>

class MyThing: public TObject
{
    TEllipse fEllipse;
public:
    MyThing();
    void Draw(Option_t* opt);
    void Paint(Option_t* opt);
    Int_t DistancetoPrimitive(Int_t px, Int_t py);
    void ExecuteEvent(Int_t event, Int_t px, Int_t py);
};

MyThing::MyThing()
    : TObject(),
      fEllipse(10.0,20.0,2.0,4.0,0,360,10)
{
    fEllipse.SetFillColor(6);
    fEllipse.SetFillStyle(3008);
    fEllipse.SetX1(10);
    fEllipse.SetY1(10);
    fEllipse.SetR1(9);
    fEllipse.SetR2(1);
}
Int_t MyThing::DistancetoPrimitive(Int_t px, Int_t py)
{
    Int_t dist;
//#define USE_TELLIPSE
#ifdef USE_TELLIPSE
    dist = fEllipse.DistancetoPrimitive(px,py);
#else

    Double_t x = gPad->AbsPixeltoX(px);
    Double_t y = gPad->AbsPixeltoY(py);

    Double_t dxnr = x - fEllipse.GetX1();
    Double_t dynr = y - fEllipse.GetY1();

    Double_t ct = TMath::Cos(M_PI*fEllipse.GetTheta()/180.0);
    Double_t st = TMath::Sin(M_PI*fEllipse.GetTheta()/180.0);

    Double_t dx = dxnr*ct + dynr*st;
    Double_t dy = - dxnr*st + dynr*ct;

    Double_t r1 = fEllipse.GetR1();
    Double_t r2 = fEllipse.GetR2();

    Double_t distp = TMath::Sqrt(dx*dx + dy*dy);

    Double_t tana = dy/dx;
    tana *= tana;
    Double_t distr = sqrt((1+tana)/(1.0/(r1*r1) + tana/(r2*r2)));
    if (distr > distp) dist = 0;
    else dist = 9999;

#endif
    return dist;
}
void MyThing::ExecuteEvent(Int_t event, Int_t px, Int_t py)
{
    fEllipse.ExecuteEvent(event,px,py);
}
void MyThing::Draw(Option_t* opt)
{
    this->AppendPad();
}
void MyThing::Paint(Option_t* opt)
{
    fEllipse.Paint();
}
int main (int argc, char *argv[])
{
    TROOT blah("blah", "blah");
    TApplication app("blah", &argc, argv, 0, 0);
    TCanvas c;
    TPad p("blah","blah",0.0,0.0,1.0,1.0);
    p.Range(0.0,0.0,20.0,20.0);
    c.cd();
    p.Draw();

    p.cd();
    MyThing mt;
    mt.Draw("");

    c.Update();
    app.Run();
    return 0;
} // end of main()



This archive was generated by hypermail 2b29 : Tue Jan 01 2002 - 17:50:40 MET