TEveShape.cxx

Go to the documentation of this file.
00001 // @(#)root/eve:$Id: TEveShape.cxx 37228 2010-12-03 16:55:15Z matevz $
00002 // Author: Matevz Tadel, 2010
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2007, 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 "TEveShape.h"
00013 #include "Riostream.h"
00014 
00015 //______________________________________________________________________________
00016 //
00017 // Abstract base-class for 2D/3D shapes.
00018 // It provides:
00019 // - fill color / transparency, accessible via Get/SetMainColor/Transparency;
00020 // - frame line color / width;
00021 // - flag if frame should be drawn;
00022 // - flag specifying whether frame or whole shape should be emphasised for
00023 //   highlight.
00024 
00025 ClassImp(TEveShape);
00026 
00027 //______________________________________________________________________________
00028 TEveShape::TEveShape(const char* n, const char* t) :
00029    TEveElementList(n, t),
00030    fFillColor(5),
00031    fLineColor(5),
00032    fLineWidth(1),
00033    fDrawFrame(kTRUE),
00034    fHighlightFrame(kTRUE),
00035    fMiniFrame(kTRUE)
00036 {
00037    // Constructor.
00038 
00039    fCanEditMainColor        = kTRUE;
00040    fCanEditMainTransparency = kTRUE;
00041    SetMainColorPtr(&fFillColor);
00042 }
00043 
00044 //______________________________________________________________________________
00045 TEveShape::~TEveShape()
00046 {
00047    // Destructor.
00048 }
00049 
00050 //______________________________________________________________________________
00051 void TEveShape::SetMainColor(Color_t color)
00052 {
00053    // Set main color.
00054    // Override so that line-color can also be changed if it is equal
00055    // to fill color (which is treated as main color).
00056 
00057    if (fFillColor == fLineColor) {
00058       fLineColor = color;
00059       StampObjProps();
00060    }
00061    TEveElementList::SetMainColor(color);
00062 }
00063 
00064 //______________________________________________________________________________
00065 void TEveShape::CopyVizParams(const TEveElement* el)
00066 {
00067    // Copy visualization parameters from element el.
00068 
00069    const TEveShape* m = dynamic_cast<const TEveShape*>(el);
00070    if (m)
00071    {
00072       fFillColor = m->fFillColor;
00073       fLineColor = m->fLineColor;
00074       fLineWidth = m->fLineWidth;
00075       fDrawFrame      = m->fDrawFrame;
00076       fHighlightFrame = m->fHighlightFrame;
00077       fMiniFrame      = m->fMiniFrame;
00078    }
00079 
00080    TEveElementList::CopyVizParams(el);
00081 }
00082 
00083 //______________________________________________________________________________
00084 void TEveShape::WriteVizParams(ostream& out, const TString& var)
00085 {
00086    // Write visualization parameters.
00087 
00088    TEveElementList::WriteVizParams(out, var);
00089 
00090    TString t = "   " + var + "->";
00091    out << t << "SetFillColor(" << fFillColor << ");\n";
00092    out << t << "SetLineColor(" << fLineColor << ");\n";
00093    out << t << "SetLineWidth(" << fLineWidth << ");\n";
00094    out << t << "SetDrawFrame("      << ToString(fDrawFrame) << ");\n";
00095    out << t << "SetHighlightFrame(" << ToString(fHighlightFrame) << ");\n";
00096 }
00097 
00098 //______________________________________________________________________________
00099 void TEveShape::Paint(Option_t*)
00100 {
00101    // Paint this object. Only direct rendering is supported.
00102 
00103    PaintStandard(this);
00104 }
00105 
00106 //==============================================================================
00107 
00108 //______________________________________________________________________________
00109 Int_t TEveShape::FindConvexHull(const vVector2_t& pin, vVector2_t& pout, TEveElement* caller)
00110 {
00111    // Determines the convex-hull of points in pin.
00112    //
00113    // Adds the hull points to pout and returns the number of added points.
00114    // If size of pout is less then 3 then either the number of input points
00115    // was too low or they were degenerate so that the hull is actually a line
00116    // segment or even a point.
00117 
00118    Int_t N = pin.size();
00119 
00120    // Find the minimum (bottom-left) point.
00121    Int_t min_point = 0;
00122    for (Int_t i = 1; i < N; ++i)
00123    {
00124       if (pin[i].fY < pin[min_point].fY || (pin[i].fY == pin[min_point].fY && pin[i].fX < pin[min_point].fX))
00125          min_point = i;
00126    }
00127 
00128    // Calculate angles and sort.
00129    std::vector<Float_t> angles(N);
00130    for (Int_t i = 0; i < N; ++i)
00131    {
00132       angles[i] = (pin[i] - pin[min_point]).Phi();
00133    }
00134    std::vector<Int_t> idcs(N);
00135    TMath::Sort(N, &angles[0], &idcs[0], kFALSE);
00136 
00137    // Weed out points with the same angle -- keep the furthest only.
00138    // The first point must stay.
00139    if (N > 2)
00140    {
00141       std::vector<Int_t> new_idcs;
00142       new_idcs.push_back(idcs[0]);
00143       std::vector<Int_t>::iterator a, b;
00144       a = idcs.begin(); ++a;
00145       b = a; ++b;
00146       while (b != idcs.end())
00147       {
00148          if (TMath::Abs(angles[*a] - angles[*b]) < 1e-5f)
00149          {
00150             if (pin[idcs[0]].SquareDistance(pin[*a]) < pin[idcs[0]].SquareDistance(pin[*b]))
00151                a = b;
00152          }
00153          else
00154          {
00155             new_idcs.push_back(*a);
00156             a = b;
00157          }
00158          ++b;
00159       }
00160       new_idcs.push_back(*a);
00161       idcs.swap(new_idcs);
00162    }
00163 
00164    N = idcs.size();
00165 
00166    // Find hull.
00167    std::vector<Int_t> hull;
00168    if (N > 2)
00169    {
00170       hull.push_back(idcs[0]);
00171       hull.push_back(idcs[1]);
00172       hull.push_back(idcs[2]);
00173       {
00174          Int_t i = 3;
00175          while (i < N)
00176          {
00177             Int_t n = hull.size() - 1;
00178             if ((pin[hull[n]] - pin[hull[n-1]]).Cross(pin[idcs[i]] - pin[hull[n]]) > 0)
00179             {
00180                hull.push_back(idcs[i]);
00181                ++i;
00182             }
00183             else
00184             {
00185                hull.pop_back();
00186             }
00187          }
00188       }
00189    }
00190    else
00191    {
00192       ::Warning("TEveShape::FindConvexHull()", "Polygon reduced to %d points. for '%s'.",
00193               N, caller ? caller->GetElementName() : "unknown");
00194       hull.swap(idcs);
00195    }
00196 
00197    // Add hull points into the output vector.
00198    N = hull.size();
00199    Int_t Nold = pout.size();
00200    pout.resize(Nold + N);
00201    for (Int_t i = 0; i < N; ++i)
00202    {
00203       pout[Nold + i] = pin[hull[i]];
00204    }
00205 
00206    // Print the hull.
00207    // for (Int_t i = 0; i < N; ++i)
00208    // {
00209    //    const TEveVector2 &p = pin[hull[i]];
00210    //    printf("%d [%d] (%5.1f, %5.1f) %f\n", i, hull[i], p.fX, p.fY, angles[hull[i]]);
00211    // }
00212 
00213    return N;
00214 }
00215 
00216 //==============================================================================
00217 
00218 //______________________________________________________________________________
00219 Bool_t TEveShape::IsBoxOrientationConsistentEv(const TEveVector box[8])
00220 {
00221    // Checks if the first face normal is pointing into the other
00222    // direction as the vector pointing towards the opposite face.
00223    // This assumes standard box vertex arrangement.
00224 
00225    TEveVector f1 = box[1] - box[0];
00226    TEveVector f2 = box[3] - box[0];
00227    TEveVector up = box[4] - box[0];
00228 
00229    return up.Dot(f1.Cross(f2)) < 0;
00230 }
00231 
00232 //______________________________________________________________________________
00233 Bool_t TEveShape::IsBoxOrientationConsistentFv(const Float_t box[8][3])
00234 {
00235    // Checks if the first face normal is pointing into the other
00236    // direction as the vector pointing towards the opposite face.
00237    // This assumes standard box vertex arrangement.
00238 
00239    TEveVector b0(box[0]);
00240    TEveVector f1(box[1]); f1 -= b0;
00241    TEveVector f2(box[3]); f2 -= b0;
00242    TEveVector up(box[4]); up -= b0;
00243 
00244    return up.Dot(f1.Cross(f2)) < 0;
00245 }
00246 
00247 //______________________________________________________________________________
00248 void TEveShape::CheckAndFixBoxOrientationEv(TEveVector box[8])
00249 {
00250    // Make sure box orientation is consistent with standard arrangement.
00251 
00252    if ( ! IsBoxOrientationConsistentEv(box))
00253    {
00254       std::swap(box[1], box[3]);
00255       std::swap(box[5], box[7]);
00256    }
00257 }
00258 
00259 //______________________________________________________________________________
00260 void TEveShape::CheckAndFixBoxOrientationFv(Float_t box[8][3])
00261 {
00262    // Make sure box orientation is consistent with standard arrangement.
00263 
00264    if ( ! IsBoxOrientationConsistentFv(box))
00265    {
00266       std::swap(box[1][0], box[3][0]);
00267       std::swap(box[1][1], box[3][1]);
00268       std::swap(box[1][2], box[3][2]);
00269       std::swap(box[5][0], box[7][0]);
00270       std::swap(box[5][1], box[7][1]);
00271       std::swap(box[5][2], box[7][2]);
00272    }
00273 }

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