inlib  1.2.0
/Users/barrand/private/dev/softinex/old/inexlib-1.2/inlib/inlib/CListContour
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_CListContour
00005 #define inlib_CListContour
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 // Inheritance :
00011 #include "CContour"
00012 
00013 #include <list>
00014 #include <ostream>
00015 #include <iomanip> //std::setprecision
00016 
00017 namespace inlib {
00018 
00019 // a list of point index referring to the secondary grid
00020 // Let i the index of a point,
00021 typedef std::list<unsigned int> CLineStrip;
00022 typedef std::list<CLineStrip*> CLineStripList;
00023 typedef std::vector<CLineStripList> CLineStripListVector;
00024 
00025 class CListContour : public CContour  
00026 {
00027 public: //CContour
00028         // Adding segment to line strips
00029         // See CContour::ExportLine for further details
00030         virtual void ExportLine(int iPlane,int x1, int y1, int x2, int y2);
00031 
00032 public:
00033         CListContour();
00034         virtual ~CListContour(){CleanMemory();}
00035 protected: //G.Barrand
00036         inline CListContour(const CListContour& a_from):CContour(a_from){}
00037 private: //G.Barrand
00038         inline CListContour& operator=(const CListContour&){return *this;}
00039 public:
00040         // retreiving list of line strip for the i-th contour
00041         CLineStripList* GetLines(unsigned int iPlane);
00042 
00043         // Initializing memory
00044         virtual void InitMemory();
00045         // Cleaning memory and line strips
00046         virtual void CleanMemory();
00047         // Generate contour strips
00048         virtual void Generate();
00049 
00050         // Adding segment to line strips
00051         // See CContour::ExportLine for further details
00052         //void ExportLine(int iPlane,int x1, int y1, int x2, int y2);
00053 
00054         // Basic algorithm to concatanate line strip. Not optimized at all !
00055         bool CompactStrips();
00057         void DumpPlane(unsigned int iPlane) const;
00058 
00059         // Area given by this function can be positive or negative depending on the winding direction of the contour.
00060         double Area(CLineStrip* Line);
00061 
00062         double EdgeWeight(CLineStrip* pLine, double R);
00063         bool   PrintContour(std::ostream& a_out);
00064 protected:
00065         // Merges pStrip1 with pStrip2 if they have a common end point
00066         bool MergeStrips(CLineStrip* pStrip1, CLineStrip* pStrip2);
00067         // Merges the two strips with a welding threshold.
00068         bool ForceMerge(CLineStrip* pStrip1, CLineStrip* pStrip2,double);
00069         // returns true if contour is touching boundary
00070         bool OnBoundary(CLineStrip* pStrip);
00071         // L.Garnier : check specials case for CompactStrip
00072         bool SpecialCompactStripCase(double,double,double,double,double); 
00073 
00074 private:
00075         // array of line strips
00076         CLineStripListVector m_vStripLists; 
00077         typedef unsigned int UINT;
00078 
00079 private:
00080         inline static const char* _TT(const char* what) {return what;}
00081 
00082         inline static void TRACE(const char* /*a_fmt*/,...) {
00083           //va_list args;
00084           //va_start(args,a_fmt);
00085           //::vprintf(s,a_fmt,args);
00086           //va_end(args);
00087         }
00088         inline static void PROBLEM(const char* what) {::printf("%s",what);}
00089 
00090         inline static bool ASSERT_RET(bool what,const char* cmt) {
00091           if(!(what)) {
00092             ::printf("debug : ListContour : assert failure in %s\n",cmt);
00093             return false;
00094           }
00095           return true;
00096         }
00097 
00098         inline static bool ASSERT_MERGE_RET(bool what,const char* cmt,CLineStrip* pStrip2) {
00099           if(!(what)) {
00100             ::printf("debug : ListContour : assert failure in %s\n",cmt);
00101             pStrip2->clear();
00102             return false;
00103           }
00104           return true;
00105         }
00106 };
00107 
00108 
00109 // implementation :
00110 inline CListContour::CListContour()
00111 : CContour()
00112 {
00113 }
00114 
00115 inline void CListContour::Generate()
00116 {
00117         // generate line strips
00118         CContour::Generate();
00119         // compact strips
00120         CompactStrips();
00121 }
00122 
00123 inline void CListContour::InitMemory()
00124 {
00125         CContour::InitMemory();
00126         
00127         CLineStripList::iterator pos;
00128         CLineStrip* pStrip;
00129         
00130         if (!m_vStripLists.empty())
00131         {
00132                 UINT i;
00133                 // reseting lists
00134                 ASSERT(m_vStripLists.size() == GetNPlanes(),"CListContour::InitMemory::0");
00135                 for (i=0;i<GetNPlanes();i++)
00136                 {
00137                         for (pos = m_vStripLists[i].begin(); pos!=m_vStripLists[i].end() ; pos++)
00138                         {
00139                                 pStrip=(*pos);
00140                                 ASSERTP(pStrip,"CListContour::InitMemory::1");
00141 
00142                                 pStrip->clear();
00143                                 delete pStrip;
00144                         }
00145                         m_vStripLists[i].clear();
00146                 }
00147         }
00148         else
00149                 m_vStripLists.resize(GetNPlanes());
00150 }
00151 
00152 inline void CListContour::CleanMemory()
00153 {
00154         CContour::CleanMemory();
00155         
00156         CLineStripList::iterator pos;
00157         CLineStrip* pStrip;
00158         UINT i;
00159 
00160         // reseting lists
00161         for (i=0;i<m_vStripLists.size();i++) //G.Barrand
00162         {
00163                 for (pos=m_vStripLists[i].begin(); pos!=m_vStripLists[i].end();pos++)
00164                 {
00165                         pStrip=(*pos);
00166                         ASSERTP(pStrip,"CListContour::CleanMemory");
00167                         pStrip->clear();
00168                         delete pStrip;
00169                 }
00170                 m_vStripLists[i].clear();
00171         }
00172 }
00173 
00174 inline void CListContour::ExportLine(int iPlane,int x1, int y1, int x2, int y2)
00175 {
00176         ASSERT(iPlane>=0,"CListContour::ExportLine::0");
00177         ASSERT(iPlane<(int)GetNPlanes(),"CListContour::ExportLine::1");
00178         
00179         // check that the two points are not at the beginning or end of the  some line strip
00180         UINT i1=y1*(m_iColSec+1)+x1;
00181         UINT i2=y2*(m_iColSec+1)+x2;
00182         
00183         CLineStrip* pStrip;
00184         
00185         CLineStripList::iterator pos;
00186         bool added = false;
00187         for(pos=m_vStripLists[iPlane].begin(); pos!=m_vStripLists[iPlane].end() && !added; pos++)
00188         {
00189                 pStrip=(*pos);
00190                 ASSERTP(pStrip,"CListContour::ExportLine::2");
00191                 // check if points are appendable to this strip
00192                 if (i1==pStrip->front())
00193                 {
00194                         pStrip->insert(pStrip->begin(),i2);
00195                         return;
00196                 }
00197                 if (i1==pStrip->back())
00198                 {
00199                         pStrip->insert(pStrip->end(),i2);
00200                         return;
00201                 }
00202                 if (i2==pStrip->front())
00203                 {
00204                         pStrip->insert(pStrip->begin(),i1);
00205                         return;
00206                 }
00207                 if (i2==pStrip->back())
00208                 {
00209                         pStrip->insert(pStrip->end(),i1);
00210                         return;
00211                 }
00212         }
00213         
00214         // segment was not part of any line strip, creating new one
00215         pStrip=new CLineStrip;
00216         pStrip->insert(pStrip->begin(),i1);
00217         pStrip->insert(pStrip->end(),i2);
00218         m_vStripLists[iPlane].insert(m_vStripLists[iPlane].begin(),pStrip);
00219 }
00220 
00221 inline bool CListContour::ForceMerge(CLineStrip* pStrip1, CLineStrip* pStrip2,double aHeight) 
00222 {
00223 
00224         CLineStrip::iterator pos;
00225         CLineStrip::reverse_iterator rpos;
00226         
00227         if (pStrip2->empty())
00228                 return false;
00229         
00230         double x[4], y[4], weldDist;
00231         int index;
00232         index = pStrip1->front();
00233         x[0] = GetXi(index);
00234         y[0] = GetYi(index);
00235         index = pStrip1->back();
00236         x[1] = GetXi(index);
00237         y[1] = GetYi(index);
00238         index = pStrip2->front();
00239         x[2] = GetXi(index);
00240         y[2] = GetYi(index);
00241         index = pStrip2->back();
00242         x[3] = GetXi(index);
00243         y[3] = GetYi(index);
00244         
00245         weldDist = 10*(m_dDx*m_dDx+m_dDy*m_dDy);
00246         
00247         if (((x[1]-x[2])*(x[1]-x[2])+(y[1]-y[2])*(y[1]-y[2])< weldDist)
00248             || SpecialCompactStripCase(x[1],x[2],y[1],y[2],aHeight)) // L.Garnier
00249           
00250     {
00251                 for (pos=pStrip2->begin(); pos!=pStrip2->end();pos++)
00252                 {
00253                         index=(*pos);
00254                         if(!ASSERT_RET(index>=0,"CListContour::ForceMerge::0")) return false;
00255                         pStrip1->insert(pStrip1->end(),index);
00256                 }
00257                 pStrip2->clear();
00258                 return true;
00259     }
00260         
00261         if (((x[3]-x[0])*(x[3]-x[0])+(y[3]-y[0])*(y[3]-y[0])< weldDist)
00262             || SpecialCompactStripCase(x[3],x[0],y[3],y[0],aHeight)) // L.Garnier
00263     {
00264                 for (rpos=pStrip2->rbegin(); rpos!=pStrip2->rend();rpos++)
00265                 {
00266                         index=(*rpos);
00267                         if(!ASSERT_RET(index>=0,"CListContour::ForceMerge::1")) return false;
00268                         pStrip1->insert(pStrip1->begin(),index);
00269                 }
00270                 pStrip2->clear();
00271                 return true;
00272     }
00273         
00274         if (((x[1]-x[3])*(x[1]-x[3])+(y[1]-y[3])*(y[1]-y[3])< weldDist)
00275             || SpecialCompactStripCase(x[1],x[3],y[1],y[3],aHeight)) // L.Garnier
00276     {
00277                 for (rpos=pStrip2->rbegin(); rpos!=pStrip2->rend();rpos++)
00278                 {
00279                         index=(*rpos);
00280                         if(!ASSERT_RET(index>=0,"CListContour::ForceMerge::2")) return false;
00281                         pStrip1->insert(pStrip1->end(),index);
00282                 }
00283                 pStrip2->clear();
00284                 return true;
00285     }
00286 
00287         if (((x[0]-x[2])*(x[0]-x[2])+(y[0]-y[2])*(y[0]-y[2])< weldDist)
00288             || SpecialCompactStripCase(x[0],x[2],y[0],y[2],aHeight)) // L.Garnier
00289     {
00290                 for (pos=pStrip2->begin(); pos!=pStrip2->end();pos++)
00291                 {
00292                         index=(*pos);
00293                         if(!ASSERT_RET(index>=0,"CListContour::ForceMerge::3")) return false;
00294                         pStrip1->insert(pStrip1->begin(),index);
00295                 }
00296                 pStrip2->clear();
00297                 return true;
00298     }
00299 
00300         return false;
00301 }
00302 
00303 inline bool CListContour::MergeStrips(CLineStrip* pStrip1, CLineStrip* pStrip2)
00304 {
00305         CLineStrip::iterator pos;
00306         CLineStrip::reverse_iterator rpos;
00307         if (pStrip2->empty())
00308                 return false;
00309         
00310         int index;
00311 
00312         // debugging stuff
00313         if (pStrip2->front()==pStrip1->front())
00314     {
00315                 // retreiving first element
00316                 pStrip2->pop_front();
00317                 // adding the rest to strip1
00318                 for (pos=pStrip2->begin(); pos!=pStrip2->end();pos++)
00319                 {
00320                         index=(*pos);
00321                         if(!ASSERT_MERGE_RET(index>=0,"CListContour::MergeStrips::0",pStrip2)) return false;
00322                         pStrip1->insert(pStrip1->begin(),index);
00323                 }
00324                 pStrip2->clear();
00325                 return true;
00326     }
00327         
00328         if (pStrip2->front()==pStrip1->back())
00329     {
00330                 pStrip2->pop_front();
00331                 // adding the rest to strip1
00332                 for (pos=pStrip2->begin(); pos!=pStrip2->end();pos++)
00333                 {
00334                         index=(*pos);
00335                         if(!ASSERT_MERGE_RET(index>=0,"CListContour::MergeStrips::1",pStrip2)) return false;
00336                         pStrip1->insert(pStrip1->end(),index);
00337                 }
00338                 pStrip2->clear();
00339                 return true;
00340     }
00341         
00342         if (pStrip2->back()==pStrip1->front())
00343     {
00344                 pStrip2->pop_back();
00345                 // adding the rest to strip1
00346                 for (rpos=pStrip2->rbegin(); rpos!=pStrip2->rend();rpos++)
00347                 {
00348                         index=(*rpos);
00349                         if(!ASSERT_MERGE_RET(index>=0,"CListContour::MergeStrips::2",pStrip2)) return false;
00350                         pStrip1->insert(pStrip1->begin(),index);
00351                 }
00352                 pStrip2->clear();
00353                 return true;
00354     }
00355         
00356         if (pStrip2->back()==pStrip1->back())
00357     {
00358                 pStrip2->pop_back();
00359                 // adding the rest to strip1
00360                 for (rpos=pStrip2->rbegin(); rpos!=pStrip2->rend();rpos++)
00361                 {
00362                         index=(*rpos);
00363                         if(!ASSERT_MERGE_RET(index>=0,"CListContour::MergeStrips::3",pStrip2)) return false;
00364                         pStrip1->insert(pStrip1->end(),index);
00365                 }
00366                 pStrip2->clear();
00367                 return true;
00368     }
00369         
00370         return false;
00371 }
00372 
00373 inline bool CListContour::CompactStrips()
00374 {
00375         CLineStrip* pStrip;
00376         CLineStrip* pStripBase;
00377         UINT i;
00378         CLineStripList::iterator pos,pos2;
00379         CLineStripList newList;
00380         bool again, changed;    
00381         
00382         const double weldDist = 10*(m_dDx*m_dDx+m_dDy*m_dDy);
00383 
00384         if(!ASSERT_RET(m_vStripLists.size() == GetNPlanes(),"CListContour::CompactStrips::0")) return false;
00385         for (i=0;i<GetNPlanes();i++)
00386         {
00387                 double planeHeight = GetPlane(i);
00388                 again=true;
00389                 while(again)
00390                 {
00391                         // REPEAT COMPACT PROCESS UNTILL LAST PROCESS MAKES NO CHANGE
00392                         
00393                         again=false;
00394                         // building compacted list
00395                         if(!ASSERT_RET(newList.empty(),"CListContour::CompactStrips::1")) return false;
00396                         for (pos=m_vStripLists[i].begin(); pos!=m_vStripLists[i].end();pos++)
00397                         {
00398                                 pStrip=(*pos);
00399                                 for (pos2=newList.begin(); pos2!=newList.end();pos2++)
00400                                 {
00401                                         pStripBase=(*pos2);
00402                                         changed=MergeStrips(pStripBase,pStrip);
00403                                         if (changed)
00404                                                 again=true;
00405                                         if (pStrip->empty())
00406                                                 break;
00407                                 }
00408                                 if (pStrip->empty())
00409                                         delete pStrip;
00410                                 else
00411                                         newList.insert(newList.begin(),pStrip);
00412                         }
00413                         
00414 
00415                         // deleting old list
00416                         m_vStripLists[i].clear();
00417                         CLineStrip* pStrip2;
00418                         // Copying all
00419                         for (pos2=newList.begin(); pos2 != newList.end(); pos2++)
00420                         {
00421                                 pStrip2=(*pos2);
00422                                 CLineStrip::iterator pos1 = pStrip2->begin(),pos3;
00423                                 while (pos1!=pStrip2->end()) 
00424                                 {
00425                                         pos3 = pos1;
00426                                         pos3++;
00427                                         if ( (*pos1) == (*pos3))
00428                                         {
00429                                                 if ( (*pos3) != (*pStrip2->end()))
00430                                                         pStrip2->erase(pos3);
00431                                                 else
00432                                                 {
00433                                                         pStrip2->erase(pos3);
00434                                                         break;
00435                                                 }
00436                                         }
00437                                         else
00438                                                 pos1++;
00439                                 }
00440                                 
00441                                 //if (!(pStrip2->front()==pStrip2->back() && pStrip2->size()==2))
00442                                 if (pStrip2->size()!=1)         
00443                                         m_vStripLists[i].insert(m_vStripLists[i].begin(),pStrip2 );
00444                                 else 
00445                                         delete pStrip2;
00446                         }
00447                         // emptying temp list
00448                         newList.clear();
00449                         
00450                 } // OF WHILE(AGAIN) (LAST COMPACT PROCESS MADE NO CHANGES)
00451 
00452         
00453                 if (m_vStripLists[i].empty())
00454                         continue;
00456                 // compact more
00457                 int Nstrip,j,index,count;
00458 
00459                 Nstrip = m_vStripLists[i].size(); 
00460                 std::vector<bool> closed(Nstrip);
00461                 double x,y;
00462 
00463                 // First let's find the open and closed lists in m_vStripLists
00464                 for(pos2 = m_vStripLists[i].begin(), j=0, count=0; pos2 != m_vStripLists[i].end(); pos2++, j++) 
00465                 {
00466                         pStrip = (*pos2);
00467 
00468                         // is it open ?
00469                         if (pStrip->front() != pStrip->back()) 
00470                         {
00471                                 index = pStrip->front();
00472                                 x = GetXi(index); y = GetYi(index);
00473                                 index = pStrip->back();
00474                                 x -= GetXi(index); y -= GetYi(index);
00475                                 
00476                                 // is it "almost closed" ?
00477                                 if ((x*x+y*y < weldDist) ||
00478                                     SpecialCompactStripCase(GetXi(pStrip->front()), // L.Garnier
00479                                                             GetXi(pStrip->back()),
00480                                                             GetYi(pStrip->front()),
00481                                                             GetYi(pStrip->back()),
00482                                                             planeHeight))
00483                                 {
00484                                         closed[j] = true; 
00485                                         // close it !!! Added by L.Garnier
00486                                         pStrip->push_back(pStrip->front());
00487                                         //
00488                                 }
00489                                 else 
00490                                 { 
00491                                         closed[j] = false; 
00492                                         // updating not closed counter...
00493                                         count ++; 
00494                                 }
00495                         } 
00496                         else 
00497                                 closed[j] = true;
00498                 }
00499                 
00500                 // is there any open strip ?
00501                 if (count > 1) 
00502                 { 
00503                         // Merge the open strips into NewList
00504                         pos = m_vStripLists[i].begin();
00505                         for(j=0;j<Nstrip;j++) 
00506                         {
00507                                 if (closed[j] == false ) 
00508                                 {
00509                                         pStrip = (*pos);
00510                                         newList.insert(newList.begin(),pStrip); 
00511                                         pos = m_vStripLists[i].erase(pos);
00512                                 }
00513                                 else 
00514                                         pos ++;
00515                         }
00516                         
00517                         // are they open strips to process ?
00518                         while(newList.size()>1) 
00519                         {
00520                                 pStripBase = newList.front();
00521                                 
00522                                 // merge the rest to pStripBase
00523                                 again = true;
00524                                 while (again) 
00525                                 {
00526                                         again = false;
00527                                         pos = newList.begin(); 
00528                                         for(pos++; pos!=newList.end();) 
00529                                         {
00530                                                 pStrip = (*pos);
00531                                                 changed = ForceMerge(pStripBase,pStrip,planeHeight);
00532                                                 if (changed) 
00533                                                 { 
00534                                                         again = true;
00535                                                         delete pStrip;
00536                                                         pos = newList.erase(pos);
00537                                                 } 
00538                                                 else 
00539                                                         pos ++;
00540                                         }                     
00541                                 } // while(again)
00542 
00543                                 index = pStripBase->front();
00544                                 x = GetXi(index); y = GetYi(index);
00545                                 index = pStripBase->back();
00546                                 x -= GetXi(index); y -= GetYi(index);
00547                                 // if pStripBase is closed or not
00548 
00549                                 if ((x*x+y*y < weldDist) ||
00550                                     SpecialCompactStripCase(GetXi(pStripBase->front()), // L.Garnier
00551                                                             GetXi(pStripBase->back()),
00552                                                             GetYi(pStripBase->front()),
00553                                                             GetYi(pStripBase->back()),
00554                                                             planeHeight))
00555                                 {
00556 
00557                                   // close it !!! Added by L.Garnier
00558                                   if ((x!=0) || (y!=0)) {
00559                                     pStripBase->push_back(pStripBase->front());
00560                                   }
00561                                   //
00562                                   m_vStripLists[i].insert(m_vStripLists[i].begin(),pStripBase);
00563                                   newList.pop_front();
00564                                 }
00565                                 else 
00566                                 {                       
00567                                         if (OnBoundary(pStripBase)) 
00568                                         {
00569                                                 TRACE(_TT("# open strip ends on boundary, continue.\n"));
00570                                                 m_vStripLists[i].insert(m_vStripLists[i].begin(),pStripBase);
00571                                                 newList.pop_front();
00572                                         }
00573                                         else 
00574                                         {
00575                                                 PROBLEM(_TT("unpaird open strip at 1!\n"));
00576                                                 //exit(0);
00577                                                 return false;
00578                                         }
00579                                 }
00580                         } // while(newList.size()>1);
00581 
00582 
00583                         if (newList.size() ==1) 
00584                         {
00585                                 pStripBase = newList.front();
00586                                 index = pStripBase->front(); // L.Garnier
00587                                 x = GetXi(index); y = GetYi(index); // L.Garnier
00588                                 index = pStripBase->back(); // L.Garnier
00589                                 x -= GetXi(index); y -= GetYi(index); // L.Garnier
00590                                 
00591                                 // is it "almost closed", give last chance...5*weldDist
00592                                 if (x*x+y*y < 3*weldDist) // L.Garnier
00593                                 {
00594                                         m_vStripLists[i].insert(m_vStripLists[i].begin(),pStripBase);
00595                                         newList.pop_front();
00596                                 }
00597                                 else if (OnBoundary(pStripBase)) 
00598                                 {
00599                                         TRACE(_TT("# open strip ends on boundary, continue.\n"));
00600                                         m_vStripLists[i].insert(m_vStripLists[i].begin(),pStripBase);
00601                                         newList.pop_front();
00602                                 }
00603                                 else 
00604                                 {
00605                                         PROBLEM(_TT("unpaird open strip at 2!\n"));
00606                                         DumpPlane(i);
00607                                         //exit(0);
00608                                         return false;
00609                                 }
00610                         }
00611                         
00612                         newList.clear();
00613                         
00614                 } 
00615                 else if (count == 1) 
00616                 {
00617                         pos = m_vStripLists[i].begin();
00618                         for(j=0;j<Nstrip;j++) 
00619                         {
00620                                 if (closed[j] == false ) 
00621                                 {
00622                                         pStripBase = (*pos);
00623                                         break;
00624                                 }
00625                                 pos ++;
00626                         }
00627                         index = pStripBase->front(); // L.Garnier
00628                         x = GetXi(index); y = GetYi(index); // L.Garnier
00629                         index = pStripBase->back(); // L.Garnier
00630                         x -= GetXi(index); y -= GetYi(index); // L.Garnier
00631                         
00632                         // is it "almost closed", give last chance...5*weldDist
00633                         if (x*x+y*y < 2*weldDist) // L.Garnier
00634                         {
00635                           //close it!!
00636                           pStripBase->push_back(pStripBase->front()); // L.Garnier
00637                         }
00638                         else if (OnBoundary(pStripBase)) 
00639                         {
00640                                 TRACE(_TT("# open strip ends on boundary, continue.\n"));
00641                                 pStripBase->push_back(pStripBase->front()); // L.Garnier
00642                         } 
00643                         else 
00644                         {
00645                                 TRACE(_TT("unpaird open strip at 3!"));
00646                                 DumpPlane(i);
00647                                 return false;  // L.Garnier
00648                                 //exit(0);
00649                         }
00650                         newList.clear();  // L.Garnier
00651                 }
00652         }
00653         return true;
00654 }
00655 
00656 
00657 inline bool CListContour::OnBoundary(CLineStrip* pStrip) 
00658 {
00659         bool e1,e2;
00660 
00661         int index = pStrip->front();
00662         double x = GetXi(index), y = GetYi(index);
00663         if (x==m_pLimits[0] || x == m_pLimits[1] || 
00664                 y == m_pLimits[2] || y == m_pLimits[3])
00665                 e1 = true;
00666         else 
00667                 e1 = false;
00668         
00669         index = pStrip->back();
00670         x = GetXi(index); y = GetYi(index);
00671         if (x==m_pLimits[0] || x == m_pLimits[1] || 
00672                 y == m_pLimits[2] || y == m_pLimits[3])
00673                 e2 = true;
00674         else 
00675                 e2 = false;
00676         
00677         return (e1 && e2);
00678 }
00679 
00680 inline void CListContour::DumpPlane(UINT iPlane) const
00681 {
00682         CLineStripList::const_iterator pos;
00683         UINT i;
00684         CLineStrip* pStrip;
00685         
00686         /*ASSERT(iPlane>=0,"CListContour::DumpPlane");*/
00687         ASSERT(iPlane<GetNPlanes(),"CListContour::DumpPlane::0");
00688         TRACE(_TT("Level : %d"),GetPlane(iPlane));
00689         
00690         TRACE(_TT("Number of strips : %d\r\n"),m_vStripLists[iPlane].size());
00691         TRACE(_TT("i np start end xstart ystart xend yend\r\n"));
00692         for (pos = m_vStripLists[iPlane].begin(), i=0; pos != m_vStripLists[iPlane].end(); pos++, i++)
00693         {
00694                 pStrip=*pos;
00695                 ASSERTP(pStrip,"CListContour::DumpPlane::1");
00696                 TRACE(_TT("%d %d %d %d %g %g %g %g\r\n"),i,pStrip->size(),pStrip->front(),pStrip->back(),
00697                         GetXi(pStrip->front()),GetYi(pStrip->front()),
00698                         GetXi(pStrip->back()),GetYi(pStrip->back()) );
00699         }
00700 }
00701 
00702 inline double CListContour::Area(CLineStrip* Line) 
00703 {
00704         // if Line is not closed, return 0;
00705         
00706         double Ar = 0, x, y, x0,y0,x1, y1;
00707         int index;
00708         
00709         CLineStrip::iterator pos;
00710         pos = Line->begin();
00711         index = (*pos);
00712         x0 = x =  GetXi(index);
00713         y0 = y =  GetYi(index);
00714         
00715         pos ++;
00716         
00717         for(;pos!=Line->end();pos++) 
00718         {
00719                 index = (*pos);  
00720                 x1 = GetXi(index);
00721                 y1 = GetYi(index);
00722                 // Ar += (x1-x)*(y1+y);
00723                 Ar += (y1-y)*(x1+x)-(x1-x)*(y1+y);
00724                 x = x1;
00725                 y = y1;  
00726                 
00727         }
00728         
00729         
00730         //Ar += (x0-x)*(y0+y);
00731         Ar += (y0-y)*(x0+x)-(x0-x)*(y0+y);
00732         // if not closed curve, return 0;
00733         if ((x0-x)*(x0-x) + (y0-y)*(y0-y)>20*(m_dDx*m_dDx+m_dDy*m_dDy)) 
00734         {
00735                 Ar = 0;
00736                 TRACE(_TT("# open curve!\n"));
00737         }
00738         //else   Ar /= -2;
00739         else Ar/=4;
00740         // result is \int ydex/2 alone the implicit direction.
00741         return Ar;
00742 }
00743 
00744 inline double CListContour:: EdgeWeight(CLineStrip* pLine, double R) 
00745 {
00746         CLineStrip::iterator pos;
00747         int count = 0,index;
00748         double x,y;
00749         for(pos = pLine->begin(); pos!=pLine->end(); pos++) 
00750         {
00751                 index = (*pos);
00752                 x = GetXi(index); 
00753                 y = GetYi(index);
00754                 if (fabs(x) > R || fabs(y) > R) 
00755                         count ++;
00756         }
00757         return (double)count/pLine->size();
00758 }
00759 
00760 inline bool CListContour::PrintContour(std::ostream& a_out) 
00761 {
00762         std::streamsize old_prec = a_out.precision(3);
00763         a_out << std::setprecision(10);
00764         
00765         UINT i, index;
00766         CLineStrip* pStrip;
00767         CLineStrip::iterator pos2;
00768         CLineStripList::iterator pos;
00769         
00770         for(i=0;i<GetNPlanes();i++) {
00771                 for(pos = m_vStripLists[i].begin();pos!=m_vStripLists[i].end();pos++) 
00772                 {
00773                         pStrip = (*pos);
00774                         for(pos2 = pStrip->begin();pos2!=pStrip->end();pos2++) 
00775                         {
00776                           index = (*pos2);
00777                           a_out << GetXi(index)<<"\t"<<GetYi(index)<<"\n";
00778                         }
00779                         a_out<<"\n";
00780                 }
00781         }
00782         a_out.precision(old_prec);
00783         return true;
00784         
00785 }
00786 
00787 //G.Barrand : from .h to .cxx to avoid ASSERT in .h
00788 inline CLineStripList* CListContour::GetLines(unsigned int iPlane)      {
00789   /*ASSERT(iPlane>=0);*/
00790   ASSERT(iPlane<GetNPlanes(),"CListContour::GetLines");
00791   return &m_vStripLists[iPlane];
00792 }
00793 
00794 // Added by L.Garnier
00795 inline bool CListContour::SpecialCompactStripCase(double aXfront,double aXback,double aYfront,double aYback,double actualHeight) 
00796 {
00797   // To solve the case of a list of strips 
00798   // which appeared to be open but should correspond to a closed
00799   // contour.
00800   //  With the today Generate() algorithm, it appears that we fall
00801   // on this case when the begin and end points
00802   // are on a horizontal or vertical line.
00803   // (case where front()->x == back()->x or front()->y == back()->y).
00804   //  We try to detect in this method this situation and decide to close
00805   // or not the line. To do that we check the heigth of intermediate 
00806   // points to see if there are on the same contour; if so we close
00807   // the line (and return true), if not we do nothing (and return false).
00808 
00809   // check if we could realy close it
00810   float marge = 1; // *m_dDy or *m_dDx. 1 seems to be good and normal, but why
00811                    // not 2 in certain cases???
00812 
00813   double distToNext =0;
00814   // try to get the correct hight
00815   if (GetPlane(0)>= actualHeight) {
00816     return false;
00817   }
00818   if (GetNPlanes() >1){
00819     distToNext = GetPlane(1)-GetPlane(0);
00820   } else {
00821     return false;
00822   }
00823 
00824   if ((aYback-aYfront) == 0) {
00825     double temp;
00826     double av;
00827     double eg;
00828     double ap;
00829 
00830     if (aXfront==m_pLimits[0] && aXback == m_pLimits[1]) return false;
00831     if (aXfront==m_pLimits[1] && aXback == m_pLimits[0]) return false;
00832 
00833     if (aXfront > aXback ) {
00834       temp = aXfront;
00835       aXfront = aXback;
00836       aXback = temp;
00837     }
00838     for(double check=aXfront+m_dDx;
00839         check<aXback;
00840         check+=m_dDx) {
00841       av = ((*m_pFieldFcn)(check,aYback-marge*m_dDy,m_pFieldFcnData)-actualHeight);
00842       eg = ((*m_pFieldFcn)(check,aYback,m_pFieldFcnData)-actualHeight);
00843       ap = ((*m_pFieldFcn)(check,aYback+marge*m_dDy,m_pFieldFcnData)-actualHeight);
00844 
00845       if ((av>distToNext) && (ap>distToNext) && (eg>distToNext)) {
00846         return false;
00847       } else if ((av<0) && (ap<0) && (eg<0)) {
00848         return false;
00849       }
00850     }
00851     return true;
00852   } else if ((aXback-aXfront) == 0) {
00853     double temp;
00854     double av;
00855     double eg;
00856     double ap;
00857     if (aYfront==m_pLimits[3] && aYback == m_pLimits[2]) return false;
00858     if (aYfront==m_pLimits[2] && aYback == m_pLimits[3]) return false;
00859 
00860     if (aYfront > aYback ) {
00861       temp = aYfront;
00862       aYfront = aYback;
00863       aYback = temp;
00864     }
00865 
00866     for(double check=aYfront+m_dDy;
00867         check<aYback;
00868         check+=m_dDy) {
00869       av = ((*m_pFieldFcn)(aXback-marge*m_dDx,check,m_pFieldFcnData)-actualHeight);
00870       eg = ((*m_pFieldFcn)(aXback,check,m_pFieldFcnData)-actualHeight);
00871       ap = ((*m_pFieldFcn)(aXback+marge*m_dDx,check,m_pFieldFcnData)-actualHeight);
00872       if ((av>distToNext) && (ap>distToNext) && (eg>distToNext)) {
00873         return false;
00874       } else if ((av<0) && (ap<0) && (eg<0)) {
00875         return false;
00876       }
00877     }
00878     return true;
00879   }
00880   return false;
00881 }
00882 
00883 }
00884 
00885 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines