Home || Architecture || Video Search || Visual Search || Scripts || Applications || Important Messages || OGL || Src

Plot.h

Go to the documentation of this file.
00001 #ifndef Impala_Visualisation_Plot_Plot_h
00002 #define Impala_Visualisation_Plot_Plot_h
00003 
00004 #include "Core/Array/Arrays.h"
00005 #include "OglGui/Window.h"
00006 #include "Visualization/Plot/Plottable.h"
00007 
00008 namespace Impala
00009 {
00010 namespace Visualization
00011 {
00012 namespace Plot
00013 {
00014 
00015 
00024 class Plot : public OglGui::Window
00025 {
00026 public:
00027     Plot(OglGui::Window* parent, int x, int y, int width, int height) : 
00028         OglGui::Window(parent, x, y, width, height)
00029     {
00030         Init();
00031         //mPerspective = true;
00032     }
00033 
00034     Plot(OglGui::Window* parent, int width, int height) : 
00035         OglGui::Window(parent, width, height)
00036     {
00037         Init();
00038         //mPerspective = true;
00039     }
00040 
00041     void Add(Plottable* p)
00042     {
00043         mPlottables.push_back(p);
00044     }
00045 
00046     void SetCenter(double x, double y, double z)
00047     {
00048         mCenter[0] = x;
00049         mCenter[1] = y;
00050         mCenter[2] = z;
00051     }
00052 
00053     void SetRange(double x, double y, double z)
00054     {
00055         double w=1., h=1.;
00056         if(mDrawAxes)
00057         {
00058             //reserve space for axes and text
00059             w = mOglWnd->width * 0.5;
00060             w = w/(w-20.0);
00061             h = mOglWnd->height * 0.5;
00062             h = h/(h-20.0);
00063         }
00064         mRange[0] = x*w;
00065         mRange[1] = y*h;
00066         mRange[2] = z;
00067     }
00068 
00069     void GetRange(double& left, double& top, double& right, double& bottom)
00070     {
00071         Pixel2Window(20, 20, left, bottom);
00072         Pixel2Window(mOglWnd->width-20, mOglWnd->height-20, right, top);
00073     }
00074 
00075     bool IsVisible(double x, double y)
00076     {
00077         double pixX, pixY;
00078         Window2Pixel(x,y,pixX,pixY);
00079         return !(pixX < 0 || pixX > W() || pixY < 0 || pixY > H());
00080     }
00081 
00082     void MakeVisibleAtPix(double x, double y, double pixX, double pixY)
00083     {
00084         double atX, atY;
00085         Window2Pixel(x,y,atX,atY);
00086         mUserPan[0] += (pixX - atX)* mRange[0] / ((double)mOglWnd->width *mUserZoom[0]);
00087         mUserPan[1] += (pixY - atY)* mRange[1] / ((double)mOglWnd->height*mUserZoom[1]);
00088     }
00089 
00090     void GetUserPan(double& panX, double& panY)
00091     {
00092         panX = mUserPan[0];
00093         panY = mUserPan[1];
00094     }
00095 
00096     void SetUserPan(double panX, double panY)
00097     {
00098         mUserPan[0] = panX;
00099         mUserPan[1] = panY;
00100     }
00101 
00102     void GetUserZoom(double& zoomX, double& zoomY)
00103     {
00104         zoomX = mUserZoom[0];
00105         zoomY = mUserZoom[1];
00106     }
00107 
00108     void SetUserZoom(double zoomX, double zoomY)
00109     {
00110         mUserZoom[0] = zoomX;
00111         mUserZoom[1] = zoomY;
00112     }
00113 
00114     void GetRotations(double& roll, double& pitch, double& yaw)
00115     {
00116         roll = mRoll;
00117         pitch = mPitch;
00118         yaw = mYaw;
00119     }
00120 
00121     //void SetPerspective(bool flag)
00122     //{
00123     //    mPerspective = flag;
00124     //}
00125 
00126     void SetDrawAxes(bool flag)
00127     {
00128         mDrawAxes = flag;
00129     }
00130 
00131     bool GetDrawAxes()
00132     {
00133         return mDrawAxes;
00134     }
00135     void Window2Pixel(double wx, double wy, double&px, double& py)
00136     {
00137         wx -= mCenter[0]-mUserPan[0]-(.5*mRange[0]/mUserZoom[0]);
00138         px = wx / ((mRange[0]/mUserZoom[0])/(double)mOglWnd->width);
00139         wy -= mCenter[1]-mUserPan[1]-(.5*mRange[1]/mUserZoom[1]);
00140         py = wy / ((mRange[1]/mUserZoom[1])/(double)mOglWnd->height);
00141     }
00142 
00143     void Pixel2Window(double px, double py, double&wx, double& wy)
00144     {
00145         wx = (px*mRange[0]/mUserZoom[0])/(double)mOglWnd->width;
00146         wx += mCenter[0]-mUserPan[0]-(.5*mRange[0]/mUserZoom[0]);
00147         wy = (py*mRange[1]/mUserZoom[1])/(double)mOglWnd->height;
00148         wy += mCenter[1]-mUserPan[1]-(.5*mRange[1]/mUserZoom[1]);
00149     }
00150 
00151     void AutoScale()
00152     {
00153         if(mPlottables.size() == 0)
00154             return;
00155         double minx, maxx;
00156         double miny, maxy;
00157         double minz, maxz;
00158         Plottable* p;
00159         p = mPlottables[0];
00160         p->GetDimensionsX(minx, maxx);
00161         p->GetDimensionsY(miny, maxy);
00162         p->GetDimensionsZ(minz, maxz);
00163         for(int i=1 ; i<mPlottables.size() ; i++)
00164         {
00165             double min, max;
00166             p = mPlottables[i];
00167             p->GetDimensionsX(min, max);
00168             if(min<minx)
00169                 minx = min;
00170             if(max>maxx)
00171                 maxx = max;
00172             p->GetDimensionsY(min, max);
00173             if(min<miny)
00174                 miny = min;
00175             if(max>maxy)
00176                 maxy = max;
00177             p->GetDimensionsZ(min, max);
00178             if(min<minz)
00179                 minz = min;
00180             if(max>maxz)
00181                 maxz = max;
00182         }
00183 
00184         if(minz == maxz)
00185         {
00186             minz = -1;
00187             maxz = 1;
00188             mIs3d = false;
00189         }
00190         else
00191             mIs3d = true;
00192 
00193         SetCenter((maxx+minx)*.5, (maxy+miny)*.5, (maxz+minz)*.5);
00194         SetRange(maxx-minx, maxy-miny, maxz-minz);
00195     }
00196 
00197     //void TransformMatrices(double w, double h)
00198     //{
00199     //    //projection
00200     //    glMatrixMode(GL_PROJECTION);
00201     //    glPushMatrix();
00202     //    glLoadIdentity();
00203     //    if (mPerspective)
00204     //        gluPerspective(45, w/h, 1, 8);
00205     //    else
00206     //        glOrtho(-1, 1, -1, 1, 1, 7);
00207 
00208     //    //model
00209     //    glMatrixMode(GL_MODELVIEW);
00210     //    glPushMatrix();
00211     //    glLoadIdentity();
00212     //    glTranslatef(0,0,-4.5);
00213 
00214     //    glRotatef(mRoll + mUserRoll, 1, 0, 0);
00215     //    glRotatef(mPitch + mUserPitch, 0, 1, 0);
00216     //    glRotatef(mYaw, 0, 0, 1);
00217 
00218     //    glScaled(2.*mUserZoom[0]/mRange[0], 2.*mUserZoom[1]/mRange[1], 2./mRange[2]);
00219     //    glTranslated(-mCenter[0]+mUserPan[0], -mCenter[1]+mUserPan[1], -mCenter[2]);
00220     //}
00221 
00222     void TransformMatrices(double w, double h)
00223     {
00224         //******NOTE: this implementation is for 2D only*******//
00225         glMatrixMode(GL_PROJECTION);
00226         glPushMatrix();
00227         glLoadIdentity();
00228 
00229         double range[2];
00230         double center[2];
00231         for(int i=0 ; i<2 ; ++i)
00232         {
00233             center[i] = mCenter[i] - mUserPan[i];
00234             range[i] = 0.5*mRange[i] / mUserZoom[i];
00235         }
00236 
00237         glOrtho(center[0] - range[0],
00238                 center[0] + range[0],
00239                 center[1] - range[1],
00240                 center[1] + range[1],
00241                 -1, 1);
00242 
00243         glMatrixMode(GL_MODELVIEW);
00244         glPushMatrix();
00245     }
00246 
00247     virtual void DisplayFunc()
00248     {
00249         OGC oldOGC;
00250         OGCSave(&oldOGC);
00251         TransformMatrices(mOglWnd->width, mOglWnd->height);
00252 
00253         if(mDrawAxes)
00254             DrawAxes();
00255 
00256         for (int i=0 ; i<mPlottables.size() ; i++)
00257         {
00258             mPlottables[i]->Draw(this);
00259         }
00260 
00261 
00262         glMatrixMode(GL_PROJECTION);
00263         glPopMatrix();
00264         glMatrixMode(GL_MODELVIEW);
00265         glPopMatrix();
00266 
00267         OGCRestore(&oldOGC);
00268     }
00269 
00270     virtual void MouseFunc(int msg, int but, int state, int x, int y)
00271     {
00272         bool shift = (state & oglShift) != 0;
00273         bool control = (state & oglControl) != 0;
00274 
00275         if (msg == oglMouseDown && but == oglRightButton) 
00276         {
00277             //if(control)
00278             //    mPerspective = !mPerspective;
00279             //else
00280             {
00281                 for(int i=0 ; i<2 ; i++)
00282                 {
00283                     mUserPan[i] = 0;
00284                     mUserZoom[i] = 0.9;
00285                 }
00286                 mUserRoll = mUserPitch = 0;
00287             }
00288         }
00289 
00290         if (msg == oglMouseDown && but == oglLeftButton && (shift||control)) 
00291         {
00292             mDragging = true;
00293             mClickX = x;
00294             mClickY = y;
00295         }
00296 
00297         if (msg == oglMouseUp) 
00298             mDragging = false;
00299     
00300         if (msg == oglMouseMove && mDragging)
00301         {
00302             int dx = x - mClickX;
00303             int dy = y - mClickY;
00304             if(control)
00305             {
00306                 mUserZoom[0] *= pow(1.02,(double)dx);
00307                 mUserZoom[1] *= pow(1.02,(double)dy);
00308                 for(int i=0 ; i<2 ; i++)
00309                     if(mUserZoom[i] < 0.01)
00310                         mUserZoom[i] = 0.01;
00311             }
00312             else
00313                 //if(mPerspective && !control)
00314                 //{
00315                 //    mUserRoll -= dy;
00316                 //    if(mUserRoll > 90)
00317                 //        mUserRoll = 90;
00318                 //    if(mUserRoll < -90)
00319                 //        mUserRoll = -90;
00320                 //    mUserPitch += dx;
00321                 //}
00322                 //else
00323                 {
00324                     mUserPan[0] += (double)dx * mRange[0] / ((double)mOglWnd->width *mUserZoom[0]);
00325                     mUserPan[1] += (double)dy * mRange[1] / ((double)mOglWnd->height*mUserZoom[1]);
00326                 }
00327             mClickX = x;
00328             mClickY = y;
00329         }
00330     
00331         double wx, wy;
00332         Pixel2Window(x, y, wx, wy);
00333         for(int i=0 ; i<mPlottables.size() ; i++)
00334             mPlottables[i]->OnMouse(wx, wy, msg, but, state);
00335     }
00336 
00337 protected:
00338     double mRoll, mPitch, mYaw;
00339     double mUserRoll, mUserPitch;
00340     std::vector<Plottable*> mPlottables;
00341     bool mDragging;
00342     //bool mPerspective;
00343     bool mDrawAxes;
00344     bool mIs3d;
00345     int mClickX, mClickY;
00346 
00347     double mCenter[3];
00348     double mRange[3]; // means either distance from center to edge, or from min to max, TBD
00349     double mUserZoom[2];
00350     double mUserPan[2];
00351     int    mFontBase;
00352 
00353     void Init()
00354     {
00355         for(int i=0 ; i<3 ; i++)
00356         {
00357             mCenter[i] = 0;
00358             mRange[i] = 2;
00359         }
00360         for(int i=0 ; i<2 ; i++)
00361         {
00362             mUserZoom[i] = 0.9;
00363             mUserPan[i] = 0;
00364         }
00365         mRoll = mPitch = mYaw = 0;
00366         mUserRoll = mUserPitch = 0;
00367         mOglWnd->bgCol = 0xff505050;
00368         mDrawAxes = false;
00369         mDragging = false;
00370         SetIs2d(false);
00371         mIs3d = false;
00372 
00373         mFontBase = 0;
00374     }
00375 
00376     class Axis
00377     {
00378     public:
00379         void SetRange(double min, double max)
00380         {
00381             mMin = min;
00382             mMax = max;
00383             ComputeTicks();
00384         }
00385 
00386         double GetTick(int count)
00387         {
00388             return (double)(count+mFirstTick)*mTickSize;
00389         }
00390 
00391         int GetTickCount()
00392         {
00393             return mTickCount;
00394         }
00395 
00396         void DrawRulers(double* start, double* end, int axis)
00397         {
00398             double a[3];
00399             double b[3];
00400             int i;
00401             for(i=0 ; i<3 ; i++)
00402             {
00403                 a[i] = start[i];
00404                 b[i] = end[i];
00405             }
00406             glColor3d(.7,.7,.7);
00407             glBegin(GL_LINES);
00408             for(i=0 ; i<mTickCount ; i++)
00409             {
00410                 a[axis] = b[axis] = GetTick(i);
00411                 glVertex3dv(a);
00412                 glVertex3dv(b);
00413             }
00414             glEnd();
00415         }
00416 
00417     private:
00418         void ComputeTicks()
00419         {
00420             double range = mMax - mMin;
00421             double order = floor(log10(range));
00422             mTickSize = pow(10.,order);
00423             double quanta[6] = {.2, .4, .5, .75, 1., 2.};
00424             double quantum = 1.;
00425             for(int i=0 ; i<6 ; i++)
00426             {
00427                 if(range / (quanta[i]*mTickSize) >= 4)
00428                     quantum = quanta[i];
00429             }
00430             mTickSize *= quantum;
00431             mFirstTick = ceil(mMin / mTickSize);
00432             mTickCount = floor(mMax / mTickSize) - mFirstTick + 1;
00433         }
00434 
00435         double mMin, mMax;
00436         int mFirstTick;
00437         int mTickCount;
00438         double mTickSize;
00439     };
00440     Axis mAxisX;
00441     Axis mAxisY;
00442     Axis mAxisZ;
00443 
00444     void UpdateAxes()
00445     {
00446         double x1,x2,y1,y2;
00447         Pixel2Window(20, 20, x1, y1);
00448         Pixel2Window(mOglWnd->width-20, mOglWnd->height-20, x2, y2);
00449         mAxisX.SetRange(x1, x2);
00450         mAxisY.SetRange(y1, y2);
00451     }
00452 
00453     void DrawAxes()
00454     {
00455         UpdateAxes();
00456         if (!mFontBase)
00457             FindOglFont(mOglWnd, 0, &mFontBase);
00458 
00459         glColor3d(1,1,0);
00460         double x1,y1,tick;
00461         Pixel2Window(4, 4, x1, y1);
00462 
00463         int i;
00464         for(i=0 ; i<mAxisX.GetTickCount() ; i++)
00465         {
00466             tick = mAxisX.GetTick(i);
00467             glRasterPos3d(tick, y1, 0);
00468             std::ostringstream os;
00469             os << tick;
00470             oglSys.PrintFont(mFontBase, (char*) os.str().c_str());
00471         }
00472         for(i=0 ; i<mAxisY.GetTickCount() ; i++)
00473         {
00474             tick = mAxisY.GetTick(i);
00475             glRasterPos3d(x1, tick, 0);
00476             std::ostringstream os;
00477             os << tick;
00478             oglSys.PrintFont(mFontBase, (char*) os.str().c_str());
00479         }
00480 
00481         double x2,y2;
00482         Pixel2Window(20, 20, x1, y1);
00483         Pixel2Window(mOglWnd->width-20, mOglWnd->height-20, x2, y2);
00484         glBegin(GL_LINE_STRIP);
00485         glVertex2d(x2,y1);
00486         glVertex2d(x1,y1);
00487         glVertex2d(x1,y2);
00488         glEnd();
00489 
00490         glColor3d(0.6,0.6,0);
00491         glBegin(GL_LINES);
00492         for(i=0 ; i<mAxisX.GetTickCount() ; i++)
00493         {
00494             tick = mAxisX.GetTick(i);
00495             glVertex3d(tick, y1, 0);
00496             glVertex3d(tick, y2, 0);
00497         }
00498         for(i=0 ; i<mAxisY.GetTickCount() ; i++)
00499         {
00500             tick = mAxisY.GetTick(i);
00501             glVertex3d(x1, tick, 0);
00502             glVertex3d(x2, tick, 0);
00503         }
00504         glEnd();
00505     
00506     }
00507 };
00508 
00509 
00510 }//namespace Impala
00511 }//namespace Visulization
00512 }//namespace Plot
00513 
00514 /*
00515 */
00516 #endif

Generated on Fri Mar 19 09:31:51 2010 for ImpalaSrc by  doxygen 1.5.1