TGLBoundingBox.h

Go to the documentation of this file.
00001 // @(#)root/gl:$Id: TGLBoundingBox.h 37397 2010-12-08 13:54:23Z matevz $
00002 // Author:  Richard Maunder  25/05/2005
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2004, 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 #ifndef ROOT_TGLBoundingBox
00013 #define ROOT_TGLBoundingBox
00014 
00015 #ifndef ROOT_TGLUtil
00016 #include "TGLUtil.h"
00017 #endif
00018 
00019 //////////////////////////////////////////////////////////////////////////
00020 //                                                                      //
00021 // TGLBoundingBox                                                       //
00022 //                                                                      //
00023 // Concrete class describing an orientated (free) or axis aligned box   //
00024 // of 8 verticies. Supports methods for setting aligned or orientated   //
00025 // boxes, find volume, axes, extents, centers, face planes etc.         //
00026 // Also tests for overlap testing of planes and other bounding boxes,   //
00027 // with fast sphere approximation.                                      //
00028 //////////////////////////////////////////////////////////////////////////
00029 
00030 // TODO: Create more compact version + axis aligned version, both with lazy
00031 // sphere testing.
00032 class TGLBoundingBox
00033 {
00034 private:
00035    // Fields
00036 
00037    // Box vertices are indexed thus (OpenGL is left handed by default)
00038    //    y
00039    //    |
00040    //    |
00041    //    |________x
00042    //   /  3-------2
00043    //  /  /|      /|
00044    // z  7-------6 |
00045    //    | 0-----|-1
00046    //    |/      |/
00047    //    4-------5
00048    //
00049    // 0123 'far' face
00050    // 4567 'near' face
00051    //
00052    // This could be more compact:
00053    // For orientated box 3 vertices which form plane cutting box
00054    // diagonally (e.g. 0,5,6 or 1,3,6 etc) would fix in space.
00055    // For axis aligned 2 verticies would suffice.
00056    // Rest could be calculated on demand - however speed more important
00057    // than memory considerations
00058    TGLVertex3              fVertex[8];  //! the 8 bounding box vertices
00059    Double_t                fVolume;     //! box volume - cached for speed
00060    Double_t                fDiagonal;   //! max box diagonal - cached for speed
00061    TGLVector3              fAxes[3];    //! box axes in global frame - cached for speed
00062    TGLVector3              fAxesNorm[3];//! normalised box axes in global frame - cached for speed
00063 
00064    // Methods
00065    void     UpdateCache();
00066    Bool_t   ValidIndex(UInt_t index) const { return (index < 8); }
00067    Double_t Min(UInt_t index) const;
00068    Double_t Max(UInt_t index) const;
00069 
00070 public:
00071    TGLBoundingBox();
00072    TGLBoundingBox(const TGLVertex3 vertex[8]);
00073    TGLBoundingBox(const Double_t vertex[8][3]);
00074    TGLBoundingBox(const TGLVertex3 & lowVertex, const TGLVertex3 & highVertex);
00075    TGLBoundingBox(const TGLBoundingBox & other);
00076    virtual ~TGLBoundingBox(); // ClassDef introduces virtual fns
00077 
00078    // Set orientated box
00079    TGLBoundingBox & operator =(const TGLBoundingBox & other);
00080    void Set(const TGLVertex3 vertex[8]);
00081    void Set(const Double_t vertex[8][3]);
00082    void Set(const TGLBoundingBox & other);
00083    void SetEmpty();
00084 
00085    // Set axis aligned box
00086    void SetAligned(const TGLVertex3 & lowVertex, const TGLVertex3 & highVertex); // axis aligned
00087    void SetAligned(UInt_t nbPnts, const Double_t * pnts); // axis aligned
00088    void MergeAligned(const TGLBoundingBox & other);
00089    void ExpandAligned(const TGLVertex3 & point);
00090 
00091    // Manipulation
00092    void Transform(const TGLMatrix & matrix);
00093    void Scale(Double_t factor);
00094    void Scale(Double_t xFactor, Double_t yFactor, Double_t zFactor);
00095    void Translate(const TGLVector3 & offset);
00096 
00097    // Single vertex accessors
00098    const TGLVertex3 & operator [] (UInt_t index) const;
00099    const TGLVertex3 & Vertex(UInt_t index) const;
00100    Double_t XMin() const { return Min(0); }
00101    Double_t XMax() const { return Max(0); }
00102    Double_t YMin() const { return Min(1); }
00103    Double_t YMax() const { return Max(1); }
00104    Double_t ZMin() const { return Min(2); }
00105    Double_t ZMax() const { return Max(2); }
00106    TGLVertex3 MinAAVertex() const;
00107    TGLVertex3 MaxAAVertex() const;
00108 
00109    // Multiple vertices accessors
00110    const TGLVertex3* Vertices() const;           // All 8 box vertices
00111    Int_t             NumVertices() const { return 8; }
00112 
00113    enum EFace { kFaceLowX, kFaceHighX, kFaceLowY, kFaceHighY, kFaceLowZ, kFaceHighZ, kFaceCount };
00114    const std::vector<UInt_t> & FaceVertices(EFace face) const; // 4 box face vertices
00115 
00116    // Other properties
00117    TGLVertex3   Center() const;
00118    TGLVector3   Extents() const;
00119    const  TGLVector3 & Axis(UInt_t i, Bool_t normalised = kTRUE) const;
00120    Bool_t       IsEmpty()  const;
00121    Double_t     Volume()   const { return fVolume;   }
00122    Double_t     Diagonal() const { return fDiagonal; }
00123    void         PlaneSet(TGLPlaneSet_t & planeSet) const;
00124    TGLPlane     GetNearPlane() const;
00125 
00126    // Overlap testing
00127    EOverlap Overlap(const TGLPlane & plane) const;
00128    EOverlap Overlap(const TGLBoundingBox & box) const;
00129 
00130    void Draw(Bool_t solid = kFALSE) const;
00131    void Dump() const;
00132 
00133    ClassDef(TGLBoundingBox,0); // a 3D orientated bounding box
00134 };
00135 
00136 //______________________________________________________________________________
00137 inline TGLBoundingBox & TGLBoundingBox::operator =(const TGLBoundingBox & other)
00138 {
00139    // Check for self-assignment
00140    if (this != &other) {
00141       Set(other);
00142    }
00143    return *this;
00144 }
00145 
00146 //______________________________________________________________________________
00147 inline const TGLVertex3 & TGLBoundingBox::operator [] (UInt_t index) const
00148 {
00149    return fVertex[index];
00150 }
00151 
00152 //______________________________________________________________________________
00153 inline const TGLVertex3 & TGLBoundingBox::Vertex(UInt_t index) const
00154 {
00155    return fVertex[index];
00156 }
00157 
00158 //______________________________________________________________________________
00159 inline const TGLVertex3* TGLBoundingBox::Vertices() const
00160 {
00161    return fVertex;
00162 }
00163 
00164 //______________________________________________________________________________
00165 inline TGLVector3 TGLBoundingBox::Extents() const
00166 {
00167    // Return the local axis entents of the box
00168    return TGLVector3(Axis(0,kFALSE).Mag(),
00169                      Axis(1,kFALSE).Mag(),
00170                      Axis(2,kFALSE).Mag());
00171 }
00172 
00173 //______________________________________________________________________________
00174 inline TGLVertex3 TGLBoundingBox::Center() const
00175 {
00176    // Return the center vertex of the box
00177    return TGLVertex3((fVertex[0].X() + fVertex[6].X())/2.0,
00178                      (fVertex[0].Y() + fVertex[6].Y())/2.0,
00179                      (fVertex[0].Z() + fVertex[6].Z())/2.0);
00180 }
00181 
00182 //______________________________________________________________________________
00183 inline const TGLVector3 & TGLBoundingBox::Axis(UInt_t i, Bool_t normalised) const
00184 {
00185    // Return a vector representing axis of index i (0:X, 1:Y, 2:Z).
00186    // Vector can be as-is (edge, magnitude == extent) or normalised (default)
00187    //    y
00188    //    |
00189    //    |
00190    //    |________x
00191    //   /  3-------2
00192    //  /  /|      /|
00193    // z  7-------6 |
00194    //    | 0-----|-1
00195    //    |/      |/
00196    //    4-------5
00197    //
00198 
00199    if (normalised) {
00200       return fAxesNorm[i];
00201    } else {
00202       return fAxes[i];
00203    }
00204 }
00205 
00206 //______________________________________________________________________________
00207 inline Bool_t TGLBoundingBox::IsEmpty() const
00208 {
00209    // Return kTRUE if box has zero diagonal - kFALSE otherwise
00210 
00211    // TODO: Round errors - should have epsilon test
00212    return (Diagonal() == 0.0);
00213 }
00214 
00215 #endif // ROOT_TGLBoundingBox

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