g4tools  5.4.0
clist_contour
Go to the documentation of this file.
1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
2 // See the file tools.license for terms.
3 
4 #ifndef tools_clist_contour
5 #define tools_clist_contour
6 
7 // G.Barrand : inline version of the one found in Lib of OSC 16.11.
8 // This code is not mine and I keep it "as it is".
9 
10 // Inheritance :
11 #include "ccontour"
12 
13 #include <list>
14 #include <ostream>
15 #include <iomanip> //std::setprecision
16 
17 namespace tools {
18 
19 // a list of point index referring to the secondary grid
20 // Let i the index of a point,
21 typedef std::list<unsigned int> cline_strip;
22 typedef std::list<cline_strip*> cline_strip_list;
23 typedef std::vector<cline_strip_list> cline_strip_list_vector;
24 
25 class clist_contour : public ccontour
26 {
27 public: //ccontour
28  // Adding segment to line strips
29  // See ccontour::ExportLine for further details
30  virtual void ExportLine(int iPlane,int x1, int y1, int x2, int y2);
31 
32 public:
33  clist_contour();
35 protected: //G.Barrand
36  clist_contour(const clist_contour& a_from):ccontour(a_from){}
37 private: //G.Barrand
38  clist_contour& operator=(const clist_contour&){return *this;}
39 public:
40  // retreiving list of line strip for the i-th contour
41  cline_strip_list* get_lines(unsigned int iPlane);
42  // Basic algorithm to concatanate line strip. Not optimized at all !
43  bool compact_strips ();
44  // generate contour strips
45  virtual void generate();
46 protected: //G.Barrand
47 
48  // Initializing memory
49  virtual void InitMemory();
50  // Cleaning memory and line strips
51  virtual void CleanMemory();
52 
53  // Adding segment to line strips
54  // See ccontour::ExportLine for further details
55  //void ExportLine(int iPlane,int x1, int y1, int x2, int y2);
56 
58  void DumpPlane(unsigned int iPlane) const;
59 
60  // Area given by this function can be positive or negative depending on the winding direction of the contour.
61  double Area(cline_strip* Line);
62 
63  double EdgeWeight(cline_strip* pLine, double R);
64  //bool PrintContour(std::ostream& a_out);
65 protected:
66  // Merges pStrip1 with pStrip2 if they have a common end point
67  bool MergeStrips(cline_strip* pStrip1, cline_strip* pStrip2);
68  // Merges the two strips with a welding threshold.
69  bool ForceMerge(cline_strip* pStrip1, cline_strip* pStrip2,double);
70  // returns true if contour is touching boundary
71  bool OnBoundary(cline_strip* pStrip);
72  // L.Garnier : check specials case for CompactStrip
73  bool SpecialCompactStripCase(double,double,double,double,double);
74 
75 private:
76  // array of line strips
77  cline_strip_list_vector m_vStripLists;
78  typedef unsigned int UINT;
79 
80 private:
81  static const char* _TT(const char* what) {return what;}
82 
83  static void _TRACE_(const char* /*a_fmt*/,...) {
84  //va_list args;
85  //va_start(args,a_fmt);
86  //::vprintf(s,a_fmt,args);
87  //va_end(args);
88  }
89  static void _PROBLEM_(const char* what) {::printf("%s",what);}
90 
91  static bool _ASSERT_RET_(bool what,const char* cmt) {
92  if(!(what)) {
93  ::printf("debug : ListContour : assert failure in %s\n",cmt);
94  return false;
95  }
96  return true;
97  }
98 
99  static bool _ASSERT_MERGE_RET_(bool what,const char* cmt,cline_strip* pStrip2) {
100  if(!(what)) {
101  ::printf("debug : ListContour : assert failure in %s\n",cmt);
102  pStrip2->clear();
103  return false;
104  }
105  return true;
106  }
107 };
108 
109 
110 // implementation :
112 : ccontour()
113 {
114 }
115 
117 {
118  // generate line strips
120  // compact strips
121  compact_strips ();
122 }
123 
125 {
127 
128  cline_strip_list::iterator pos;
129  cline_strip* pStrip;
130 
131  if (!m_vStripLists.empty())
132  {
133  UINT i;
134  // reseting lists
135  _ASSERT_(m_vStripLists.size() == get_number_of_planes(),"clist_contour::InitMemory::0");
136  for (i=0;i<get_number_of_planes();i++)
137  {
138  for (pos = m_vStripLists[i].begin(); pos!=m_vStripLists[i].end() ; pos++)
139  {
140  pStrip=(*pos);
141  _ASSERTP_(pStrip,"clist_contour::InitMemory::1");
142 
143  pStrip->clear();
144  delete pStrip;
145  }
146  m_vStripLists[i].clear();
147  }
148  }
149  else
150  m_vStripLists.resize(get_number_of_planes());
151 }
152 
154 {
156 
157  cline_strip_list::iterator pos;
158  cline_strip* pStrip;
159  UINT i;
160 
161  // reseting lists
162  for (i=0;i<m_vStripLists.size();i++) //G.Barrand
163  {
164  for (pos=m_vStripLists[i].begin(); pos!=m_vStripLists[i].end();pos++)
165  {
166  pStrip=(*pos);
167  _ASSERTP_(pStrip,"clist_contour::CleanMemory");
168  pStrip->clear();
169  delete pStrip;
170  }
171  m_vStripLists[i].clear();
172  }
173 }
174 
175 inline void clist_contour::ExportLine(int iPlane,int x1, int y1, int x2, int y2)
176 {
177  _ASSERT_(iPlane>=0,"clist_contour::ExportLine::0");
178  _ASSERT_(iPlane<(int)get_number_of_planes(),"clist_contour::ExportLine::1");
179 
180  // check that the two points are not at the beginning or end of the some line strip
181  UINT i1=y1*(m_iColSec+1)+x1;
182  UINT i2=y2*(m_iColSec+1)+x2;
183 
184  cline_strip* pStrip;
185 
186  cline_strip_list::iterator pos;
187  bool added = false;
188  for(pos=m_vStripLists[iPlane].begin(); pos!=m_vStripLists[iPlane].end() && !added; pos++)
189  {
190  pStrip=(*pos);
191  _ASSERTP_(pStrip,"clist_contour::ExportLine::2");
192  // check if points are appendable to this strip
193  if (i1==pStrip->front())
194  {
195  pStrip->insert(pStrip->begin(),i2);
196  return;
197  }
198  if (i1==pStrip->back())
199  {
200  pStrip->insert(pStrip->end(),i2);
201  return;
202  }
203  if (i2==pStrip->front())
204  {
205  pStrip->insert(pStrip->begin(),i1);
206  return;
207  }
208  if (i2==pStrip->back())
209  {
210  pStrip->insert(pStrip->end(),i1);
211  return;
212  }
213  }
214 
215  // segment was not part of any line strip, creating new one
216  pStrip=new cline_strip;
217  pStrip->insert(pStrip->begin(),i1);
218  pStrip->insert(pStrip->end(),i2);
219  m_vStripLists[iPlane].insert(m_vStripLists[iPlane].begin(),pStrip);
220 }
221 
222 inline bool clist_contour::ForceMerge(cline_strip* pStrip1, cline_strip* pStrip2,double aHeight)
223 {
224 
225  cline_strip::iterator pos;
226  cline_strip::reverse_iterator rpos;
227 
228  if (pStrip2->empty())
229  return false;
230 
231  double x[4], y[4], weldDist;
232  int index;
233  index = pStrip1->front();
234  x[0] = get_xi(index);
235  y[0] = get_yi(index);
236  index = pStrip1->back();
237  x[1] = get_xi(index);
238  y[1] = get_yi(index);
239  index = pStrip2->front();
240  x[2] = get_xi(index);
241  y[2] = get_yi(index);
242  index = pStrip2->back();
243  x[3] = get_xi(index);
244  y[3] = get_yi(index);
245 
246  weldDist = 10*(m_dDx*m_dDx+m_dDy*m_dDy);
247 
248  if (((x[1]-x[2])*(x[1]-x[2])+(y[1]-y[2])*(y[1]-y[2])< weldDist)
249  || SpecialCompactStripCase(x[1],x[2],y[1],y[2],aHeight)) // L.Garnier
250 
251  {
252  for (pos=pStrip2->begin(); pos!=pStrip2->end();pos++)
253  {
254  index=(*pos);
255  if(!_ASSERT_RET_(index>=0,"clist_contour::ForceMerge::0")) return false;
256  pStrip1->insert(pStrip1->end(),index);
257  }
258  pStrip2->clear();
259  return true;
260  }
261 
262  if (((x[3]-x[0])*(x[3]-x[0])+(y[3]-y[0])*(y[3]-y[0])< weldDist)
263  || SpecialCompactStripCase(x[3],x[0],y[3],y[0],aHeight)) // L.Garnier
264  {
265  for (rpos=pStrip2->rbegin(); rpos!=pStrip2->rend();rpos++)
266  {
267  index=(*rpos);
268  if(!_ASSERT_RET_(index>=0,"clist_contour::ForceMerge::1")) return false;
269  pStrip1->insert(pStrip1->begin(),index);
270  }
271  pStrip2->clear();
272  return true;
273  }
274 
275  if (((x[1]-x[3])*(x[1]-x[3])+(y[1]-y[3])*(y[1]-y[3])< weldDist)
276  || SpecialCompactStripCase(x[1],x[3],y[1],y[3],aHeight)) // L.Garnier
277  {
278  for (rpos=pStrip2->rbegin(); rpos!=pStrip2->rend();rpos++)
279  {
280  index=(*rpos);
281  if(!_ASSERT_RET_(index>=0,"clist_contour::ForceMerge::2")) return false;
282  pStrip1->insert(pStrip1->end(),index);
283  }
284  pStrip2->clear();
285  return true;
286  }
287 
288  if (((x[0]-x[2])*(x[0]-x[2])+(y[0]-y[2])*(y[0]-y[2])< weldDist)
289  || SpecialCompactStripCase(x[0],x[2],y[0],y[2],aHeight)) // L.Garnier
290  {
291  for (pos=pStrip2->begin(); pos!=pStrip2->end();pos++)
292  {
293  index=(*pos);
294  if(!_ASSERT_RET_(index>=0,"clist_contour::ForceMerge::3")) return false;
295  pStrip1->insert(pStrip1->begin(),index);
296  }
297  pStrip2->clear();
298  return true;
299  }
300 
301  return false;
302 }
303 
304 inline bool clist_contour::MergeStrips(cline_strip* pStrip1, cline_strip* pStrip2)
305 {
306  cline_strip::iterator pos;
307  cline_strip::reverse_iterator rpos;
308  if (pStrip2->empty())
309  return false;
310 
311  int index;
312 
313  // debugging stuff
314  if (pStrip2->front()==pStrip1->front())
315  {
316  // retreiving first element
317  pStrip2->pop_front();
318  // adding the rest to strip1
319  for (pos=pStrip2->begin(); pos!=pStrip2->end();pos++)
320  {
321  index=(*pos);
322  if(!_ASSERT_MERGE_RET_(index>=0,"clist_contour::MergeStrips::0",pStrip2)) return false;
323  pStrip1->insert(pStrip1->begin(),index);
324  }
325  pStrip2->clear();
326  return true;
327  }
328 
329  if (pStrip2->front()==pStrip1->back())
330  {
331  pStrip2->pop_front();
332  // adding the rest to strip1
333  for (pos=pStrip2->begin(); pos!=pStrip2->end();pos++)
334  {
335  index=(*pos);
336  if(!_ASSERT_MERGE_RET_(index>=0,"clist_contour::MergeStrips::1",pStrip2)) return false;
337  pStrip1->insert(pStrip1->end(),index);
338  }
339  pStrip2->clear();
340  return true;
341  }
342 
343  if (pStrip2->back()==pStrip1->front())
344  {
345  pStrip2->pop_back();
346  // adding the rest to strip1
347  for (rpos=pStrip2->rbegin(); rpos!=pStrip2->rend();rpos++)
348  {
349  index=(*rpos);
350  if(!_ASSERT_MERGE_RET_(index>=0,"clist_contour::MergeStrips::2",pStrip2)) return false;
351  pStrip1->insert(pStrip1->begin(),index);
352  }
353  pStrip2->clear();
354  return true;
355  }
356 
357  if (pStrip2->back()==pStrip1->back())
358  {
359  pStrip2->pop_back();
360  // adding the rest to strip1
361  for (rpos=pStrip2->rbegin(); rpos!=pStrip2->rend();rpos++)
362  {
363  index=(*rpos);
364  if(!_ASSERT_MERGE_RET_(index>=0,"clist_contour::MergeStrips::3",pStrip2)) return false;
365  pStrip1->insert(pStrip1->end(),index);
366  }
367  pStrip2->clear();
368  return true;
369  }
370 
371  return false;
372 }
373 
375 {
376  cline_strip* pStrip;
377  cline_strip* pStripBase = 0;
378  UINT i;
379  cline_strip_list::iterator pos,pos2;
380  cline_strip_list newList;
381  bool again, changed;
382 
383  const double weldDist = 10*(m_dDx*m_dDx+m_dDy*m_dDy);
384 
385  if(!_ASSERT_RET_(m_vStripLists.size() == get_number_of_planes(),"clist_contour::compact_strips ::0")) return false;
386  for (i=0;i<get_number_of_planes();i++)
387  {
388  double planeHeight = get_plane(i);
389  again=true;
390  while(again)
391  {
392  // REPEAT COMPACT PROCESS UNTILL LAST PROCESS MAKES NO CHANGE
393 
394  again=false;
395  // building compacted list
396  if(!_ASSERT_RET_(newList.empty(),"clist_contour::compact_strips ::1")) return false;
397  for (pos=m_vStripLists[i].begin(); pos!=m_vStripLists[i].end();pos++)
398  {
399  pStrip=(*pos);
400  for (pos2=newList.begin(); pos2!=newList.end();pos2++)
401  {
402  pStripBase=(*pos2);
403  changed=MergeStrips(pStripBase,pStrip);
404  if (changed)
405  again=true;
406  if (pStrip->empty())
407  break;
408  }
409  if (pStrip->empty())
410  delete pStrip;
411  else
412  newList.insert(newList.begin(),pStrip);
413  }
414 
415 
416  // deleting old list
417  m_vStripLists[i].clear();
418  cline_strip* pStrip2;
419  // Copying all
420  for (pos2=newList.begin(); pos2 != newList.end(); pos2++)
421  {
422  pStrip2=(*pos2);
423  cline_strip::iterator pos1 = pStrip2->begin(),pos3;
424  while (pos1!=pStrip2->end())
425  {
426  pos3 = pos1;
427  pos3++;
428  if (pos3==pStrip2->end()) break; //G.Barrand
429  if ( (*pos1) == (*pos3))
430  {
431  /*G.Barrand : we can't compare with pStrip2->end() content.
432  if ( (*pos3) != (*pStrip2->end()))
433  pStrip2->erase(pos3);
434  else
435  {
436  pStrip2->erase(pos3);
437  break;
438  }
439  */
440  pStrip2->erase(pos3); //G.Barrand.
441  }
442  else
443  pos1++;
444  }
445 
446  //if (!(pStrip2->front()==pStrip2->back() && pStrip2->size()==2))
447  if (pStrip2->size()!=1)
448  m_vStripLists[i].insert(m_vStripLists[i].begin(),pStrip2 );
449  else
450  delete pStrip2;
451  }
452  // emptying temp list
453  newList.clear();
454 
455  } // OF WHILE(AGAIN) (LAST COMPACT PROCESS MADE NO CHANGES)
456 
457 
458  if (m_vStripLists[i].empty())
459  continue;
461  // compact more
462  int index,count;
463  size_t Nstrip,j;
464 
465  Nstrip = m_vStripLists[i].size();
466  std::vector<bool> closed(Nstrip);
467  double x,y;
468 
469  // First let's find the open and closed lists in m_vStripLists
470  for(pos2 = m_vStripLists[i].begin(), j=0, count=0; pos2 != m_vStripLists[i].end(); pos2++, j++)
471  {
472  pStrip = (*pos2);
473 
474  // is it open ?
475  if (pStrip->front() != pStrip->back())
476  {
477  index = pStrip->front();
478  x = get_xi(index); y = get_yi(index);
479  index = pStrip->back();
480  x -= get_xi(index); y -= get_yi(index);
481 
482  // is it "almost closed" ?
483  if ((x*x+y*y < weldDist) ||
484  SpecialCompactStripCase(get_xi(pStrip->front()), // L.Garnier
485  get_xi(pStrip->back()),
486  get_yi(pStrip->front()),
487  get_yi(pStrip->back()),
488  planeHeight))
489  {
490  closed[j] = true;
491  // close it !!! Added by L.Garnier
492  pStrip->push_back(pStrip->front());
493  //
494  }
495  else
496  {
497  closed[j] = false;
498  // updating not closed counter...
499  count ++;
500  }
501  }
502  else
503  closed[j] = true;
504  }
505 
506  // is there any open strip ?
507  if (count > 1)
508  {
509  // Merge the open strips into NewList
510  pos = m_vStripLists[i].begin();
511  for(j=0;j<Nstrip;j++)
512  {
513  if (closed[j] == false )
514  {
515  pStrip = (*pos);
516  newList.insert(newList.begin(),pStrip);
517  pos = m_vStripLists[i].erase(pos);
518  }
519  else
520  pos ++;
521  }
522 
523  // are they open strips to process ?
524  while(newList.size()>1)
525  {
526  pStripBase = newList.front();
527 
528  // merge the rest to pStripBase
529  again = true;
530  while (again)
531  {
532  again = false;
533  pos = newList.begin();
534  for(pos++; pos!=newList.end();)
535  {
536  pStrip = (*pos);
537  changed = ForceMerge(pStripBase,pStrip,planeHeight);
538  if (changed)
539  {
540  again = true;
541  delete pStrip;
542  pos = newList.erase(pos);
543  }
544  else
545  pos ++;
546  }
547  } // while(again)
548 
549  index = pStripBase->front();
550  x = get_xi(index); y = get_yi(index);
551  index = pStripBase->back();
552  x -= get_xi(index); y -= get_yi(index);
553  // if pStripBase is closed or not
554 
555  if ((x*x+y*y < weldDist) ||
556  SpecialCompactStripCase(get_xi(pStripBase->front()), // L.Garnier
557  get_xi(pStripBase->back()),
558  get_yi(pStripBase->front()),
559  get_yi(pStripBase->back()),
560  planeHeight))
561  {
562 
563  // close it !!! Added by L.Garnier
564  if ((x!=0) || (y!=0)) {
565  pStripBase->push_back(pStripBase->front());
566  }
567  //
568  m_vStripLists[i].insert(m_vStripLists[i].begin(),pStripBase);
569  newList.pop_front();
570  }
571  else
572  {
573  if (OnBoundary(pStripBase))
574  {
575  _TRACE_(_TT("# open strip ends on boundary, continue.\n"));
576  m_vStripLists[i].insert(m_vStripLists[i].begin(),pStripBase);
577  newList.pop_front();
578  }
579  else
580  {
581  _PROBLEM_(_TT("unpaird open strip at 1!\n"));
582  //exit(0);
583  return false;
584  }
585  }
586  } // while(newList.size()>1);
587 
588 
589  if (newList.size() ==1)
590  {
591  pStripBase = newList.front();
592  index = pStripBase->front(); // L.Garnier
593  x = get_xi(index); y = get_yi(index); // L.Garnier
594  index = pStripBase->back(); // L.Garnier
595  x -= get_xi(index); y -= get_yi(index); // L.Garnier
596 
597  // is it "almost closed", give last chance...5*weldDist
598  if (x*x+y*y < 3*weldDist) // L.Garnier
599  {
600  m_vStripLists[i].insert(m_vStripLists[i].begin(),pStripBase);
601  newList.pop_front();
602  }
603  else if (OnBoundary(pStripBase))
604  {
605  _TRACE_(_TT("# open strip ends on boundary, continue.\n"));
606  m_vStripLists[i].insert(m_vStripLists[i].begin(),pStripBase);
607  newList.pop_front();
608  }
609  else
610  {
611  _PROBLEM_(_TT("unpaird open strip at 2!\n"));
612  DumpPlane(i);
613  //exit(0);
614  return false;
615  }
616  }
617 
618  newList.clear();
619 
620  }
621  else if (count == 1)
622  {
623  pos = m_vStripLists[i].begin();
624  for(j=0;j<Nstrip;j++)
625  {
626  if (closed[j] == false )
627  {
628  pStripBase = (*pos);
629  break;
630  }
631  pos ++;
632  }
633  index = pStripBase->front(); // L.Garnier
634  x = get_xi(index); y = get_yi(index); // L.Garnier
635  index = pStripBase->back(); // L.Garnier
636  x -= get_xi(index); y -= get_yi(index); // L.Garnier
637 
638  // is it "almost closed", give last chance...5*weldDist
639  if (x*x+y*y < 2*weldDist) // L.Garnier
640  {
641  //close it!!
642  pStripBase->push_back(pStripBase->front()); // L.Garnier
643  }
644  else if (OnBoundary(pStripBase))
645  {
646  _TRACE_(_TT("# open strip ends on boundary, continue.\n"));
647  pStripBase->push_back(pStripBase->front()); // L.Garnier
648  }
649  else
650  {
651  _TRACE_(_TT("unpaird open strip at 3!"));
652  DumpPlane(i);
653  return false; // L.Garnier
654  //exit(0);
655  }
656  newList.clear(); // L.Garnier
657  }
658  }
659  return true;
660 }
661 
662 
664 {
665  bool e1,e2;
666 
667  int index = pStrip->front();
668  double x = get_xi(index), y = get_yi(index);
669  if (x==m_pLimits[0] || x == m_pLimits[1] ||
670  y == m_pLimits[2] || y == m_pLimits[3])
671  e1 = true;
672  else
673  e1 = false;
674 
675  index = pStrip->back();
676  x = get_xi(index); y = get_yi(index);
677  if (x==m_pLimits[0] || x == m_pLimits[1] ||
678  y == m_pLimits[2] || y == m_pLimits[3])
679  e2 = true;
680  else
681  e2 = false;
682 
683  return (e1 && e2);
684 }
685 
686 inline void clist_contour::DumpPlane(UINT iPlane) const
687 {
688  cline_strip_list::const_iterator pos;
689  UINT i;
690  cline_strip* pStrip;
691 
692  /*_ASSERT_(iPlane>=0,"clist_contour::DumpPlane");*/
693  _ASSERT_(iPlane<get_number_of_planes(),"clist_contour::DumpPlane::0");
694  _TRACE_(_TT("Level : %d"),get_plane(iPlane));
695 
696  _TRACE_(_TT("Number of strips : %d\r\n"),m_vStripLists[iPlane].size());
697  _TRACE_(_TT("i np start end xstart ystart xend yend\r\n"));
698  for (pos = m_vStripLists[iPlane].begin(), i=0; pos != m_vStripLists[iPlane].end(); pos++, i++)
699  {
700  pStrip=*pos;
701  _ASSERTP_(pStrip,"clist_contour::DumpPlane::1");
702  _TRACE_(_TT("%d %d %d %d %g %g %g %g\r\n"),i,pStrip->size(),pStrip->front(),pStrip->back(),
703  get_xi(pStrip->front()),get_yi(pStrip->front()),
704  get_xi(pStrip->back()),get_yi(pStrip->back()) );
705  }
706 }
707 
708 inline double clist_contour::Area(cline_strip* Line)
709 {
710  // if Line is not closed, return 0;
711 
712  double Ar = 0, x, y, x0,y0,x1, y1;
713  int index;
714 
715  cline_strip::iterator pos;
716  pos = Line->begin();
717  index = (*pos);
718  x0 = x = get_xi(index);
719  y0 = y = get_yi(index);
720 
721  pos ++;
722 
723  for(;pos!=Line->end();pos++)
724  {
725  index = (*pos);
726  x1 = get_xi(index);
727  y1 = get_yi(index);
728  // Ar += (x1-x)*(y1+y);
729  Ar += (y1-y)*(x1+x)-(x1-x)*(y1+y);
730  x = x1;
731  y = y1;
732 
733  }
734 
735 
736  //Ar += (x0-x)*(y0+y);
737  Ar += (y0-y)*(x0+x)-(x0-x)*(y0+y);
738  // if not closed curve, return 0;
739  if ((x0-x)*(x0-x) + (y0-y)*(y0-y)>20*(m_dDx*m_dDx+m_dDy*m_dDy))
740  {
741  Ar = 0;
742  _TRACE_(_TT("# open curve!\n"));
743  }
744  //else Ar /= -2;
745  else Ar/=4;
746  // result is \int ydex/2 alone the implicit direction.
747  return Ar;
748 }
749 
750 inline double clist_contour:: EdgeWeight(cline_strip* pLine, double R)
751 {
752  cline_strip::iterator pos;
753  int count = 0,index;
754  double x,y;
755  for(pos = pLine->begin(); pos!=pLine->end(); pos++)
756  {
757  index = (*pos);
758  x = get_xi(index);
759  y = get_yi(index);
760  if (fabs(x) > R || fabs(y) > R)
761  count ++;
762  }
763  return (double)count/pLine->size();
764 }
765 
766 /*
767 inline bool clist_contour::PrintContour(std::ostream& a_out)
768 {
769  std::streamsize old_prec = a_out.precision(3);
770  a_out << std::setprecision(10);
771 
772  UINT i, index;
773  cline_strip* pStrip;
774  cline_strip::iterator pos2;
775  cline_strip_list::iterator pos;
776 
777  for(i=0;i<get_number_of_planes();i++) {
778  for(pos = m_vStripLists[i].begin();pos!=m_vStripLists[i].end();pos++)
779  {
780  pStrip = (*pos);
781  for(pos2 = pStrip->begin();pos2!=pStrip->end();pos2++)
782  {
783  index = (*pos2);
784  a_out << get_xi(index)<<"\t"<<get_yi(index)<<"\n";
785  }
786  a_out<<"\n";
787  }
788  }
789  a_out.precision(old_prec);
790  return true;
791 
792 }
793 */
794 
795 //G.Barrand : from .h to .cxx to avoid _ASSERT_ in .h
796 inline cline_strip_list* clist_contour::get_lines(unsigned int iPlane) {
797  /*_ASSERT_(iPlane>=0);*/
798  _ASSERT_(iPlane<get_number_of_planes(),"clist_contour::get_lines");
799  return &m_vStripLists[iPlane];
800 }
801 
802 // Added by L.Garnier
803 inline bool clist_contour::SpecialCompactStripCase(double aXfront,double aXback,double aYfront,double aYback,double actualHeight)
804 {
805  // To solve the case of a list of strips
806  // which appeared to be open but should correspond to a closed
807  // contour.
808  // With the today generate() algorithm, it appears that we fall
809  // on this case when the begin and end points
810  // are on a horizontal or vertical line.
811  // (case where front()->x == back()->x or front()->y == back()->y).
812  // We try to detect in this method this situation and decide to close
813  // or not the line. To do that we check the heigth of intermediate
814  // points to see if there are on the same contour; if so we close
815  // the line (and return true), if not we do nothing (and return false).
816 
817  // check if we could realy close it
818  float marge = 1; // *m_dDy or *m_dDx. 1 seems to be good and normal, but why
819  // not 2 in certain cases???
820 
821  double distToNext =0;
822  // try to get the correct hight
823  if (get_plane(0)>= actualHeight) {
824  return false;
825  }
826  if (get_number_of_planes() >1){
827  distToNext = get_plane(1)-get_plane(0);
828  } else {
829  return false;
830  }
831 
832  if ((aYback-aYfront) == 0) {
833  double temp;
834  double av;
835  double eg;
836  double ap;
837 
838  if (aXfront==m_pLimits[0] && aXback == m_pLimits[1]) return false;
839  if (aXfront==m_pLimits[1] && aXback == m_pLimits[0]) return false;
840 
841  if (aXfront > aXback ) {
842  temp = aXfront;
843  aXfront = aXback;
844  aXback = temp;
845  }
846  for(double check=aXfront+m_dDx;
847  check<aXback;
848  check+=m_dDx) {
849  av = ((*m_pFieldFcn)(check,aYback-marge*m_dDy,m_pFieldFcnData)-actualHeight);
850  eg = ((*m_pFieldFcn)(check,aYback,m_pFieldFcnData)-actualHeight);
851  ap = ((*m_pFieldFcn)(check,aYback+marge*m_dDy,m_pFieldFcnData)-actualHeight);
852 
853  if ((av>distToNext) && (ap>distToNext) && (eg>distToNext)) {
854  return false;
855  } else if ((av<0) && (ap<0) && (eg<0)) {
856  return false;
857  }
858  }
859  return true;
860  } else if ((aXback-aXfront) == 0) {
861  double temp;
862  double av;
863  double eg;
864  double ap;
865  if (aYfront==m_pLimits[3] && aYback == m_pLimits[2]) return false;
866  if (aYfront==m_pLimits[2] && aYback == m_pLimits[3]) return false;
867 
868  if (aYfront > aYback ) {
869  temp = aYfront;
870  aYfront = aYback;
871  aYback = temp;
872  }
873 
874  for(double check=aYfront+m_dDy;
875  check<aYback;
876  check+=m_dDy) {
877  av = ((*m_pFieldFcn)(aXback-marge*m_dDx,check,m_pFieldFcnData)-actualHeight);
878  eg = ((*m_pFieldFcn)(aXback,check,m_pFieldFcnData)-actualHeight);
879  ap = ((*m_pFieldFcn)(aXback+marge*m_dDx,check,m_pFieldFcnData)-actualHeight);
880  if ((av>distToNext) && (ap>distToNext) && (eg>distToNext)) {
881  return false;
882  } else if ((av<0) && (ap<0) && (eg<0)) {
883  return false;
884  }
885  }
886  return true;
887  }
888  return false;
889 }
890 
891 }
892 
893 #endif
tools::clist_contour::MergeStrips
bool MergeStrips(cline_strip *pStrip1, cline_strip *pStrip2)
Definition: clist_contour:304
tools::clist_contour::clist_contour
clist_contour()
Definition: clist_contour:111
tools::ccontour::m_dDx
double m_dDx
Definition: ccontour:180
tools::clist_contour::ExportLine
virtual void ExportLine(int iPlane, int x1, int y1, int x2, int y2)
Definition: clist_contour:175
tools::clist_contour::OnBoundary
bool OnBoundary(cline_strip *pStrip)
Definition: clist_contour:663
tools::clist_contour::EdgeWeight
double EdgeWeight(cline_strip *pLine, double R)
Definition: clist_contour:750
tools::ccontour::generate
virtual void generate()
Definition: ccontour:277
tools::ccontour::get_number_of_planes
size_t get_number_of_planes() const
Definition: ccontour:106
tools::clist_contour::generate
virtual void generate()
Definition: clist_contour:116
tools::ccontour::InitMemory
virtual void InitMemory()
Definition: ccontour:250
tools::clist_contour
Definition: clist_contour:26
tools::ccontour::m_dDy
double m_dDy
Definition: ccontour:181
tools::waxml::begin
void begin(std::ostream &a_writer)
Definition: begend:15
tools::clist_contour::~clist_contour
virtual ~clist_contour()
Definition: clist_contour:34
tools::ccontour::get_plane
double get_plane(unsigned int i) const
Definition: ccontour:654
tools::ccontour::CleanMemory
virtual void CleanMemory()
Definition: ccontour:262
tools::clist_contour::get_lines
cline_strip_list * get_lines(unsigned int iPlane)
Definition: clist_contour:796
tools::clist_contour::SpecialCompactStripCase
bool SpecialCompactStripCase(double, double, double, double, double)
Definition: clist_contour:803
tools::cline_strip_list
std::list< cline_strip * > cline_strip_list
Definition: clist_contour:22
tools::clist_contour::DumpPlane
void DumpPlane(unsigned int iPlane) const
debuggin
Definition: clist_contour:686
tools::file::size
bool size(const std::string &a_file, long &a_size)
Definition: fsize:13
tools::ccontour::get_yi
double get_yi(int i) const
Definition: ccontour:660
tools::ccontour::get_xi
double get_xi(int i) const
Definition: ccontour:111
tools::clist_contour::InitMemory
virtual void InitMemory()
Definition: clist_contour:124
tools
inlined C code : ///////////////////////////////////
Definition: aida_ntuple:26
tools::cline_strip_list_vector
std::vector< cline_strip_list > cline_strip_list_vector
Definition: clist_contour:23
ccontour
tools::clist_contour::clist_contour
clist_contour(const clist_contour &a_from)
Definition: clist_contour:36
tools::ccontour::m_iColSec
int m_iColSec
Definition: ccontour:171
tools::clist_contour::Area
double Area(cline_strip *Line)
Definition: clist_contour:708
tools::clist_contour::compact_strips
bool compact_strips()
Definition: clist_contour:374
tools::clist_contour::ForceMerge
bool ForceMerge(cline_strip *pStrip1, cline_strip *pStrip2, double)
Definition: clist_contour:222
tools::ccontour::m_pLimits
double m_pLimits[4]
Definition: ccontour:168
tools::what
what
Definition: strip:12
tools::clist_contour::CleanMemory
virtual void CleanMemory()
Definition: clist_contour:153
tools::ccontour::_ASSERT_
static void _ASSERT_(bool a_what, const char *a_where)
Definition: ccontour:197
tools::ccontour
Definition: ccontour:55
tools::ccontour::m_pFieldFcnData
void * m_pFieldFcnData
Definition: ccontour:173
tools::cline_strip
std::list< unsigned int > cline_strip
Definition: clist_contour:21
tools::ccontour::_ASSERTP_
static void _ASSERTP_(void *a_what, const char *a_where)
Definition: ccontour:204