inlib  1.2.0
/Users/barrand/private/dev/softinex/old/inexlib-1.2/inlib/inlib/CContour
Go to the documentation of this file.
00001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
00002 // See the file inlib.license for terms.
00003 
00004 #ifndef inlib_CContour
00005 #define inlib_CContour
00006 
00007 // G.Barrand : inline version of the one found in Lib of OSC 16.11.
00008 //             This code is not mine and I keep it "as it is".
00009 
00010 // Contour.h: interface for the CContour class.
00011 //
00012 // CContour implements Contour plot algorithm descrided in 
00013 //              IMPLEMENTATION OF
00014 //              AN IMPROVED CONTOUR
00015 //              PLOTTING ALGORITHM
00016 //              BY 
00017 //
00018 //              MICHAEL JOSEPH ARAMINI 
00019 //
00020 //              B.S., Stevens Institute of Technology, 1980 
00021 // See http://www.ultranet.com/~aramini/thesis.html
00022 //
00023 // Ported to C++ by Jonathan de Halleux.
00024 //
00025 // Using CContour :
00026 //
00027 // CContour is not directly usable. The user has to 
00028 //      1. derive the function ExportLine that is 
00029 //              supposed to draw/store the segment of the contour
00030 //      2. Set the function draw contour of. (using  SetFieldFn
00031 //              The function must be declared as follows
00032 //              double (*myF)(double x , double y);
00033 //
00034 //      History:
00035 //              31-07-2002: 
00036 //                      - A lot of contribution from Chenggang Zhou (better strip compressions, merging, area, weight),
00037 //                      - Got rid of ugly MFC lists for STL.
00039 
00040 //G.Barrand :
00041 #include <vector>
00042 #include <cstdio>
00043 #include <cstdlib>
00044 #include <cmath>
00045 
00046 #include "mnmx"
00047 
00048 namespace inlib {
00049 
00050 class CContour  
00051 {
00052 protected:
00053         // plots a line from (x1,y1) to (x2,y2)
00054         virtual void ExportLine(int iPlane,int x1,int y1,int x2,int y2) = 0;
00055 
00056 public:
00057         CContour();
00058         virtual ~CContour(){CleanMemory();}
00059 protected: //G.Barrand
00060         inline CContour(const CContour&){}
00061 private: //G.Barrand
00062         inline CContour& operator=(const CContour&){return *this;}
00063 public:
00064         // Initialize memory. Called in Generate
00065         virtual void InitMemory();
00066         // Clean work arrays
00067         virtual void CleanMemory();
00068         // Generates contour
00069         // Before calling this functions you must
00070         //      1. derive the function ExportLine that is 
00071         //              supposed to draw/store the segment of the contour
00072         //      2. Set the function draw contour of. (using  SetFieldFn
00073         //              The function must be declared as follows
00074         //              double (*myF)(double x , double y);
00075         virtual void Generate();
00076 
00077         // Set the dimension of the primary grid
00078         void SetFirstGrid(int iCol, int iRow);
00079         // Set the dimension of the base grid
00080         void SetSecondaryGrid(int iCol, int iRow);
00081         // Sets the region [left, right, bottom,top] to generate contour 
00082         void SetLimits(double pLimits[4]);
00083         // Sets the isocurve values
00084         void SetPlanes(const std::vector<double>& vPlanes);
00085         // Sets the pointer to the F(x,y) funtion
00086         // G.Barrand : handle a user data pointer.
00087         void SetFieldFcn(double (*_pFieldFcn)(double, double,void*),void*);
00088 
00089         // Retrieve dimension of grids, contouring region and isocurve
00090         inline int GetColFir() const            {       return m_iColFir;};
00091         inline int GetRowFir() const            {       return m_iRowFir;};
00092         inline int GetColSec() const            {       return m_iColSec;};
00093         inline int GetRowSec() const            {       return m_iRowSec;};
00094         void GetLimits(double pLimits[4]);
00095         inline unsigned int GetNPlanes() const { return m_vPlanes.size();};
00096         inline const std::vector<double>& GetPlanes() const     {       return m_vPlanes;};
00097         double GetPlane(unsigned int i) const;
00098 
00099         // For an indexed point i on the sec. grid, returns x(i)
00100         inline double GetXi(int i) const {      return m_pLimits[0] +  i%(m_iColSec+1)*(m_pLimits[1]-m_pLimits[0])/(double)( m_iColSec );};
00101         // For an indexed point i on the fir. grid, returns y(i)
00102         double GetYi(int i) const;
00103 
00104 private:
00105   // A structure used internally by CContour
00106   struct CFnStr {
00107     double m_dFnVal;
00108     short m_sLeftLen;
00109     short m_sRightLen;
00110     short m_sTopLen;
00111     short m_sBotLen;
00112   };
00113 
00114 
00115 protected:
00116         // Accesibles variables
00117         std::vector<double> m_vPlanes;                  // value of contour planes
00118         double m_pLimits[4];                                            // left, right, bottom, top
00119         int m_iColFir;                                                          // primary      grid, number of columns
00120         int m_iRowFir;                                                          // primary      grid, number of rows
00121         int m_iColSec;                                                          // secondary grid, number of columns
00122         int m_iRowSec;                                                          // secondary grid, number of rows
00123         void* m_pFieldFcnData; // G.Barrand : handle a user data pointer.
00124         double (*m_pFieldFcn)(double x, double y,void*); // pointer to F(x,y) function
00125 
00126         // Protected function
00127         //virtual void ExportLine(int iPlane, int x1, int y1, int x2, int y2) = 0; // plots a line from (x1,y1) to (x2,y2)
00128 
00129         // Work functions and variables
00130         double m_dDx;
00131         double m_dDy;
00132         CFnStr** m_ppFnData;    // pointer to mesh parts
00133         inline CFnStr* FnctData(int i,int j)  { return (m_ppFnData[i]+j);};
00134 
00135         double Field(int x, int y);      /* evaluate funct if we must,  */
00136         void Cntr1(int x1, int x2, int y1, int y2);
00137         void Pass2(int x1, int x2, int y1, int y2);       /* draws the contour lines */
00138 
00139 private:
00140         //G.Barrand : have the below in the class.
00141         // A simple test function
00142         inline static double ContourTestFunction(double x,double y,void*) {  
00143           return 0.5*(::cos(x+3.14/4)+::sin(y+3.14/4)); 
00144         }
00145 
00146 protected:
00147         inline static void ASSERT(bool a_what,const char* a_where) {
00148           if(!a_what) {
00149             ::printf("debug : Contour : assert failure in %s\n",a_where);
00150             ::exit(0);
00151           }
00152         }
00153 
00154         inline static void ASSERTP(void* a_what,const char* a_where) {
00155           if(!a_what) {
00156             ::printf("debug : Contour : assert failure in %s\n",a_where);
00157             ::exit(0);
00158           }
00159         }
00160 
00161 };
00162 
00163 // implementation :
00164 //
00165 //  Code get on the web at : 
00166 //    http://www.codeproject.com/cpp/contour.asp
00167 //  
00168 //  G.Barrand 
00169 //
00170 
00172 // Construction/Destruction
00174 
00175 inline CContour::CContour()
00176 {
00177         m_iColFir=m_iRowFir=32;
00178         m_iColSec=m_iRowSec=256;
00179         m_dDx=m_dDy=0;
00180         m_pFieldFcnData = NULL;
00181         m_pFieldFcn=NULL;
00182         m_pLimits[0]=m_pLimits[2]=0;
00183         m_pLimits[1]=m_pLimits[3]=5.;
00184         m_ppFnData=NULL;
00185 
00186         // temporary stuff
00187         m_pFieldFcn=ContourTestFunction;
00188         m_vPlanes.resize(20);
00189         for (unsigned int i=0;i<m_vPlanes.size();i++)
00190         {
00191                 m_vPlanes[i]=(i-m_vPlanes.size()/2.0)*0.1;
00192         }
00193 }
00194 
00195 //G.Barrand : inline
00196 
00197 inline void CContour::InitMemory()
00198 {
00199         if (!m_ppFnData)
00200         {
00201                 m_ppFnData=new CFnStr*[m_iColSec+1];
00202                 for (int i=0;i<m_iColSec+1;i++)
00203                 {
00204                         m_ppFnData[i]=NULL;
00205                 }
00206         }
00207 }
00208 
00209 inline void CContour::CleanMemory()
00210 {
00211         if (m_ppFnData)
00212         {
00213                 int i;
00214                 for (i=0;i<m_iColSec+1;i++)
00215                 {
00216                         if (m_ppFnData[i])
00217                                 delete[] (m_ppFnData[i]);
00218                 }
00219                 delete[] m_ppFnData;
00220                 m_ppFnData=NULL;
00221         }
00222 }
00223 
00224 inline void CContour::Generate()
00225 {
00226 
00227         int i, j;
00228         int x3, x4, y3, y4, x, y, oldx3, xlow;
00229         const int cols=m_iColSec+1;
00230         const int rows=m_iRowSec+1;
00231         double xoff,yoff;
00232         
00233         // Initialize memroy if needed
00234         InitMemory();
00235 
00236         m_dDx = (m_pLimits[1]-m_pLimits[0])/(double)(m_iColSec);
00237         xoff = m_pLimits[0];
00238         m_dDy = (m_pLimits[3]-m_pLimits[2])/(double)(m_iRowSec);
00239         yoff = m_pLimits[2];
00240 
00241         xlow = 0;
00242         oldx3 = 0;
00243         x3 = (cols-1)/m_iRowFir;
00244         x4 = ( 2*(cols-1) )/m_iRowFir;
00245         for (x = oldx3; x <= x4; x++) 
00246         {         /* allocate new columns needed
00247                 */
00248                 if (x >= cols)
00249                         break;
00250                 if (m_ppFnData[x]==NULL)
00251                         m_ppFnData[x] = new CFnStr[rows];
00252 
00253                 for (y = 0; y < rows; y++)
00254                         FnctData(x,y)->m_sTopLen = -1;
00255         }
00256 
00257         y4 = 0;
00258         for (j = 0; j < m_iColFir; j++) 
00259         {
00260                 y3 = y4;
00261                 y4 = ((j+1)*(rows-1))/m_iColFir;
00262                 Cntr1(oldx3, x3, y3, y4);
00263         }
00264 
00265         for (i = 1; i < m_iRowFir; i++) 
00266         {
00267                 y4 = 0;
00268                 for (j = 0; j < m_iColFir; j++) 
00269                 {
00270                         y3 = y4;
00271                         y4 = ((j+1)*(rows-1))/m_iColFir;
00272                         Cntr1(x3, x4, y3, y4);
00273                 }
00274 
00275                 y4 = 0;
00276                 for (j = 0; j < m_iColFir; j++) 
00277                 {
00278                         y3 = y4;
00279                         y4 = ((j+1)*(rows-1))/m_iColFir;
00280                         Pass2(oldx3,x3,y3,y4);
00281                 }
00282 
00283                 if (i < (m_iRowFir-1)) 
00284                 {        /* re-use columns no longer needed */
00285                         oldx3 = x3;
00286                         x3 = x4;
00287                         x4 = ((i+2)*(cols-1))/m_iRowFir;
00288                         for (x = x3+1; x <= x4; x++) 
00289                         {
00290                                 if (xlow < oldx3) 
00291                                 {
00292                                         if (m_ppFnData[x])
00293                                                 delete[] m_ppFnData[x];
00294                                         m_ppFnData[x] = m_ppFnData[xlow];
00295                                         m_ppFnData[ xlow++ ] = NULL;
00296                                 } 
00297                                 else
00298                                         if (m_ppFnData[x]==NULL)
00299                                                 m_ppFnData[x] = new CFnStr[rows];
00300 
00301                                 for (y = 0; y < rows; y++)
00302                                         FnctData(x,y)->m_sTopLen = -1;
00303                         }
00304                 }
00305         }
00306 
00307         y4 = 0;
00308         for (j = 0; j < m_iColFir; j++) 
00309         {
00310                 y3 = y4;
00311                 y4 = ((j+1)*(rows-1))/m_iColFir;
00312                 Pass2(x3,x4,y3,y4);
00313         }
00314 }
00315 
00316 inline void CContour::Cntr1(int x1, int x2, int y1, int y2)
00317 {
00318         double f11, f12, f21, f22, f33;
00319         int x3, y3, i, j;
00320         
00321         if ((x1 == x2) || (y1 == y2))   /* if not a real cell, punt */
00322                 return;
00323         f11 = Field(x1, y1);
00324         f12 = Field(x1, y2);
00325         f21 = Field(x2, y1);
00326         f22 = Field(x2, y2);
00327         if ((x2 > x1+1) || (y2 > y1+1)) {       /* is cell divisible? */
00328                 x3 = (x1+x2)/2;
00329                 y3 = (y1+y2)/2;
00330                 f33 = Field(x3, y3);
00331                 i = j = 0;
00332                 if (f33 < f11) i++; else if (f33 > f11) j++;
00333                 if (f33 < f12) i++; else if (f33 > f12) j++;
00334                 if (f33 < f21) i++; else if (f33 > f21) j++;
00335                 if (f33 < f22) i++; else if (f33 > f22) j++;
00336                 if ((i > 2) || (j > 2)) /* should we divide cell? */
00337                 {       
00338                         /* subdivide cell */
00339                         Cntr1(x1, x3, y1, y3);
00340                         Cntr1(x3, x2, y1, y3);
00341                         Cntr1(x1, x3, y3, y2);
00342                         Cntr1(x3, x2, y3, y2);
00343                         return;
00344                 }
00345         }
00346         /* install cell in array */
00347         FnctData(x1,y2)->m_sBotLen = FnctData(x1,y1)->m_sTopLen = x2-x1;
00348         FnctData(x2,y1)->m_sLeftLen = FnctData(x1,y1)->m_sRightLen = y2-y1;
00349 }
00350 
00351 inline void CContour::Pass2(int x1, int x2, int y1, int y2)
00352 {
00353         int left = 0, right = 0, top = 0, bot = 0,old, iNew, i, j, x3, y3;
00354         double yy0 = 0, yy1 = 0, xx0 = 0, xx1 = 0, xx3, yy3;
00355         double v, f11, f12, f21, f22, f33, fold, fnew, f;
00356         double xoff=m_pLimits[0];
00357         double yoff=m_pLimits[2];
00358         
00359         if ((x1 == x2) || (y1 == y2))   /* if not a real cell, punt */
00360                 return;
00361         f11 = FnctData(x1,y1)->m_dFnVal;
00362         f12 = FnctData(x1,y2)->m_dFnVal;
00363         f21 = FnctData(x2,y1)->m_dFnVal;
00364         f22 = FnctData(x2,y2)->m_dFnVal;
00365         if ((x2 > x1+1) || (y2 > y1+1)) /* is cell divisible? */
00366         {       
00367                 x3 = (x1+x2)/2;
00368                 y3 = (y1+y2)/2;
00369                 f33 = FnctData(x3, y3)->m_dFnVal;
00370                 i = j = 0;
00371                 if (f33 < f11) i++; else if (f33 > f11) j++;
00372                 if (f33 < f12) i++; else if (f33 > f12) j++;
00373                 if (f33 < f21) i++; else if (f33 > f21) j++;
00374                 if (f33 < f22) i++; else if (f33 > f22) j++;
00375                 if ((i > 2) || (j > 2)) /* should we divide cell? */ 
00376                 {       
00377                         /* subdivide cell */
00378                         Pass2(x1, x3, y1, y3);
00379                         Pass2(x3, x2, y1, y3);
00380                         Pass2(x1, x3, y3, y2);
00381                         Pass2(x3, x2, y3, y2);
00382                         return;
00383                 }
00384         }
00385 
00386         for (i = 0; i < (int)m_vPlanes.size(); i++) 
00387         {
00388                 v = m_vPlanes[i];
00389                 j = 0;
00390                 if (f21 > v) j++;
00391                 if (f11 > v) j |= 2;
00392                 if (f22 > v) j |= 4;
00393                 if (f12 > v) j |= 010;
00394                 if ((f11 > v) ^ (f12 > v)) 
00395                 {
00396                         if ((FnctData(x1,y1)->m_sLeftLen != 0) &&
00397                                 (FnctData(x1,y1)->m_sLeftLen < FnctData(x1,y1)->m_sRightLen)) 
00398                         {
00399                                 old = y1;
00400                                 fold = f11;
00401                                 while (1) 
00402                                 {
00403                                         iNew = old+FnctData(x1,old)->m_sLeftLen;
00404                                         fnew = FnctData(x1,iNew)->m_dFnVal;
00405                                         if ((fnew > v) ^ (fold > v))
00406                                                 break;
00407                                         old = iNew;
00408                                         fold = fnew;
00409                                 }
00410                                 yy0 = ((old-y1)+(iNew-old)*(v-fold)/(fnew-fold))/(y2-y1);
00411                         } 
00412                         else
00413                                 yy0 = (v-f11)/(f12-f11);
00414 
00415                         left = (int)(y1+(y2-y1)*yy0+0.5);
00416                 }
00417                 if ((f21 > v) ^ (f22 > v)) 
00418                 {
00419                         if ((FnctData(x2,y1)->m_sRightLen != 0) &&
00420                                 (FnctData(x2,y1)->m_sRightLen < FnctData(x2,y1)->m_sLeftLen)) 
00421                         {
00422                                 old = y1;
00423                                 fold = f21;
00424                                 while (1) 
00425                                 {
00426                                         iNew = old+FnctData(x2,old)->m_sRightLen;
00427                                         fnew = FnctData(x2,iNew)->m_dFnVal;
00428                                         if ((fnew > v) ^ (fold > v))
00429                                                 break;
00430                                         old = iNew;
00431                                         fold = fnew;
00432                                 }
00433                                 yy1 = ((old-y1)+(iNew-old)*(v-fold)/(fnew-fold))/(y2-y1);
00434                         } 
00435                         else
00436                                 yy1 = (v-f21)/(f22-f21);
00437 
00438                         right = (int)(y1+(y2-y1)*yy1+0.5);
00439                 }
00440                 if ((f21 > v) ^ (f11 > v)) 
00441                 {
00442                         if ((FnctData(x1,y1)->m_sBotLen != 0) &&
00443                                 (FnctData(x1,y1)->m_sBotLen < FnctData(x1,y1)->m_sTopLen)) {
00444                                 old = x1;
00445                                 fold = f11;
00446                                 while (1) {
00447                                         iNew = old+FnctData(old,y1)->m_sBotLen;
00448                                         fnew = FnctData(iNew,y1)->m_dFnVal;
00449                                         if ((fnew > v) ^ (fold > v))
00450                                                 break;
00451                                         old = iNew;
00452                                         fold = fnew;
00453                                 }
00454                                 xx0 = ((old-x1)+(iNew-old)*(v-fold)/(fnew-fold))/(x2-x1);
00455                         } 
00456                         else
00457                                 xx0 = (v-f11)/(f21-f11);
00458 
00459                         bot = (int)(x1+(x2-x1)*xx0+0.5);
00460                 }
00461                 if ((f22 > v) ^ (f12 > v)) 
00462                 {
00463                         if ((FnctData(x1,y2)->m_sTopLen != 0) &&
00464                                 (FnctData(x1,y2)->m_sTopLen < FnctData(x1,y2)->m_sBotLen)) {
00465                                 old = x1;
00466                                 fold = f12;
00467                                 while (1) {
00468                                         iNew = old+FnctData(old,y2)->m_sTopLen;
00469                                         fnew = FnctData(iNew,y2)->m_dFnVal;
00470                                         if ((fnew > v) ^ (fold > v))
00471                                                 break;
00472                                         old = iNew;
00473                                         fold = fnew;
00474                                 }
00475                                 xx1 = ((old-x1)+(iNew-old)*(v-fold)/(fnew-fold))/(x2-x1);
00476                         } 
00477                         else
00478                                 xx1 = (v-f12)/(f22-f12);
00479 
00480                         top = (int)(x1+(x2-x1)*xx1+0.5);
00481                 }
00482 
00483                 switch (j) 
00484                 {
00485                         case 7:
00486                         case 010:
00487                                 ExportLine(i,x1,left,top,y2);
00488                                 break;
00489                         case 5:
00490                         case 012:
00491                                 ExportLine(i,bot,y1,top,y2);
00492                                 break;
00493                         case 2:
00494                         case 015:
00495                                 ExportLine(i,x1,left,bot,y1);
00496                         break;
00497                 case 4:
00498                 case 013:
00499                         ExportLine(i,top,y2,x2,right);
00500                         break;
00501                 case 3:
00502                 case 014:
00503                         ExportLine(i,x1,left,x2,right);
00504                         break;
00505                 case 1:
00506                 case 016:
00507                         ExportLine(i,bot,y1,x2,right);
00508                         break;
00509                 case 0:
00510                 case 017:
00511                         break;
00512                 case 6:
00513                 case 011:
00514                         yy3 = (xx0*(yy1-yy0)+yy0)/(1.0-(xx1-xx0)*(yy1-yy0));
00515                         xx3 = yy3*(xx1-xx0)+xx0;
00516                         xx3 = x1+xx3*(x2-x1);
00517                         yy3 = y1+yy3*(y2-y1);
00518                         xx3 = xoff+xx3*m_dDx;
00519                         yy3 = yoff+yy3*m_dDy;
00520                         f = (*m_pFieldFcn)(xx3, yy3,m_pFieldFcnData);
00521                         if (f == v) {
00522                                 ExportLine(i,bot,y1,top,y2);
00523                                 ExportLine(i,x1,left,x2,right);
00524                         } else
00525                                 if (((f > v) && (f22 > v)) || ((f < v) && (f22 < v))) {
00526                                         ExportLine(i,x1,left,top,y2);
00527                                         ExportLine(i,bot,y1,x2,right);
00528                                 } else {
00529                                         ExportLine(i,x1,left,bot,y1);
00530                                         ExportLine(i,top,y2,x2,right);
00531                                 }
00532                 }
00533         }
00534 }
00535 
00536 inline double CContour::Field(int x, int y)  /* evaluate funct if we must,*/
00537 {
00538         double x1, y1;
00539         
00540         if (FnctData(x,y)->m_sTopLen != -1)  /* is it already in the array */
00541                 return(FnctData(x,y)->m_dFnVal);
00542 
00543         /* not in the array, create new array element */
00544         x1 = m_pLimits[0]+m_dDx*x;
00545         y1 = m_pLimits[2]+m_dDy*y;
00546         FnctData(x,y)->m_sTopLen = 0;
00547         FnctData(x,y)->m_sBotLen = 0;
00548         FnctData(x,y)->m_sRightLen = 0;
00549         FnctData(x,y)->m_sLeftLen = 0;
00550         return (FnctData(x,y)->m_dFnVal = (*m_pFieldFcn)(x1, y1,m_pFieldFcnData));
00551 }
00552 
00553 inline void CContour::SetPlanes(const std::vector<double>& vPlanes)
00554 {       
00555         // cleaning memory
00556         CleanMemory();
00557 
00558         m_vPlanes = vPlanes;
00559 }
00560 
00561 inline void CContour::SetFieldFcn(double (*_pFieldFcn)(double, double,void*),void* aData) 
00562 {       
00563         m_pFieldFcnData = aData;
00564         m_pFieldFcn=_pFieldFcn;
00565 }
00566 
00567 inline void CContour::SetFirstGrid(int iCol, int iRow)
00568 {
00569         m_iColFir=mx<int>(iCol,2);
00570         m_iRowFir=mx<int>(iRow,2);
00571 }
00572 
00573 inline void CContour::SetSecondaryGrid(int iCol, int iRow)
00574 {
00575         // cleaning work matrices if allocated
00576         CleanMemory();
00577 
00578         m_iColSec=mx<int>(iCol,2);
00579         m_iRowSec=mx<int>(iRow,2);
00580 }
00581 
00582 inline void CContour::SetLimits(double pLimits[])
00583 {
00584         ASSERT(pLimits[0]<pLimits[1],"CContour::SetLimits");
00585         ASSERT(pLimits[2]<pLimits[3],"CContour::SetLimits");
00586         for (int i=0;i<4;i++)
00587         {
00588                 m_pLimits[i]=pLimits[i];
00589         }       
00590 }
00591 
00592 inline void CContour::GetLimits(double pLimits[])
00593 {
00594         for (int i=0;i<4;i++)
00595         {
00596                 pLimits[i]=m_pLimits[i];
00597         }
00598 }
00599 
00600 //G.Barrand : from .h to .cxx to avoid ASSERT in .h
00601 inline double CContour::GetPlane(unsigned int i) const  {
00602   /*ASSERT(i>=0);*/
00603   ASSERT(i<m_vPlanes.size(),"CContour::GetPlane");
00604   return m_vPlanes[i];
00605 }
00606 
00607 inline double CContour::GetYi(int i) const {
00608   if(i<0) ::printf("CContour::GetYi : %d\n",i);
00609   ASSERT(i>=0,"CContour::GetYi");
00610   return m_pLimits[2] +  i/(m_iColSec+1)*(m_pLimits[3]-m_pLimits[2])/(double)( m_iRowSec );
00611 }
00612 
00613 }
00614 
00615 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines