Warning, /include/Geant4/tools/ccontour is written in an unsupported language. File is not indexed.
0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003
0004 #ifndef tools_ccontour
0005 #define tools_ccontour
0006
0007 // G.Barrand : inline version of the one found in Lib of OSC 16.11.
0008 // This code is not mine and I keep it "as it is".
0009
0010 // Contour.h: interface for the ccontour class.
0011 //
0012 // ccontour implements Contour plot algorithm descrided in
0013 // IMPLEMENTATION OF
0014 // AN IMPROVED CONTOUR
0015 // PLOTTING ALGORITHM
0016 // BY
0017 //
0018 // MICHAEL JOSEPH ARAMINI
0019 //
0020 // B.S., Stevens Institute of Technology, 1980
0021 // See http://www.ultranet.com/~aramini/thesis.html
0022 //
0023 // Ported to C++ by Jonathan de Halleux.
0024 //
0025 // Using ccontour :
0026 //
0027 // ccontour is not directly usable. The user has to
0028 // 1. derive the function ExportLine that is
0029 // supposed to draw/store the segment of the contour
0030 // 2. Set the function draw contour of. (using SetFieldFn
0031 // The function must be declared as follows
0032 // double (*myF)(double x , double y);
0033 //
0034 // History:
0035 // 31-07-2002:
0036 // - A lot of contribution from Chenggang Zhou (better strip compressions, merging, area, weight),
0037 // - Got rid of ugly MFC lists for STL.
0038 //////////////////////////////////////////////////////////////////////
0039
0040 //G.Barrand :
0041 #include <vector>
0042 #include <cstdio>
0043 #include <cstdlib>
0044 #include <cmath>
0045
0046 #ifdef TOOLS_MEM
0047 #include "mem"
0048 #endif
0049
0050 #include "mnmx"
0051
0052 namespace tools {
0053
0054 class ccontour
0055 {
0056 #ifdef TOOLS_MEM
0057 static const std::string& s_class() {
0058 static const std::string s_v("tools::ccontour");
0059 return s_v;
0060 }
0061 #endif
0062 protected:
0063 // plots a line from (x1,y1) to (x2,y2)
0064 virtual void ExportLine(int iPlane,int x1,int y1,int x2,int y2) = 0;
0065
0066 public:
0067 ccontour();
0068 virtual ~ccontour(){
0069 CleanMemory();
0070 #ifdef TOOLS_MEM
0071 mem::decrement(s_class().c_str());
0072 #endif
0073 }
0074 protected: //G.Barrand
0075 ccontour(const ccontour&){}
0076 private: //G.Barrand
0077 ccontour& operator=(const ccontour&){return *this;}
0078 public:
0079 protected: //G.Barrand
0080 // Initialize memory. Called in generate
0081 virtual void InitMemory();
0082 // Clean work arrays
0083 virtual void CleanMemory();
0084 // generates contour
0085 // Before calling this functions you must
0086 // 1. derive the function ExportLine that is
0087 // supposed to draw/store the segment of the contour
0088 // 2. Set the function draw contour of. (using SetFieldFn
0089 // The function must be declared as follows
0090 // double (*myF)(double x , double y);
0091 public: //G.Barrand
0092 virtual void generate();
0093
0094 // Set the dimension of the primary grid
0095 void set_first_grid(int iCol, int iRow);
0096 // Set the dimension of the base grid
0097 void set_secondary_grid(int iCol, int iRow);
0098 // Sets the region [left, right, bottom,top] to generate contour
0099 void set_limits(double pLimits[4]);
0100 // Sets the isocurve values
0101 void set_planes(const std::vector<double>& vPlanes);
0102 // Sets the pointer to the F(x,y) funtion
0103 // G.Barrand : handle a user data pointer.
0104 void set_field_fcn(double (*_pFieldFcn)(double, double,void*),void*);
0105
0106 size_t get_number_of_planes() const { return m_vPlanes.size();};
0107 const std::vector<double>& get_planes() const { return m_vPlanes;};
0108 double get_plane(unsigned int i) const;
0109
0110 // For an indexed point i on the sec. grid, returns x(i)
0111 double get_xi(int i) const { return m_pLimits[0] + i%(m_iColSec+1)*(m_pLimits[1]-m_pLimits[0])/(double)( m_iColSec );};
0112 // For an indexed point i on the fir. grid, returns y(i)
0113 double get_yi(int i) const;
0114
0115 void get_limits(double pLimits[4]);
0116 protected: //G.Barrand
0117
0118 // Retrieve dimension of grids, contouring region and isocurve
0119 int GetColFir() const { return m_iColFir;};
0120 int GetRowFir() const { return m_iRowFir;};
0121 int GetColSec() const { return m_iColSec;};
0122 int GetRowSec() const { return m_iRowSec;};
0123
0124 private:
0125 // A structure used internally by ccontour
0126 /*G.Barrand :
0127 struct CFnStr {
0128 double m_dFnVal;
0129 short m_sLeftLen;
0130 short m_sRightLen;
0131 short m_sTopLen;
0132 short m_sBotLen;
0133 };
0134 */
0135 class CFnStr {
0136 #ifdef TOOLS_MEM
0137 static const std::string& s_class() {
0138 static const std::string s_v("tools::ccontour::CFnStr");
0139 return s_v;
0140 }
0141 #endif
0142 public:
0143 CFnStr():m_dFnVal(0),m_sLeftLen(0),m_sRightLen(0),m_sTopLen(0),m_sBotLen(0){
0144 #ifdef TOOLS_MEM
0145 mem::increment(s_class().c_str());
0146 #endif
0147 }
0148 ~CFnStr(){
0149 #ifdef TOOLS_MEM
0150 mem::decrement(s_class().c_str());
0151 #endif
0152 }
0153 protected:
0154 CFnStr(const CFnStr&){}
0155 CFnStr& operator=(const CFnStr&){return *this;}
0156 public:
0157 double m_dFnVal;
0158 short m_sLeftLen;
0159 short m_sRightLen;
0160 short m_sTopLen;
0161 short m_sBotLen;
0162 };
0163
0164
0165 protected:
0166 // Accesibles variables
0167 std::vector<double> m_vPlanes; // value of contour planes
0168 double m_pLimits[4]; // left, right, bottom, top
0169 int m_iColFir; // primary grid, number of columns
0170 int m_iRowFir; // primary grid, number of rows
0171 unsigned int m_iColSec; // secondary grid, number of columns
0172 unsigned int m_iRowSec; // secondary grid, number of rows
0173 void* m_pFieldFcnData; // G.Barrand : handle a user data pointer.
0174 double (*m_pFieldFcn)(double x, double y,void*); // pointer to F(x,y) function
0175
0176 // Protected function
0177 //virtual void ExportLine(int iPlane, int x1, int y1, int x2, int y2) = 0; // plots a line from (x1,y1) to (x2,y2)
0178
0179 // Work functions and variables
0180 double m_dDx;
0181 double m_dDy;
0182 CFnStr** m_ppFnData; // pointer to mesh parts
0183 CFnStr* FnctData(int i,int j) { return (m_ppFnData[i]+j);};
0184
0185 double Field(int x, int y); /* evaluate funct if we must, */
0186 void Cntr1(int x1, int x2, int y1, int y2);
0187 void Pass2(int x1, int x2, int y1, int y2); /* draws the contour lines */
0188
0189 private:
0190 //G.Barrand : have the below in the class.
0191 // A simple test function
0192 static double ContourTestFunction(double x,double y,void*) {
0193 return 0.5*(::cos(x+3.14/4)+::sin(y+3.14/4));
0194 }
0195
0196 protected:
0197 static void _ASSERT_(bool a_what,const char* a_where) {
0198 if(!a_what) {
0199 ::printf("debug : Contour : assert failure in %s\n",a_where);
0200 ::exit(0);
0201 }
0202 }
0203
0204 static void _ASSERTP_(void* a_what,const char* a_where) {
0205 if(!a_what) {
0206 ::printf("debug : Contour : assert failure in %s\n",a_where);
0207 ::exit(0);
0208 }
0209 }
0210
0211 };
0212
0213 // implementation :
0214 //
0215 // Code get on the web at :
0216 // http://www.codeproject.com/cpp/contour.asp
0217 //
0218 // G.Barrand
0219 //
0220
0221 //////////////////////////////////////////////////////////////////////
0222 // Construction/Destruction
0223 //////////////////////////////////////////////////////////////////////
0224
0225 inline ccontour::ccontour()
0226 {
0227 #ifdef TOOLS_MEM
0228 mem::increment(s_class().c_str());
0229 #endif
0230 m_iColFir=m_iRowFir=32;
0231 m_iColSec=m_iRowSec=256;
0232 m_dDx=m_dDy=0;
0233 m_pFieldFcnData = NULL;
0234 m_pFieldFcn=NULL;
0235 m_pLimits[0]=m_pLimits[2]=0;
0236 m_pLimits[1]=m_pLimits[3]=5.;
0237 m_ppFnData=NULL;
0238
0239 // temporary stuff
0240 m_pFieldFcn=ContourTestFunction;
0241 m_vPlanes.resize(20);
0242 for (unsigned int i=0;i<m_vPlanes.size();i++)
0243 {
0244 m_vPlanes[i]=(i-m_vPlanes.size()/2.0)*0.1;
0245 }
0246 }
0247
0248 //G.Barrand : inline
0249
0250 inline void ccontour::InitMemory()
0251 {
0252 if (!m_ppFnData)
0253 {
0254 m_ppFnData=new CFnStr*[m_iColSec+1];
0255 for (unsigned int i=0;i<m_iColSec+1;i++)
0256 {
0257 m_ppFnData[i]=NULL;
0258 }
0259 }
0260 }
0261
0262 inline void ccontour::CleanMemory()
0263 {
0264 if (m_ppFnData)
0265 {
0266 for (unsigned int i=0;i<m_iColSec+1;i++)
0267 {
0268 if (m_ppFnData[i])
0269 delete[] (m_ppFnData[i]);
0270 }
0271 delete[] m_ppFnData;
0272 m_ppFnData=NULL;
0273 }
0274 }
0275
0276 inline void ccontour::generate()
0277 {
0278
0279 int i, j;
0280 int x3, x4, y3, y4, x, y, oldx3, xlow;
0281 const unsigned int cols=m_iColSec+1;
0282 const unsigned int rows=m_iRowSec+1;
0283 //double xoff,yoff;
0284
0285 // Initialize memroy if needed
0286 InitMemory();
0287
0288 m_dDx = (m_pLimits[1]-m_pLimits[0])/(double)(m_iColSec);
0289 //xoff = m_pLimits[0];
0290 m_dDy = (m_pLimits[3]-m_pLimits[2])/(double)(m_iRowSec);
0291 //yoff = m_pLimits[2];
0292
0293 xlow = 0;
0294 oldx3 = 0;
0295 x3 = (cols-1)/m_iRowFir;
0296 x4 = ( 2*(cols-1) )/m_iRowFir;
0297 for (x = oldx3; x <= x4; x++)
0298 { /* allocate new columns needed
0299 */
0300 if (x >= (int)cols)
0301 break;
0302 if (m_ppFnData[x]==NULL)
0303 m_ppFnData[x] = new CFnStr[rows];
0304
0305 for (y = 0; y < (int)rows; y++)
0306 FnctData(x,y)->m_sTopLen = -1;
0307 }
0308
0309 y4 = 0;
0310 for (j = 0; j < m_iColFir; j++)
0311 {
0312 y3 = y4;
0313 y4 = ((j+1)*(rows-1))/m_iColFir;
0314 Cntr1(oldx3, x3, y3, y4);
0315 }
0316
0317 for (i = 1; i < m_iRowFir; i++)
0318 {
0319 y4 = 0;
0320 for (j = 0; j < m_iColFir; j++)
0321 {
0322 y3 = y4;
0323 y4 = ((j+1)*(rows-1))/m_iColFir;
0324 Cntr1(x3, x4, y3, y4);
0325 }
0326
0327 y4 = 0;
0328 for (j = 0; j < m_iColFir; j++)
0329 {
0330 y3 = y4;
0331 y4 = ((j+1)*(rows-1))/m_iColFir;
0332 Pass2(oldx3,x3,y3,y4);
0333 }
0334
0335 if (i < (m_iRowFir-1))
0336 { /* re-use columns no longer needed */
0337 oldx3 = x3;
0338 x3 = x4;
0339 x4 = ((i+2)*(cols-1))/m_iRowFir;
0340 for (x = x3+1; x <= x4; x++)
0341 {
0342 if (xlow < oldx3)
0343 {
0344 if (m_ppFnData[x])
0345 delete[] m_ppFnData[x];
0346 m_ppFnData[x] = m_ppFnData[xlow];
0347 m_ppFnData[ xlow++ ] = NULL;
0348 }
0349 else
0350 if (m_ppFnData[x]==NULL)
0351 m_ppFnData[x] = new CFnStr[rows];
0352
0353 for (y = 0; y < (int)rows; y++)
0354 FnctData(x,y)->m_sTopLen = -1;
0355 }
0356 }
0357 }
0358
0359 y4 = 0;
0360 for (j = 0; j < m_iColFir; j++)
0361 {
0362 y3 = y4;
0363 y4 = ((j+1)*(rows-1))/m_iColFir;
0364 Pass2(x3,x4,y3,y4);
0365 }
0366 }
0367
0368 inline void ccontour::Cntr1(int x1, int x2, int y1, int y2)
0369 {
0370 double f11, f12, f21, f22, f33;
0371 int x3, y3, i, j;
0372
0373 if ((x1 == x2) || (y1 == y2)) /* if not a real cell, punt */
0374 return;
0375 f11 = Field(x1, y1);
0376 f12 = Field(x1, y2);
0377 f21 = Field(x2, y1);
0378 f22 = Field(x2, y2);
0379 if ((x2 > x1+1) || (y2 > y1+1)) { /* is cell divisible? */
0380 x3 = (x1+x2)/2;
0381 y3 = (y1+y2)/2;
0382 f33 = Field(x3, y3);
0383 i = j = 0;
0384 if (f33 < f11) i++; else if (f33 > f11) j++;
0385 if (f33 < f12) i++; else if (f33 > f12) j++;
0386 if (f33 < f21) i++; else if (f33 > f21) j++;
0387 if (f33 < f22) i++; else if (f33 > f22) j++;
0388 if ((i > 2) || (j > 2)) /* should we divide cell? */
0389 {
0390 /* subdivide cell */
0391 Cntr1(x1, x3, y1, y3);
0392 Cntr1(x3, x2, y1, y3);
0393 Cntr1(x1, x3, y3, y2);
0394 Cntr1(x3, x2, y3, y2);
0395 return;
0396 }
0397 }
0398 /* install cell in array */
0399 FnctData(x1,y2)->m_sBotLen = FnctData(x1,y1)->m_sTopLen = x2-x1;
0400 FnctData(x2,y1)->m_sLeftLen = FnctData(x1,y1)->m_sRightLen = y2-y1;
0401 }
0402
0403 inline void ccontour::Pass2(int x1, int x2, int y1, int y2)
0404 {
0405 int left = 0, right = 0, top = 0, bot = 0,old, iNew, i, j, x3, y3;
0406 double yy0 = 0, yy1 = 0, xx0 = 0, xx1 = 0, xx3, yy3;
0407 double v, f11, f12, f21, f22, f33, fold, fnew, f;
0408 double xoff=m_pLimits[0];
0409 double yoff=m_pLimits[2];
0410
0411 if ((x1 == x2) || (y1 == y2)) /* if not a real cell, punt */
0412 return;
0413 f11 = FnctData(x1,y1)->m_dFnVal;
0414 f12 = FnctData(x1,y2)->m_dFnVal;
0415 f21 = FnctData(x2,y1)->m_dFnVal;
0416 f22 = FnctData(x2,y2)->m_dFnVal;
0417 if ((x2 > x1+1) || (y2 > y1+1)) /* is cell divisible? */
0418 {
0419 x3 = (x1+x2)/2;
0420 y3 = (y1+y2)/2;
0421 f33 = FnctData(x3, y3)->m_dFnVal;
0422 i = j = 0;
0423 if (f33 < f11) i++; else if (f33 > f11) j++;
0424 if (f33 < f12) i++; else if (f33 > f12) j++;
0425 if (f33 < f21) i++; else if (f33 > f21) j++;
0426 if (f33 < f22) i++; else if (f33 > f22) j++;
0427 if ((i > 2) || (j > 2)) /* should we divide cell? */
0428 {
0429 /* subdivide cell */
0430 Pass2(x1, x3, y1, y3);
0431 Pass2(x3, x2, y1, y3);
0432 Pass2(x1, x3, y3, y2);
0433 Pass2(x3, x2, y3, y2);
0434 return;
0435 }
0436 }
0437
0438 for (i = 0; i < (int)m_vPlanes.size(); i++)
0439 {
0440 v = m_vPlanes[i];
0441 j = 0;
0442 if (f21 > v) j++;
0443 if (f11 > v) j |= 2;
0444 if (f22 > v) j |= 4;
0445 if (f12 > v) j |= 010;
0446 if ((f11 > v) ^ (f12 > v))
0447 {
0448 if ((FnctData(x1,y1)->m_sLeftLen != 0) &&
0449 (FnctData(x1,y1)->m_sLeftLen < FnctData(x1,y1)->m_sRightLen))
0450 {
0451 old = y1;
0452 fold = f11;
0453 while (1)
0454 {
0455 iNew = old+FnctData(x1,old)->m_sLeftLen;
0456 fnew = FnctData(x1,iNew)->m_dFnVal;
0457 if ((fnew > v) ^ (fold > v))
0458 break;
0459 old = iNew;
0460 fold = fnew;
0461 }
0462 yy0 = ((old-y1)+(iNew-old)*(v-fold)/(fnew-fold))/(y2-y1);
0463 }
0464 else
0465 yy0 = (v-f11)/(f12-f11);
0466
0467 left = (int)(y1+(y2-y1)*yy0+0.5);
0468 }
0469 if ((f21 > v) ^ (f22 > v))
0470 {
0471 if ((FnctData(x2,y1)->m_sRightLen != 0) &&
0472 (FnctData(x2,y1)->m_sRightLen < FnctData(x2,y1)->m_sLeftLen))
0473 {
0474 old = y1;
0475 fold = f21;
0476 while (1)
0477 {
0478 iNew = old+FnctData(x2,old)->m_sRightLen;
0479 fnew = FnctData(x2,iNew)->m_dFnVal;
0480 if ((fnew > v) ^ (fold > v))
0481 break;
0482 old = iNew;
0483 fold = fnew;
0484 }
0485 yy1 = ((old-y1)+(iNew-old)*(v-fold)/(fnew-fold))/(y2-y1);
0486 }
0487 else
0488 yy1 = (v-f21)/(f22-f21);
0489
0490 right = (int)(y1+(y2-y1)*yy1+0.5);
0491 }
0492 if ((f21 > v) ^ (f11 > v))
0493 {
0494 if ((FnctData(x1,y1)->m_sBotLen != 0) &&
0495 (FnctData(x1,y1)->m_sBotLen < FnctData(x1,y1)->m_sTopLen)) {
0496 old = x1;
0497 fold = f11;
0498 while (1) {
0499 iNew = old+FnctData(old,y1)->m_sBotLen;
0500 fnew = FnctData(iNew,y1)->m_dFnVal;
0501 if ((fnew > v) ^ (fold > v))
0502 break;
0503 old = iNew;
0504 fold = fnew;
0505 }
0506 xx0 = ((old-x1)+(iNew-old)*(v-fold)/(fnew-fold))/(x2-x1);
0507 }
0508 else
0509 xx0 = (v-f11)/(f21-f11);
0510
0511 bot = (int)(x1+(x2-x1)*xx0+0.5);
0512 }
0513 if ((f22 > v) ^ (f12 > v))
0514 {
0515 if ((FnctData(x1,y2)->m_sTopLen != 0) &&
0516 (FnctData(x1,y2)->m_sTopLen < FnctData(x1,y2)->m_sBotLen)) {
0517 old = x1;
0518 fold = f12;
0519 while (1) {
0520 iNew = old+FnctData(old,y2)->m_sTopLen;
0521 fnew = FnctData(iNew,y2)->m_dFnVal;
0522 if ((fnew > v) ^ (fold > v))
0523 break;
0524 old = iNew;
0525 fold = fnew;
0526 }
0527 xx1 = ((old-x1)+(iNew-old)*(v-fold)/(fnew-fold))/(x2-x1);
0528 }
0529 else
0530 xx1 = (v-f12)/(f22-f12);
0531
0532 top = (int)(x1+(x2-x1)*xx1+0.5);
0533 }
0534
0535 switch (j)
0536 {
0537 case 7:
0538 case 010:
0539 ExportLine(i,x1,left,top,y2);
0540 break;
0541 case 5:
0542 case 012:
0543 ExportLine(i,bot,y1,top,y2);
0544 break;
0545 case 2:
0546 case 015:
0547 ExportLine(i,x1,left,bot,y1);
0548 break;
0549 case 4:
0550 case 013:
0551 ExportLine(i,top,y2,x2,right);
0552 break;
0553 case 3:
0554 case 014:
0555 ExportLine(i,x1,left,x2,right);
0556 break;
0557 case 1:
0558 case 016:
0559 ExportLine(i,bot,y1,x2,right);
0560 break;
0561 case 0:
0562 case 017:
0563 break;
0564 case 6:
0565 case 011:
0566 yy3 = (xx0*(yy1-yy0)+yy0)/(1.0-(xx1-xx0)*(yy1-yy0));
0567 xx3 = yy3*(xx1-xx0)+xx0;
0568 xx3 = x1+xx3*(x2-x1);
0569 yy3 = y1+yy3*(y2-y1);
0570 xx3 = xoff+xx3*m_dDx;
0571 yy3 = yoff+yy3*m_dDy;
0572 f = (*m_pFieldFcn)(xx3, yy3,m_pFieldFcnData);
0573 if (f == v) {
0574 ExportLine(i,bot,y1,top,y2);
0575 ExportLine(i,x1,left,x2,right);
0576 } else
0577 if (((f > v) && (f22 > v)) || ((f < v) && (f22 < v))) {
0578 ExportLine(i,x1,left,top,y2);
0579 ExportLine(i,bot,y1,x2,right);
0580 } else {
0581 ExportLine(i,x1,left,bot,y1);
0582 ExportLine(i,top,y2,x2,right);
0583 }
0584 }
0585 }
0586 }
0587
0588 inline double ccontour::Field(int x, int y) /* evaluate funct if we must,*/
0589 {
0590 double x1, y1;
0591
0592 if (FnctData(x,y)->m_sTopLen != -1) /* is it already in the array */
0593 return(FnctData(x,y)->m_dFnVal);
0594
0595 /* not in the array, create new array element */
0596 x1 = m_pLimits[0]+m_dDx*x;
0597 y1 = m_pLimits[2]+m_dDy*y;
0598 FnctData(x,y)->m_sTopLen = 0;
0599 FnctData(x,y)->m_sBotLen = 0;
0600 FnctData(x,y)->m_sRightLen = 0;
0601 FnctData(x,y)->m_sLeftLen = 0;
0602 return (FnctData(x,y)->m_dFnVal = (*m_pFieldFcn)(x1, y1,m_pFieldFcnData));
0603 }
0604
0605 inline void ccontour::set_planes(const std::vector<double>& vPlanes)
0606 {
0607 // cleaning memory
0608 CleanMemory();
0609
0610 m_vPlanes = vPlanes;
0611 }
0612
0613 inline void ccontour::set_field_fcn(double (*_pFieldFcn)(double, double,void*),void* aData)
0614 {
0615 m_pFieldFcnData = aData;
0616 m_pFieldFcn=_pFieldFcn;
0617 }
0618
0619 inline void ccontour::set_first_grid(int iCol, int iRow)
0620 {
0621 m_iColFir=mx<int>(iCol,2);
0622 m_iRowFir=mx<int>(iRow,2);
0623 }
0624
0625 inline void ccontour::set_secondary_grid(int iCol, int iRow)
0626 {
0627 // cleaning work matrices if allocated
0628 CleanMemory();
0629
0630 m_iColSec=mx<int>(iCol,2);
0631 m_iRowSec=mx<int>(iRow,2);
0632 }
0633
0634 inline void ccontour::set_limits(double pLimits[4])
0635 {
0636 _ASSERT_(pLimits[0]<pLimits[1],"ccontour::set_limits");
0637 _ASSERT_(pLimits[2]<pLimits[3],"ccontour::set_limits");
0638 for (int i=0;i<4;i++)
0639 {
0640 m_pLimits[i]=pLimits[i];
0641 }
0642 }
0643
0644 inline void ccontour::get_limits(double pLimits[4])
0645 {
0646 for (int i=0;i<4;i++)
0647 {
0648 pLimits[i]=m_pLimits[i];
0649 }
0650 }
0651
0652 //G.Barrand : from .h to .cxx to avoid _ASSERT_ in .h
0653 inline double ccontour::get_plane(unsigned int i) const {
0654 /*_ASSERT_(i>=0);*/
0655 _ASSERT_(i<m_vPlanes.size(),"ccontour::get_plane");
0656 return m_vPlanes[i];
0657 }
0658
0659 inline double ccontour::get_yi(int i) const {
0660 if(i<0) ::printf("ccontour::get_yi : %d\n",i);
0661 _ASSERT_(i>=0,"ccontour::get_yi");
0662 return m_pLimits[2] + i/(m_iColSec+1)*(m_pLimits[3]-m_pLimits[2])/(double)( m_iRowSec );
0663 }
0664
0665 }
0666
0667 #endif