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