Warning, /include/Geant4/tools/clist_contour 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_clist_contour
0005 #define tools_clist_contour
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 // Inheritance :
0011 #include "ccontour"
0012
0013 #include <list>
0014 #include <ostream>
0015 #include <iomanip> //std::setprecision
0016
0017 namespace tools {
0018
0019 // a list of point index referring to the secondary grid
0020 // Let i the index of a point,
0021 typedef std::list<unsigned int> cline_strip;
0022 typedef std::list<cline_strip*> cline_strip_list;
0023 typedef std::vector<cline_strip_list> cline_strip_list_vector;
0024
0025 class clist_contour : public ccontour
0026 {
0027 public: //ccontour
0028 // Adding segment to line strips
0029 // See ccontour::ExportLine for further details
0030 virtual void ExportLine(int iPlane,int x1, int y1, int x2, int y2);
0031
0032 public:
0033 clist_contour();
0034 virtual ~clist_contour(){CleanMemory();}
0035 protected: //G.Barrand
0036 clist_contour(const clist_contour& a_from):ccontour(a_from){}
0037 private: //G.Barrand
0038 clist_contour& operator=(const clist_contour&){return *this;}
0039 public:
0040 // retreiving list of line strip for the i-th contour
0041 cline_strip_list* get_lines(unsigned int iPlane);
0042 // Basic algorithm to concatanate line strip. Not optimized at all !
0043 bool compact_strips ();
0044 // generate contour strips
0045 virtual void generate();
0046 protected: //G.Barrand
0047
0048 // Initializing memory
0049 virtual void InitMemory();
0050 // Cleaning memory and line strips
0051 virtual void CleanMemory();
0052
0053 // Adding segment to line strips
0054 // See ccontour::ExportLine for further details
0055 //void ExportLine(int iPlane,int x1, int y1, int x2, int y2);
0056
0057 /// debuggin
0058 void DumpPlane(unsigned int iPlane) const;
0059
0060 // Area given by this function can be positive or negative depending on the winding direction of the contour.
0061 double Area(cline_strip* Line);
0062
0063 double EdgeWeight(cline_strip* pLine, double R);
0064 //bool PrintContour(std::ostream& a_out);
0065 protected:
0066 // Merges pStrip1 with pStrip2 if they have a common end point
0067 bool MergeStrips(cline_strip* pStrip1, cline_strip* pStrip2);
0068 // Merges the two strips with a welding threshold.
0069 bool ForceMerge(cline_strip* pStrip1, cline_strip* pStrip2,double);
0070 // returns true if contour is touching boundary
0071 bool OnBoundary(cline_strip* pStrip);
0072 // L.Garnier : check specials case for CompactStrip
0073 bool SpecialCompactStripCase(double,double,double,double,double);
0074
0075 private:
0076 // array of line strips
0077 cline_strip_list_vector m_vStripLists;
0078 typedef unsigned int UINT;
0079
0080 private:
0081 static const char* _TT(const char* what) {return what;}
0082
0083 static void _TRACE_(const char* /*a_fmt*/,...) {
0084 //va_list args;
0085 //va_start(args,a_fmt);
0086 //::vprintf(s,a_fmt,args);
0087 //va_end(args);
0088 }
0089 static void _PROBLEM_(const char* what) {::printf("%s",what);}
0090
0091 static bool _ASSERT_RET_(bool what,const char* cmt) {
0092 if(!(what)) {
0093 ::printf("debug : ListContour : assert failure in %s\n",cmt);
0094 return false;
0095 }
0096 return true;
0097 }
0098
0099 static bool _ASSERT_MERGE_RET_(bool what,const char* cmt,cline_strip* pStrip2) {
0100 if(!(what)) {
0101 ::printf("debug : ListContour : assert failure in %s\n",cmt);
0102 pStrip2->clear();
0103 return false;
0104 }
0105 return true;
0106 }
0107 };
0108
0109
0110 // implementation :
0111 inline clist_contour::clist_contour()
0112 : ccontour()
0113 {
0114 }
0115
0116 inline void clist_contour::generate()
0117 {
0118 // generate line strips
0119 ccontour::generate();
0120 // compact strips
0121 compact_strips ();
0122 }
0123
0124 inline void clist_contour::InitMemory()
0125 {
0126 ccontour::InitMemory();
0127
0128 cline_strip_list::iterator pos;
0129 cline_strip* pStrip;
0130
0131 if (!m_vStripLists.empty())
0132 {
0133 UINT i;
0134 // reseting lists
0135 _ASSERT_(m_vStripLists.size() == get_number_of_planes(),"clist_contour::InitMemory::0");
0136 for (i=0;i<get_number_of_planes();i++)
0137 {
0138 for (pos = m_vStripLists[i].begin(); pos!=m_vStripLists[i].end() ; pos++)
0139 {
0140 pStrip=(*pos);
0141 _ASSERTP_(pStrip,"clist_contour::InitMemory::1");
0142
0143 pStrip->clear();
0144 delete pStrip;
0145 }
0146 m_vStripLists[i].clear();
0147 }
0148 }
0149 else
0150 m_vStripLists.resize(get_number_of_planes());
0151 }
0152
0153 inline void clist_contour::CleanMemory()
0154 {
0155 ccontour::CleanMemory();
0156
0157 cline_strip_list::iterator pos;
0158 cline_strip* pStrip;
0159 UINT i;
0160
0161 // reseting lists
0162 for (i=0;i<m_vStripLists.size();i++) //G.Barrand
0163 {
0164 for (pos=m_vStripLists[i].begin(); pos!=m_vStripLists[i].end();pos++)
0165 {
0166 pStrip=(*pos);
0167 _ASSERTP_(pStrip,"clist_contour::CleanMemory");
0168 pStrip->clear();
0169 delete pStrip;
0170 }
0171 m_vStripLists[i].clear();
0172 }
0173 }
0174
0175 inline void clist_contour::ExportLine(int iPlane,int x1, int y1, int x2, int y2)
0176 {
0177 _ASSERT_(iPlane>=0,"clist_contour::ExportLine::0");
0178 _ASSERT_(iPlane<(int)get_number_of_planes(),"clist_contour::ExportLine::1");
0179
0180 // check that the two points are not at the beginning or end of the some line strip
0181 UINT i1=y1*(m_iColSec+1)+x1;
0182 UINT i2=y2*(m_iColSec+1)+x2;
0183
0184 cline_strip* pStrip;
0185
0186 cline_strip_list::iterator pos;
0187 bool added = false;
0188 for(pos=m_vStripLists[iPlane].begin(); pos!=m_vStripLists[iPlane].end() && !added; pos++)
0189 {
0190 pStrip=(*pos);
0191 _ASSERTP_(pStrip,"clist_contour::ExportLine::2");
0192 // check if points are appendable to this strip
0193 if (i1==pStrip->front())
0194 {
0195 pStrip->insert(pStrip->begin(),i2);
0196 return;
0197 }
0198 if (i1==pStrip->back())
0199 {
0200 pStrip->insert(pStrip->end(),i2);
0201 return;
0202 }
0203 if (i2==pStrip->front())
0204 {
0205 pStrip->insert(pStrip->begin(),i1);
0206 return;
0207 }
0208 if (i2==pStrip->back())
0209 {
0210 pStrip->insert(pStrip->end(),i1);
0211 return;
0212 }
0213 }
0214
0215 // segment was not part of any line strip, creating new one
0216 pStrip=new cline_strip;
0217 pStrip->insert(pStrip->begin(),i1);
0218 pStrip->insert(pStrip->end(),i2);
0219 m_vStripLists[iPlane].insert(m_vStripLists[iPlane].begin(),pStrip);
0220 }
0221
0222 inline bool clist_contour::ForceMerge(cline_strip* pStrip1, cline_strip* pStrip2,double aHeight)
0223 {
0224
0225 cline_strip::iterator pos;
0226 cline_strip::reverse_iterator rpos;
0227
0228 if (pStrip2->empty())
0229 return false;
0230
0231 double x[4], y[4], weldDist;
0232 int index;
0233 index = pStrip1->front();
0234 x[0] = get_xi(index);
0235 y[0] = get_yi(index);
0236 index = pStrip1->back();
0237 x[1] = get_xi(index);
0238 y[1] = get_yi(index);
0239 index = pStrip2->front();
0240 x[2] = get_xi(index);
0241 y[2] = get_yi(index);
0242 index = pStrip2->back();
0243 x[3] = get_xi(index);
0244 y[3] = get_yi(index);
0245
0246 weldDist = 10*(m_dDx*m_dDx+m_dDy*m_dDy);
0247
0248 if (((x[1]-x[2])*(x[1]-x[2])+(y[1]-y[2])*(y[1]-y[2])< weldDist)
0249 || SpecialCompactStripCase(x[1],x[2],y[1],y[2],aHeight)) // L.Garnier
0250
0251 {
0252 for (pos=pStrip2->begin(); pos!=pStrip2->end();pos++)
0253 {
0254 index=(*pos);
0255 if(!_ASSERT_RET_(index>=0,"clist_contour::ForceMerge::0")) return false;
0256 pStrip1->insert(pStrip1->end(),index);
0257 }
0258 pStrip2->clear();
0259 return true;
0260 }
0261
0262 if (((x[3]-x[0])*(x[3]-x[0])+(y[3]-y[0])*(y[3]-y[0])< weldDist)
0263 || SpecialCompactStripCase(x[3],x[0],y[3],y[0],aHeight)) // L.Garnier
0264 {
0265 for (rpos=pStrip2->rbegin(); rpos!=pStrip2->rend();rpos++)
0266 {
0267 index=(*rpos);
0268 if(!_ASSERT_RET_(index>=0,"clist_contour::ForceMerge::1")) return false;
0269 pStrip1->insert(pStrip1->begin(),index);
0270 }
0271 pStrip2->clear();
0272 return true;
0273 }
0274
0275 if (((x[1]-x[3])*(x[1]-x[3])+(y[1]-y[3])*(y[1]-y[3])< weldDist)
0276 || SpecialCompactStripCase(x[1],x[3],y[1],y[3],aHeight)) // L.Garnier
0277 {
0278 for (rpos=pStrip2->rbegin(); rpos!=pStrip2->rend();rpos++)
0279 {
0280 index=(*rpos);
0281 if(!_ASSERT_RET_(index>=0,"clist_contour::ForceMerge::2")) return false;
0282 pStrip1->insert(pStrip1->end(),index);
0283 }
0284 pStrip2->clear();
0285 return true;
0286 }
0287
0288 if (((x[0]-x[2])*(x[0]-x[2])+(y[0]-y[2])*(y[0]-y[2])< weldDist)
0289 || SpecialCompactStripCase(x[0],x[2],y[0],y[2],aHeight)) // L.Garnier
0290 {
0291 for (pos=pStrip2->begin(); pos!=pStrip2->end();pos++)
0292 {
0293 index=(*pos);
0294 if(!_ASSERT_RET_(index>=0,"clist_contour::ForceMerge::3")) return false;
0295 pStrip1->insert(pStrip1->begin(),index);
0296 }
0297 pStrip2->clear();
0298 return true;
0299 }
0300
0301 return false;
0302 }
0303
0304 inline bool clist_contour::MergeStrips(cline_strip* pStrip1, cline_strip* pStrip2)
0305 {
0306 cline_strip::iterator pos;
0307 cline_strip::reverse_iterator rpos;
0308 if (pStrip2->empty())
0309 return false;
0310
0311 int index;
0312
0313 // debugging stuff
0314 if (pStrip2->front()==pStrip1->front())
0315 {
0316 // retreiving first element
0317 pStrip2->pop_front();
0318 // adding the rest to strip1
0319 for (pos=pStrip2->begin(); pos!=pStrip2->end();pos++)
0320 {
0321 index=(*pos);
0322 if(!_ASSERT_MERGE_RET_(index>=0,"clist_contour::MergeStrips::0",pStrip2)) return false;
0323 pStrip1->insert(pStrip1->begin(),index);
0324 }
0325 pStrip2->clear();
0326 return true;
0327 }
0328
0329 if (pStrip2->front()==pStrip1->back())
0330 {
0331 pStrip2->pop_front();
0332 // adding the rest to strip1
0333 for (pos=pStrip2->begin(); pos!=pStrip2->end();pos++)
0334 {
0335 index=(*pos);
0336 if(!_ASSERT_MERGE_RET_(index>=0,"clist_contour::MergeStrips::1",pStrip2)) return false;
0337 pStrip1->insert(pStrip1->end(),index);
0338 }
0339 pStrip2->clear();
0340 return true;
0341 }
0342
0343 if (pStrip2->back()==pStrip1->front())
0344 {
0345 pStrip2->pop_back();
0346 // adding the rest to strip1
0347 for (rpos=pStrip2->rbegin(); rpos!=pStrip2->rend();rpos++)
0348 {
0349 index=(*rpos);
0350 if(!_ASSERT_MERGE_RET_(index>=0,"clist_contour::MergeStrips::2",pStrip2)) return false;
0351 pStrip1->insert(pStrip1->begin(),index);
0352 }
0353 pStrip2->clear();
0354 return true;
0355 }
0356
0357 if (pStrip2->back()==pStrip1->back())
0358 {
0359 pStrip2->pop_back();
0360 // adding the rest to strip1
0361 for (rpos=pStrip2->rbegin(); rpos!=pStrip2->rend();rpos++)
0362 {
0363 index=(*rpos);
0364 if(!_ASSERT_MERGE_RET_(index>=0,"clist_contour::MergeStrips::3",pStrip2)) return false;
0365 pStrip1->insert(pStrip1->end(),index);
0366 }
0367 pStrip2->clear();
0368 return true;
0369 }
0370
0371 return false;
0372 }
0373
0374 inline bool clist_contour::compact_strips ()
0375 {
0376 cline_strip* pStrip;
0377 cline_strip* pStripBase = 0;
0378 UINT i;
0379 cline_strip_list::iterator pos,pos2;
0380 cline_strip_list newList;
0381 bool again, changed;
0382
0383 const double weldDist = 10*(m_dDx*m_dDx+m_dDy*m_dDy);
0384
0385 if(!_ASSERT_RET_(m_vStripLists.size() == get_number_of_planes(),"clist_contour::compact_strips ::0")) return false;
0386 for (i=0;i<get_number_of_planes();i++)
0387 {
0388 double planeHeight = get_plane(i);
0389 again=true;
0390 while(again)
0391 {
0392 // REPEAT COMPACT PROCESS UNTILL LAST PROCESS MAKES NO CHANGE
0393
0394 again=false;
0395 // building compacted list
0396 if(!_ASSERT_RET_(newList.empty(),"clist_contour::compact_strips ::1")) return false;
0397 for (pos=m_vStripLists[i].begin(); pos!=m_vStripLists[i].end();pos++)
0398 {
0399 pStrip=(*pos);
0400 for (pos2=newList.begin(); pos2!=newList.end();pos2++)
0401 {
0402 pStripBase=(*pos2);
0403 changed=MergeStrips(pStripBase,pStrip);
0404 if (changed)
0405 again=true;
0406 if (pStrip->empty())
0407 break;
0408 }
0409 if (pStrip->empty())
0410 delete pStrip;
0411 else
0412 newList.insert(newList.begin(),pStrip);
0413 }
0414
0415
0416 // deleting old list
0417 m_vStripLists[i].clear();
0418 cline_strip* pStrip2;
0419 // Copying all
0420 for (pos2=newList.begin(); pos2 != newList.end(); pos2++)
0421 {
0422 pStrip2=(*pos2);
0423 cline_strip::iterator pos1 = pStrip2->begin(),pos3;
0424 while (pos1!=pStrip2->end())
0425 {
0426 pos3 = pos1;
0427 pos3++;
0428 if (pos3==pStrip2->end()) break; //G.Barrand
0429 if ( (*pos1) == (*pos3))
0430 {
0431 /*G.Barrand : we can't compare with pStrip2->end() content.
0432 if ( (*pos3) != (*pStrip2->end()))
0433 pStrip2->erase(pos3);
0434 else
0435 {
0436 pStrip2->erase(pos3);
0437 break;
0438 }
0439 */
0440 pStrip2->erase(pos3); //G.Barrand.
0441 }
0442 else
0443 pos1++;
0444 }
0445
0446 //if (!(pStrip2->front()==pStrip2->back() && pStrip2->size()==2))
0447 if (pStrip2->size()!=1)
0448 m_vStripLists[i].insert(m_vStripLists[i].begin(),pStrip2 );
0449 else
0450 delete pStrip2;
0451 }
0452 // emptying temp list
0453 newList.clear();
0454
0455 } // OF WHILE(AGAIN) (LAST COMPACT PROCESS MADE NO CHANGES)
0456
0457
0458 if (m_vStripLists[i].empty())
0459 continue;
0460 ///////////////////////////////////////////////////////////////////////
0461 // compact more
0462 int index,count;
0463 size_t Nstrip,j;
0464
0465 Nstrip = m_vStripLists[i].size();
0466 std::vector<bool> closed(Nstrip);
0467 double x,y;
0468
0469 // First let's find the open and closed lists in m_vStripLists
0470 for(pos2 = m_vStripLists[i].begin(), j=0, count=0; pos2 != m_vStripLists[i].end(); pos2++, j++)
0471 {
0472 pStrip = (*pos2);
0473
0474 // is it open ?
0475 if (pStrip->front() != pStrip->back())
0476 {
0477 index = pStrip->front();
0478 x = get_xi(index); y = get_yi(index);
0479 index = pStrip->back();
0480 x -= get_xi(index); y -= get_yi(index);
0481
0482 // is it "almost closed" ?
0483 if ((x*x+y*y < weldDist) ||
0484 SpecialCompactStripCase(get_xi(pStrip->front()), // L.Garnier
0485 get_xi(pStrip->back()),
0486 get_yi(pStrip->front()),
0487 get_yi(pStrip->back()),
0488 planeHeight))
0489 {
0490 closed[j] = true;
0491 // close it !!! Added by L.Garnier
0492 pStrip->push_back(pStrip->front());
0493 //
0494 }
0495 else
0496 {
0497 closed[j] = false;
0498 // updating not closed counter...
0499 count ++;
0500 }
0501 }
0502 else
0503 closed[j] = true;
0504 }
0505
0506 // is there any open strip ?
0507 if (count > 1)
0508 {
0509 // Merge the open strips into NewList
0510 pos = m_vStripLists[i].begin();
0511 for(j=0;j<Nstrip;j++)
0512 {
0513 if (closed[j] == false )
0514 {
0515 pStrip = (*pos);
0516 newList.insert(newList.begin(),pStrip);
0517 pos = m_vStripLists[i].erase(pos);
0518 }
0519 else
0520 pos ++;
0521 }
0522
0523 // are they open strips to process ?
0524 while(newList.size()>1)
0525 {
0526 pStripBase = newList.front();
0527
0528 // merge the rest to pStripBase
0529 again = true;
0530 while (again)
0531 {
0532 again = false;
0533 pos = newList.begin();
0534 for(pos++; pos!=newList.end();)
0535 {
0536 pStrip = (*pos);
0537 changed = ForceMerge(pStripBase,pStrip,planeHeight);
0538 if (changed)
0539 {
0540 again = true;
0541 delete pStrip;
0542 pos = newList.erase(pos);
0543 }
0544 else
0545 pos ++;
0546 }
0547 } // while(again)
0548
0549 index = pStripBase->front();
0550 x = get_xi(index); y = get_yi(index);
0551 index = pStripBase->back();
0552 x -= get_xi(index); y -= get_yi(index);
0553 // if pStripBase is closed or not
0554
0555 if ((x*x+y*y < weldDist) ||
0556 SpecialCompactStripCase(get_xi(pStripBase->front()), // L.Garnier
0557 get_xi(pStripBase->back()),
0558 get_yi(pStripBase->front()),
0559 get_yi(pStripBase->back()),
0560 planeHeight))
0561 {
0562
0563 // close it !!! Added by L.Garnier
0564 if ((x!=0) || (y!=0)) {
0565 pStripBase->push_back(pStripBase->front());
0566 }
0567 //
0568 m_vStripLists[i].insert(m_vStripLists[i].begin(),pStripBase);
0569 newList.pop_front();
0570 }
0571 else
0572 {
0573 if (OnBoundary(pStripBase))
0574 {
0575 _TRACE_(_TT("# open strip ends on boundary, continue.\n"));
0576 m_vStripLists[i].insert(m_vStripLists[i].begin(),pStripBase);
0577 newList.pop_front();
0578 }
0579 else
0580 {
0581 _PROBLEM_(_TT("unpaird open strip at 1!\n"));
0582 //exit(0);
0583 return false;
0584 }
0585 }
0586 } // while(newList.size()>1);
0587
0588
0589 if (newList.size() ==1)
0590 {
0591 pStripBase = newList.front();
0592 index = pStripBase->front(); // L.Garnier
0593 x = get_xi(index); y = get_yi(index); // L.Garnier
0594 index = pStripBase->back(); // L.Garnier
0595 x -= get_xi(index); y -= get_yi(index); // L.Garnier
0596
0597 // is it "almost closed", give last chance...5*weldDist
0598 if (x*x+y*y < 3*weldDist) // L.Garnier
0599 {
0600 m_vStripLists[i].insert(m_vStripLists[i].begin(),pStripBase);
0601 newList.pop_front();
0602 }
0603 else if (OnBoundary(pStripBase))
0604 {
0605 _TRACE_(_TT("# open strip ends on boundary, continue.\n"));
0606 m_vStripLists[i].insert(m_vStripLists[i].begin(),pStripBase);
0607 newList.pop_front();
0608 }
0609 else
0610 {
0611 _PROBLEM_(_TT("unpaird open strip at 2!\n"));
0612 DumpPlane(i);
0613 //exit(0);
0614 return false;
0615 }
0616 }
0617
0618 newList.clear();
0619
0620 }
0621 else if (count == 1)
0622 {
0623 pos = m_vStripLists[i].begin();
0624 for(j=0;j<Nstrip;j++)
0625 {
0626 if (closed[j] == false )
0627 {
0628 pStripBase = (*pos);
0629 break;
0630 }
0631 pos ++;
0632 }
0633 index = pStripBase->front(); // L.Garnier
0634 x = get_xi(index); y = get_yi(index); // L.Garnier
0635 index = pStripBase->back(); // L.Garnier
0636 x -= get_xi(index); y -= get_yi(index); // L.Garnier
0637
0638 // is it "almost closed", give last chance...5*weldDist
0639 if (x*x+y*y < 2*weldDist) // L.Garnier
0640 {
0641 //close it!!
0642 pStripBase->push_back(pStripBase->front()); // L.Garnier
0643 }
0644 else if (OnBoundary(pStripBase))
0645 {
0646 _TRACE_(_TT("# open strip ends on boundary, continue.\n"));
0647 pStripBase->push_back(pStripBase->front()); // L.Garnier
0648 }
0649 else
0650 {
0651 _TRACE_(_TT("unpaird open strip at 3!"));
0652 DumpPlane(i);
0653 return false; // L.Garnier
0654 //exit(0);
0655 }
0656 newList.clear(); // L.Garnier
0657 }
0658 }
0659 return true;
0660 }
0661
0662
0663 inline bool clist_contour::OnBoundary(cline_strip* pStrip)
0664 {
0665 bool e1,e2;
0666
0667 int index = pStrip->front();
0668 double x = get_xi(index), y = get_yi(index);
0669 if (x==m_pLimits[0] || x == m_pLimits[1] ||
0670 y == m_pLimits[2] || y == m_pLimits[3])
0671 e1 = true;
0672 else
0673 e1 = false;
0674
0675 index = pStrip->back();
0676 x = get_xi(index); y = get_yi(index);
0677 if (x==m_pLimits[0] || x == m_pLimits[1] ||
0678 y == m_pLimits[2] || y == m_pLimits[3])
0679 e2 = true;
0680 else
0681 e2 = false;
0682
0683 return (e1 && e2);
0684 }
0685
0686 inline void clist_contour::DumpPlane(UINT iPlane) const
0687 {
0688 cline_strip_list::const_iterator pos;
0689 UINT i;
0690 cline_strip* pStrip;
0691
0692 /*_ASSERT_(iPlane>=0,"clist_contour::DumpPlane");*/
0693 _ASSERT_(iPlane<get_number_of_planes(),"clist_contour::DumpPlane::0");
0694 _TRACE_(_TT("Level : %d"),get_plane(iPlane));
0695
0696 _TRACE_(_TT("Number of strips : %d\r\n"),m_vStripLists[iPlane].size());
0697 _TRACE_(_TT("i np start end xstart ystart xend yend\r\n"));
0698 for (pos = m_vStripLists[iPlane].begin(), i=0; pos != m_vStripLists[iPlane].end(); pos++, i++)
0699 {
0700 pStrip=*pos;
0701 _ASSERTP_(pStrip,"clist_contour::DumpPlane::1");
0702 _TRACE_(_TT("%d %d %d %d %g %g %g %g\r\n"),i,pStrip->size(),pStrip->front(),pStrip->back(),
0703 get_xi(pStrip->front()),get_yi(pStrip->front()),
0704 get_xi(pStrip->back()),get_yi(pStrip->back()) );
0705 }
0706 }
0707
0708 inline double clist_contour::Area(cline_strip* Line)
0709 {
0710 // if Line is not closed, return 0;
0711
0712 double Ar = 0, x, y, x0,y0,x1, y1;
0713 int index;
0714
0715 cline_strip::iterator pos;
0716 pos = Line->begin();
0717 index = (*pos);
0718 x0 = x = get_xi(index);
0719 y0 = y = get_yi(index);
0720
0721 pos ++;
0722
0723 for(;pos!=Line->end();pos++)
0724 {
0725 index = (*pos);
0726 x1 = get_xi(index);
0727 y1 = get_yi(index);
0728 // Ar += (x1-x)*(y1+y);
0729 Ar += (y1-y)*(x1+x)-(x1-x)*(y1+y);
0730 x = x1;
0731 y = y1;
0732
0733 }
0734
0735
0736 //Ar += (x0-x)*(y0+y);
0737 Ar += (y0-y)*(x0+x)-(x0-x)*(y0+y);
0738 // if not closed curve, return 0;
0739 if ((x0-x)*(x0-x) + (y0-y)*(y0-y)>20*(m_dDx*m_dDx+m_dDy*m_dDy))
0740 {
0741 Ar = 0;
0742 _TRACE_(_TT("# open curve!\n"));
0743 }
0744 //else Ar /= -2;
0745 else Ar/=4;
0746 // result is \int ydex/2 alone the implicit direction.
0747 return Ar;
0748 }
0749
0750 inline double clist_contour:: EdgeWeight(cline_strip* pLine, double R)
0751 {
0752 cline_strip::iterator pos;
0753 int count = 0,index;
0754 double x,y;
0755 for(pos = pLine->begin(); pos!=pLine->end(); pos++)
0756 {
0757 index = (*pos);
0758 x = get_xi(index);
0759 y = get_yi(index);
0760 if (fabs(x) > R || fabs(y) > R)
0761 count ++;
0762 }
0763 return (double)count/pLine->size();
0764 }
0765
0766 /*
0767 inline bool clist_contour::PrintContour(std::ostream& a_out)
0768 {
0769 std::streamsize old_prec = a_out.precision(3);
0770 a_out << std::setprecision(10);
0771
0772 UINT i, index;
0773 cline_strip* pStrip;
0774 cline_strip::iterator pos2;
0775 cline_strip_list::iterator pos;
0776
0777 for(i=0;i<get_number_of_planes();i++) {
0778 for(pos = m_vStripLists[i].begin();pos!=m_vStripLists[i].end();pos++)
0779 {
0780 pStrip = (*pos);
0781 for(pos2 = pStrip->begin();pos2!=pStrip->end();pos2++)
0782 {
0783 index = (*pos2);
0784 a_out << get_xi(index)<<"\t"<<get_yi(index)<<"\n";
0785 }
0786 a_out<<"\n";
0787 }
0788 }
0789 a_out.precision(old_prec);
0790 return true;
0791
0792 }
0793 */
0794
0795 //G.Barrand : from .h to .cxx to avoid _ASSERT_ in .h
0796 inline cline_strip_list* clist_contour::get_lines(unsigned int iPlane) {
0797 /*_ASSERT_(iPlane>=0);*/
0798 _ASSERT_(iPlane<get_number_of_planes(),"clist_contour::get_lines");
0799 return &m_vStripLists[iPlane];
0800 }
0801
0802 // Added by L.Garnier
0803 inline bool clist_contour::SpecialCompactStripCase(double aXfront,double aXback,double aYfront,double aYback,double actualHeight)
0804 {
0805 // To solve the case of a list of strips
0806 // which appeared to be open but should correspond to a closed
0807 // contour.
0808 // With the today generate() algorithm, it appears that we fall
0809 // on this case when the begin and end points
0810 // are on a horizontal or vertical line.
0811 // (case where front()->x == back()->x or front()->y == back()->y).
0812 // We try to detect in this method this situation and decide to close
0813 // or not the line. To do that we check the heigth of intermediate
0814 // points to see if there are on the same contour; if so we close
0815 // the line (and return true), if not we do nothing (and return false).
0816
0817 // check if we could realy close it
0818 float marge = 1; // *m_dDy or *m_dDx. 1 seems to be good and normal, but why
0819 // not 2 in certain cases???
0820
0821 double distToNext =0;
0822 // try to get the correct hight
0823 if (get_plane(0)>= actualHeight) {
0824 return false;
0825 }
0826 if (get_number_of_planes() >1){
0827 distToNext = get_plane(1)-get_plane(0);
0828 } else {
0829 return false;
0830 }
0831
0832 if ((aYback-aYfront) == 0) {
0833 double temp;
0834 double av;
0835 double eg;
0836 double ap;
0837
0838 if (aXfront==m_pLimits[0] && aXback == m_pLimits[1]) return false;
0839 if (aXfront==m_pLimits[1] && aXback == m_pLimits[0]) return false;
0840
0841 if (aXfront > aXback ) {
0842 temp = aXfront;
0843 aXfront = aXback;
0844 aXback = temp;
0845 }
0846 for(double check=aXfront+m_dDx;
0847 check<aXback;
0848 check+=m_dDx) {
0849 av = ((*m_pFieldFcn)(check,aYback-marge*m_dDy,m_pFieldFcnData)-actualHeight);
0850 eg = ((*m_pFieldFcn)(check,aYback,m_pFieldFcnData)-actualHeight);
0851 ap = ((*m_pFieldFcn)(check,aYback+marge*m_dDy,m_pFieldFcnData)-actualHeight);
0852
0853 if ((av>distToNext) && (ap>distToNext) && (eg>distToNext)) {
0854 return false;
0855 } else if ((av<0) && (ap<0) && (eg<0)) {
0856 return false;
0857 }
0858 }
0859 return true;
0860 } else if ((aXback-aXfront) == 0) {
0861 double temp;
0862 double av;
0863 double eg;
0864 double ap;
0865 if (aYfront==m_pLimits[3] && aYback == m_pLimits[2]) return false;
0866 if (aYfront==m_pLimits[2] && aYback == m_pLimits[3]) return false;
0867
0868 if (aYfront > aYback ) {
0869 temp = aYfront;
0870 aYfront = aYback;
0871 aYback = temp;
0872 }
0873
0874 for(double check=aYfront+m_dDy;
0875 check<aYback;
0876 check+=m_dDy) {
0877 av = ((*m_pFieldFcn)(aXback-marge*m_dDx,check,m_pFieldFcnData)-actualHeight);
0878 eg = ((*m_pFieldFcn)(aXback,check,m_pFieldFcnData)-actualHeight);
0879 ap = ((*m_pFieldFcn)(aXback+marge*m_dDx,check,m_pFieldFcnData)-actualHeight);
0880 if ((av>distToNext) && (ap>distToNext) && (eg>distToNext)) {
0881 return false;
0882 } else if ((av<0) && (ap<0) && (eg<0)) {
0883 return false;
0884 }
0885 }
0886 return true;
0887 }
0888 return false;
0889 }
0890
0891 }
0892
0893 #endif