Orfeo Toolbox  3.16
itkVoronoiDiagram2DGenerator.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Insight Segmentation & Registration Toolkit
4  Module: $RCSfile: itkVoronoiDiagram2DGenerator.txx,v $
5  Language: C++
6  Date: $Date: 2009-04-06 00:19:17 $
7  Version: $Revision: 1.24 $
8 
9  Copyright (c) Insight Software Consortium. All rights reserved.
10  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
11 
12  This software is distributed WITHOUT ANY WARRANTY; without even
13  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14  PURPOSE. See the above copyright notices for more information.
15 
16 =========================================================================*/
17 #ifndef __itkVoronoiDiagram2DGenerator_txx
18 #define __itkVoronoiDiagram2DGenerator_txx
20 
21 
22 #include <algorithm>
23 #include "vnl/vnl_sample.h"
24 
25 namespace itk
26 {
27 
28 const double NUMERIC_TOLERENCE = 1.0e-10;
29 const double DIFF_TOLERENCE = 0.001;
30 
31 template <typename TCoordRepType>
34 {
35  m_NumberOfSeeds = 0;
36  m_Pxmin = 0;
37  m_Pymin = 0;
38  m_OutputVD=this->GetOutput();
39 }
40 
41 template <typename TCoordRepType>
44 {
45 }
46 
47 template <typename TCoordRepType>
48 void
50 PrintSelf(std::ostream& os, Indent indent) const
51 {
52  Superclass::PrintSelf(os, indent);
53  os << indent << "Number Of Seeds: "
54  << m_NumberOfSeeds << std::endl;
55 }
56 
57 /* Set random seed points. Specify the number of seeds as "num". */
58 template <typename TCoordRepType>
59 void
62 {
63  PointType curr;
64  m_Seeds.clear();
65  double ymax = (double)(m_VorBoundary[1]);
66  double xmax = (double)(m_VorBoundary[0]);
67  for(int i = 0; i < num; ++i)
68  {
69  curr[0] = (CoordRepType)(vnl_sample_uniform(0,xmax));
70  curr[1] = (CoordRepType)(vnl_sample_uniform(0,ymax));
71  m_Seeds.push_back(curr);
72  }
73  m_NumberOfSeeds = num;
74 }
75 
76 /* Set the seed points. Specify the number of seeds as "num". */
77 template <typename TCoordRepType>
78 void
80 SetSeeds(int num, SeedsIterator begin)
81 {
82  m_Seeds.clear();
83  SeedsIterator ii(begin);
84  for(int i = 0; i < num; ++i)
85  {
86  m_Seeds.push_back(*ii++);
87  }
88  m_NumberOfSeeds = num;
89 }
90 
91 /* Set the rectangle that encloses the Voronoi Diagram. */
92 template <typename TCoordRepType>
93 void
96 {
97  m_VorBoundary[0] = vorsize[0];
98  m_VorBoundary[1] = vorsize[1];
99  m_OutputVD->SetBoundary(vorsize);
100 }
101 
102 template <typename TCoordRepType>
103 void
106 {
107  m_Pxmin = vorsize[0];
108  m_Pymin = vorsize[1];
109  m_OutputVD->SetOrigin(vorsize);
110 }
111 
112 /* Compare point coordinates in the y direction. */
113 template <typename TCoordRepType>
114 bool
117 {
118  if(arg1[1]<arg2[1]) return 1;
119  else if(arg1[1]>arg2[1]) return 0;
120  else if(arg1[0]<arg2[0]) return 1;
121  else if(arg1[0]>arg2[0]) return 0;
122  else return 1;
123 }
124 
125 
126 /* Sort the seeds with their y coordinates. */
127 template <typename TCoordRepType>
128 void
131 {
132  std::sort(m_Seeds.begin(),m_Seeds.end(),comp);
133 }
134 
135 
136 /* Add seeds. Specify the number of seeds to be added as "num". */
137 template <typename TCoordRepType>
138 void
140 AddSeeds(int num, SeedsIterator begin)
141 {
142  SeedsIterator ii(begin);
143  for(int i = 0; i < num; ++i)
144  {
145  m_Seeds.push_back(*ii++);
146  }
147  m_NumberOfSeeds += num;
148 }
149 
150 /* Add one seed. */
151 template <typename TCoordRepType>
152 void
155 {
156  m_Seeds.push_back(inputSeed);
157  m_NumberOfSeeds++;
158 }
159 
160 template <typename TCoordRepType>
163 GetSeed(int SeedID)
164 {
165  PointType answer;
166  answer[0]=m_Seeds[SeedID][0];
167  answer[1]=m_Seeds[SeedID][1];
168  return answer;
169 }
170 
171 template <typename TCoordRepType>
172 void
175 {
176  SortSeeds();
177  m_OutputVD->SetSeeds(m_NumberOfSeeds, m_Seeds.begin());
178  this->GenerateVDFortune();
179  this->ConstructDiagram();
180 }
181 
182 template <typename TCoordRepType>
183 void
186 {
187  this->GenerateData();
188 }
189 
190 
194 template <typename TCoordRepType>
195 bool
198 {
199  double diffx = p1[0]-p2[0];
200  double diffy = p1[1]-p2[1];
201  return ( (diffx<-DIFF_TOLERENCE) || (diffx>DIFF_TOLERENCE)
202  || (diffy<-DIFF_TOLERENCE) || (diffy>DIFF_TOLERENCE) );
203 
204 }
205 
206 template <typename TCoordRepType>
207 bool
210 {
211  double diff = p1-p2;
212  bool save;
213  save = ( (diff<-DIFF_TOLERENCE) || (diff>DIFF_TOLERENCE) );
214  return (!save);
215 }
216 
217 template <typename TCoordRepType>
218 unsigned char
220 Pointonbnd(int VertID)
221 {
222  PointType currVert = m_OutputVD->GetVertex(VertID);
223  if(almostsame(currVert[0],m_Pxmin))
224  return 1;
225  else if(almostsame(currVert[1],m_Pymax))
226  return 2;
227  else if(almostsame(currVert[0],m_Pxmax))
228  return 3;
229  else if(almostsame(currVert[1],m_Pymin))
230  return 4;
231  else
232  return 0;
233 }
234 
235 template <typename TCoordRepType>
236 void
239 {
240  EdgeInfoDQ *rawEdges = new EdgeInfoDQ[m_NumberOfSeeds];
241 
242  m_OutputVD->Reset();
243 
244  EdgeInfo currentPtID;
245  int edges = m_OutputVD->EdgeListSize();
246 
247  EdgeInfo LRsites;
248  for (int i = 0; i < edges; i++)
249  {
250  currentPtID = m_OutputVD->GetEdgeEnd(i);
251  LRsites = m_OutputVD->GetLine(m_OutputVD->GetEdgeLineID(i));
252  rawEdges[LRsites[0]].push_back(currentPtID);
253  rawEdges[LRsites[1]].push_back(currentPtID);
254  m_OutputVD->AddCellNeighbor(LRsites);
255  }
256 
257 
258  PointType corner[4];
259  int cornerID[4];
260 
261  corner[0][0]=m_Pxmin;
262  corner[0][1]=m_Pymin;
263  cornerID[0]=m_Nvert;
264  m_Nvert++;
265  m_OutputVD->AddVert(corner[0]);
266  corner[1][0]=m_Pxmin;
267  corner[1][1]=m_Pymax;
268  cornerID[1]=m_Nvert;
269  m_Nvert++;
270  m_OutputVD->AddVert(corner[1]);
271  corner[2][0]=m_Pxmax;
272  corner[2][1]=m_Pymax;
273  cornerID[2]=m_Nvert;
274  m_Nvert++;
275  m_OutputVD->AddVert(corner[2]);
276  corner[3][0]=m_Pxmax;
277  corner[3][1]=m_Pymin;
278  cornerID[3]=m_Nvert;
279  m_Nvert++;
280  m_OutputVD->AddVert(corner[3]);
281 
282  std::list<EdgeInfo> buildEdges;
283  typename std::list<EdgeInfo>::iterator BEiter;
284  EdgeInfo curr;
285  EdgeInfo curr1;
286  EdgeInfo curr2;
287 
288  unsigned char frontbnd;
289  unsigned char backbnd;
290  std::vector<unsigned long> cellPoints;
291  for(unsigned int i = 0; i < m_NumberOfSeeds; i++)
292  {
293  buildEdges.clear();
294  curr=rawEdges[i].front();
295  rawEdges[i].pop_front();
296  buildEdges.push_back(curr);
297  EdgeInfo front=curr;
298  EdgeInfo back=curr;
299  int maxStop= static_cast< int >( rawEdges[i].size() );
300  while(!(rawEdges[i].empty()))
301  {
302  maxStop--;
303  curr=rawEdges[i].front();
304  rawEdges[i].pop_front();
305  frontbnd=Pointonbnd(front[0]);
306  backbnd=Pointonbnd(back[1]);
307  if(curr[0]==back[1])
308  {
309  buildEdges.push_back(curr);
310  back=curr;
311  }
312  else if(curr[1]==front[0])
313  {
314  buildEdges.push_front(curr);
315  front=curr;
316  }
317  else if(curr[1]==back[1])
318  {
319  curr1[1]=curr[0];
320  curr1[0]=curr[1];
321  buildEdges.push_back(curr1);
322  back=curr1;
323  }
324  else if(curr[0]==front[0])
325  {
326  curr1[0]=curr[1];
327  curr1[1]=curr[0];
328  buildEdges.push_front(curr1);
329  front=curr1;
330  }
331  else if( (frontbnd != 0) || (backbnd != 0) )
332  {
333  unsigned char cfrontbnd=Pointonbnd(curr[0]);
334  unsigned char cbackbnd=Pointonbnd(curr[1]);
335 
336  if((cfrontbnd == backbnd) &&(backbnd))
337  {
338  curr1[0]=back[1];
339  curr1[1]=curr[0];
340  buildEdges.push_back(curr1);
341  buildEdges.push_back(curr);
342  back=curr;
343  }
344  else if((cbackbnd == frontbnd)&&(frontbnd))
345  {
346  curr1[0]=curr[1];
347  curr1[1]=front[0];
348  buildEdges.push_front(curr1);
349  buildEdges.push_front(curr);
350  front=curr;
351  }
352  else if((cfrontbnd == frontbnd)&&(frontbnd))
353  {
354  curr1[0]=curr[0];
355  curr1[1]=front[0];
356  buildEdges.push_front(curr1);
357  curr1[0]=curr[1];
358  curr1[1]=curr[0];
359  buildEdges.push_front(curr1);
360  front=curr1;
361  }
362  else if((cbackbnd == backbnd)&&(backbnd))
363  {
364  curr1[0]=back[1];
365  curr1[1]=curr[1];
366  buildEdges.push_back(curr1);
367  curr1[0]=curr[1];
368  curr1[1]=curr[0];
369  buildEdges.push_back(curr1);
370  back=curr1;
371  }
372  else
373  {
374  rawEdges[i].push_back(curr);
375  }
376  }
377  else
378  {
379  rawEdges[i].push_back(curr);
380  }
381  }
382 
383  curr=buildEdges.front();
384  curr1=buildEdges.back();
385  if(curr[0] != curr1[1])
386  {
387  frontbnd=Pointonbnd(curr[0]);
388  backbnd=Pointonbnd(curr1[1]);
389  if( (frontbnd!=0) && (backbnd!=0) )
390  {
391  if(frontbnd == backbnd)
392  {
393  curr2[0]=curr1[1];
394  curr2[1]=curr[0];
395  buildEdges.push_back(curr2);
396  }
397  else if((frontbnd == backbnd+1) || (frontbnd == backbnd-3) )
398  {
399  curr2[0]=cornerID[frontbnd-1];
400  curr2[1]=curr[0];
401  buildEdges.push_front(curr2);
402  curr2[1]=curr2[0];
403  curr2[0]=curr1[1];
404  buildEdges.push_front(curr2);
405  }
406  else if((frontbnd == backbnd-1) || (frontbnd == backbnd+3) )
407  {
408  curr2[0]=cornerID[backbnd-1];
409  curr2[1]=curr[0];
410  buildEdges.push_front(curr2);
411  curr2[1]=curr2[0];
412  curr2[0]=curr1[1];
413  buildEdges.push_front(curr2);
414  }
415  else
416  {
417  itkDebugMacro(<<"Numerical problem 1"<<curr[0]<<" "<<curr1[1]);
418  }
419  }
420  }
421 
422  EdgeInfo pp;
423 
424  m_OutputVD->ClearRegion(i);
425 
426  for(BEiter = buildEdges.begin(); BEiter != buildEdges.end(); ++BEiter)
427  {
428  pp = *BEiter;
429  m_OutputVD->VoronoiRegionAddPointId(i,pp[0]);
430  }
431  m_OutputVD->BuildEdge(i);
432  }
433  m_OutputVD->InsertCells();
434 
435  delete [] rawEdges;
436 }
437 
442 template <typename TCoordRepType>
443 bool
446 {
447  FortuneEdge *e = el->m_Edge;
448  FortuneSite *topsite = e->m_Reg[1];
449 
450  bool right_of_site = ( ((*p)[0]) > (topsite->m_Coord[0]) );
451  if (right_of_site && (!(el->m_RorL)) ) return (1);
452  if ( (!right_of_site) && (el->m_RorL) ) return (0);
453  bool above;
454  bool fast;
455  if (e->m_A == 1.0)
456  {
457  double dyp = ((*p)[1]) - (topsite->m_Coord[1]);
458  double dxp = ((*p)[0]) - (topsite->m_Coord[0]);
459  fast = 0;
460  if( ((!right_of_site) && ((e->m_B)<0.0)) ||
461  (right_of_site && ((e->m_B)>=0.0)) )
462  {
463  above = ( dyp >= (e->m_B)*dxp );
464  fast = above;
465  }
466  else
467  {
468  above = ( (((*p)[0]) + ((*p)[1])*(e->m_B)) > e->m_C );
469  if(e->m_B < 0.0 ) above = !above;
470  if(!above) fast = 1;
471  }
472  if(!fast)
473  {
474  double dxs = topsite->m_Coord[0] - ((e->m_Reg[0])->m_Coord[0]);
475  above = ( ((e->m_B)*(dxp*dxp-dyp*dyp))<(dxs*dyp*(1.0+2.0*dxp/dxs+(e->m_B)*(e->m_B))) );
476  if((e->m_B) < 0.0) above = !above;
477  }
478  }
479  else
480  { // e->m_B == 1.0
481  double y1 = (e->m_C) - (e->m_A)*((*p)[0]);
482  double t1 = ((*p)[1]) -y1;
483  double t2 = ((*p)[0]) - topsite->m_Coord[0];
484  double t3 = y1 - topsite->m_Coord[1];
485  above = ( (t1*t1) > (t2*t2+t3*t3) );
486  }
487  return (el->m_RorL? (!above):above);
488 }
489 
490 
491 template <typename TCoordRepType>
492 void
495 {
496  task->m_Edge = e;
497  task->m_RorL = pm;
498  task->m_Next = NULL;
499  task->m_Vert = NULL;
500 }
501 
502 
503 template <typename TCoordRepType>
504 void
507 {
508  while( (m_PQHash[m_PQmin].m_Next) == NULL)
509  {
510  m_PQmin += 1;
511  }
512  (*answer)[0] = m_PQHash[m_PQmin].m_Next->m_Vert->m_Coord[0];
513  (*answer)[1] = m_PQHash[m_PQmin].m_Next->m_Ystar;
514 }
515 
516 
517 template <typename TCoordRepType>
518 void
521 {
522  FortuneHalfEdge *last;
523  if( (task->m_Vert) != NULL)
524  {
525  last = &(m_PQHash[PQbucket(task)]);
526  while ((last->m_Next) != task)
527  last = last->m_Next;
528  last->m_Next = (task->m_Next);
529  m_PQcount--;
530  task->m_Vert = NULL;
531  }
532 }
533 
534 template <typename TCoordRepType>
535 void
538 {
539  (task->m_Left)->m_Right = task->m_Right;
540  (task->m_Right)->m_Left = task->m_Left;
541  task->m_Edge = &(m_DELETED);
542 }
543 
544 
545 template <typename TCoordRepType>
546 int
549 {
550  int bucket;
551  bucket = (int) ((task->m_Ystar - m_Pymin)/m_Deltay * m_PQhashsize);
552  if(bucket < 0)
553  {
554  bucket = 0;
555  }
556  if(bucket >= static_cast<int>(m_PQhashsize))
557  {
558  bucket = m_PQhashsize -1;
559  }
560  if(bucket < static_cast<int>(m_PQmin))
561  {
562  m_PQmin = bucket;
563  }
564  return(bucket);
565 }
566 
567 template <typename TCoordRepType>
568 void
570 insertPQ(FortuneHalfEdge *he, FortuneSite *v, double offset)
571 {
572  he->m_Vert = v;
573  he->m_Ystar = (v->m_Coord[1]) + offset;
574  FortuneHalfEdge *last = &(m_PQHash[PQbucket(he)]);
575  FortuneHalfEdge *enext;
576 
577  while( ((enext = (last->m_Next)) != NULL) &&
578  ( ((he->m_Ystar) > (enext->m_Ystar)) ||
579  ( ((he->m_Ystar) == (enext->m_Ystar)) &&
580  ( (v->m_Coord[0])> (enext->m_Vert->m_Coord[0]) ))))
581  {last = enext;}
582  he->m_Next = (last->m_Next);
583  last->m_Next = he;
584  m_PQcount += 1;
585 }
586 
587 template <typename TCoordRepType>
588 double
591 {
592  double dx = (s1->m_Coord[0])-(s2->m_Coord[0]);
593  double dy = (s1->m_Coord[1])-(s2->m_Coord[1]);
594  return(vcl_sqrt(dx*dx+dy*dy));
595 }
596 
597 template <typename TCoordRepType>
600 ELgethash( int b)
601 {
602  if( (b<0) || (b>=static_cast<int>(m_ELhashsize)) )
603  {
604  return (NULL);
605  }
606  FortuneHalfEdge *he = m_ELHash[b];
607  if(he==NULL)
608  {
609  return (he);
610  }
611  if(he->m_Edge == NULL)
612  {
613  return (he);
614  }
615  if((he->m_Edge) != (&m_DELETED))
616  {
617  return (he);
618  }
619  m_ELHash[b] = NULL;
620 
621  return (NULL);
622 }
623 
624 
625 template <typename TCoordRepType>
629 {
630  int i;
631  int bucket = (int)( (((*p)[0]) - m_Pxmin)/m_Deltax * m_ELhashsize );
632  if(bucket < 0)
633  {
634  bucket = 0;
635  }
636  if(bucket >= static_cast<int>(m_ELhashsize))
637  {
638  bucket = static_cast<int>(m_ELhashsize) - 1;
639  }
640  FortuneHalfEdge *he = ELgethash(bucket);
641  if(he == NULL)
642  {
643  for(i = 1; 1; i++)
644  {
645  if( (he=ELgethash(bucket-i)) != NULL) break;
646  if( (he=ELgethash(bucket+i)) != NULL) break;
647  }
648  }
649 
650  if( (he==(&m_ELleftend)) || ((he!=(&m_ELrightend)) && right_of(he,p)) )
651  {
652  do
653  {
654  he = he->m_Right;
655  }
656  while ( (he!=(&m_ELrightend)) && (right_of(he,p)) );
657  he = he->m_Left;
658  }
659  else
660  {
661  do
662  {
663  he = he->m_Left;
664  }
665  while ( (he!=(&m_ELleftend)) && (!right_of(he,p)) );
666  }
667 
668  if( (bucket>0) && (bucket<static_cast<int>(m_ELhashsize)-1) )
669  {
670  m_ELHash[bucket] = he;
671  }
672  return (he);
673 }
674 
675 template <typename TCoordRepType>
679 {
680  if( (he->m_Edge) == NULL )
681  {
682  return(m_BottomSite);
683  }
684  else if(he->m_RorL)
685  {
686  return(he->m_Edge->m_Reg[0]);
687  }
688  else
689  {
690  return(he->m_Edge->m_Reg[1]);
691  }
692 }
693 
694 template <typename TCoordRepType>
698 {
699  if( (he->m_Edge) == NULL )
700  {
701  return(m_BottomSite);
702  }
703  else if(he->m_RorL)
704  {
705  return(he->m_Edge->m_Reg[1]);
706  }
707  else
708  {
709  return(he->m_Edge->m_Reg[0]);
710  }
711 }
712 
713 
714 template <typename TCoordRepType>
715 void
718 {
719  lnew->m_Left = lbase;
720  lnew->m_Right = lbase->m_Right;
721  (lbase->m_Right)->m_Left = lnew;
722  lbase->m_Right = lnew;
723 }
724 
725 template <typename TCoordRepType>
726 void
729 {
730  answer->m_Reg[0] = s1;
731  answer->m_Reg[1] = s2;
732  answer->m_Ep[0] = NULL;
733  answer->m_Ep[1] = NULL;
734 
735  double dx = (s2->m_Coord[0]) - (s1->m_Coord[0]);
736  double dy = (s2->m_Coord[1]) - (s1->m_Coord[1]);
737  double adx = (dx>0)?dx:-dx;
738  double ady = (dy>0)?dy:-dy;
739 
740  answer->m_C = (s1->m_Coord[0])*dx + (s1->m_Coord[1])*dy + (dx*dx+dy*dy)*0.5;
741  if(adx > ady)
742  {
743  answer->m_A = 1.0;
744  answer->m_B = dy/dx;
745  answer->m_C /= dx;
746  }
747  else
748  {
749  answer->m_A = dx/dy;
750  answer->m_B = 1.0;
751  answer->m_C /= dy;
752  }
753  answer->m_Edgenbr = m_Nedges;
754  m_Nedges++;
755  Point<int, 2> outline;
756  outline[0] = answer->m_Reg[0]->m_Sitenbr;
757  outline[1] = answer->m_Reg[1]->m_Sitenbr;
758  m_OutputVD->AddLine(outline);
759 
760 }
761 
762 
763 template <typename TCoordRepType>
764 void
767 {
768  FortuneEdge *e1 = el1->m_Edge;
769  FortuneEdge *e2 = el2->m_Edge;
770  FortuneHalfEdge *saveHE;
771  FortuneEdge *saveE;
772 
773  if(e1 == NULL)
774  {
775  newV->m_Sitenbr = -1;
776  return;
777  }
778  if(e2 == NULL)
779  {
780  newV->m_Sitenbr = -2;
781  return;
782  }
783  if( (e1->m_Reg[1]) == (e2->m_Reg[1]) )
784  {
785  newV->m_Sitenbr = -3;
786  return;
787  }
788 
789  double d = (e1->m_A)*(e2->m_B) - (e1->m_B)*(e2->m_A);
790 
791  if ( (d>-NUMERIC_TOLERENCE) && (d<NUMERIC_TOLERENCE) )
792  {
793  newV->m_Sitenbr = -4;
794  return;
795  }
796 
797  double xmeet = ( (e1->m_C)*(e2->m_B) - (e2->m_C)*(e1->m_B) )/d;
798  double ymeet = ( (e2->m_C)*(e1->m_A) - (e1->m_C)*(e2->m_A) )/d;
799 
800  if( comp(e1->m_Reg[1]->m_Coord, e2->m_Reg[1]->m_Coord) )
801  {
802  saveHE = el1;
803  saveE = e1;
804  }
805  else
806  {
807  saveHE = el2;
808  saveE = e2;
809  }
810 
811  bool right_of_site = (xmeet >= (saveE->m_Reg[1]->m_Coord[0]) );
812  if( (right_of_site && (!(saveHE->m_RorL))) ||
813  ( (!right_of_site) && (saveHE->m_RorL)) )
814  {
815  newV->m_Sitenbr = -4;
816  return;
817  }
818 
819  newV->m_Coord[0] = xmeet;
820  newV->m_Coord[1] = ymeet;
821  newV->m_Sitenbr = -5;
822 }
823 
824 template <typename TCoordRepType>
827 getPQmin(void)
828 {
829  FortuneHalfEdge *curr = m_PQHash[m_PQmin].m_Next;
830  m_PQHash[m_PQmin].m_Next = curr->m_Next;
831  m_PQcount--;
832  return(curr);
833 }
834 
835 template <typename TCoordRepType>
836 void
839 {
840 /* clip line */
841  FortuneSite *s1;
842  FortuneSite *s2;
843  double x1,y1,x2,y2;
844  if( ((task->m_A) == 1.0) && ((task->m_B) >= 0.0) )
845  {
846  s1 = task->m_Ep[1];
847  s2 = task->m_Ep[0];
848  }
849  else
850  {
851  s2 = task->m_Ep[1];
852  s1 = task->m_Ep[0];
853  }
854 
855  int id1;
856  int id2;
857  if( (task->m_A) == 1.0)
858  {
859  if( (s1 != NULL) && ((s1->m_Coord[1]) >m_Pymin) )
860  {
861  y1 = s1->m_Coord[1];
862  if(y1 > m_Pymax)
863  {
864  return;
865  }
866  x1 = s1->m_Coord[0];
867  id1 = s1->m_Sitenbr;
868  }
869  else
870  {
871  y1 = m_Pymin;
872  x1 = (task->m_C) - (task->m_B)*y1;
873  id1 = -1;
874  }
875 
876  if ( (s2 != NULL) && ((s2->m_Coord[1]) <m_Pymax) )
877  {
878  y2 = s2->m_Coord[1];
879  if(y2 < m_Pymin)
880  return;
881  x2 = s2->m_Coord[0];
882  id2 = s2->m_Sitenbr;
883  }
884  else
885  {
886  y2 = m_Pymax;
887  x2 = (task->m_C) - (task->m_B)*y2;
888  id2 = -1;
889  }
890 
891  if( (x1>m_Pxmax) && (x2>m_Pxmax) )
892  {
893  return;
894  }
895  if( (x1<m_Pxmin) && (x2<m_Pxmin) )
896  {
897  return;
898  }
899  if(x1 > m_Pxmax)
900  {
901  x1 = m_Pxmax;
902  y1 = ((task->m_C)-x1)/(task->m_B);
903  id1 = -1;
904  }
905  if(x1 <m_Pxmin)
906  {
907  x1 = m_Pxmin;
908  y1 = ((task->m_C)-x1)/(task->m_B);
909  id1 = -1;
910  }
911  if(x2 > m_Pxmax)
912  {
913  x2 = m_Pxmax;
914  y2 = ((task->m_C)-x2)/(task->m_B);
915  id2 = -1;
916  }
917  if(x2 <m_Pxmin)
918  {
919  x2 = m_Pxmin;
920  y2 = ((task->m_C)-x2)/(task->m_B);
921  id2 = -1;
922  }
923  }
924  else
925  {
926  if( (s1 != NULL) && ((s1->m_Coord[0]) >m_Pxmin) )
927  {
928  x1 = s1->m_Coord[0];
929  if(x1 > m_Pxmax)
930  {
931  return;
932  }
933  y1 = s1->m_Coord[1];
934  id1 = s1->m_Sitenbr;
935  }
936  else
937  {
938  x1 = m_Pxmin;
939  y1 = (task->m_C) - (task->m_A)*x1;
940  id1 = -1;
941  }
942  if ( (s2 != NULL) && ((s2->m_Coord[0]) <m_Pxmax) )
943  {
944  x2 = s2->m_Coord[0];
945  if(x2 < m_Pxmin)
946  return;
947  y2 = s2->m_Coord[1];
948  id2 = s2->m_Sitenbr;
949  }
950  else
951  {
952  x2 = m_Pxmax;
953  y2 = (task->m_C) - (task->m_A)*x2;
954  id2 = -1;
955  }
956  if( (y1>m_Pymax) && (y2>m_Pymax) )
957  {
958  return;
959  }
960  if( (y1<m_Pymin) && (y2<m_Pymin) )
961  return;
962  if(y1 > m_Pymax)
963  {
964  y1 = m_Pymax;
965  x1 = ((task->m_C)-y1)/(task->m_A);
966  id1 = -1;
967  }
968  if(y1 <m_Pymin)
969  {
970  y1 = m_Pymin;
971  x1 = ((task->m_C)-y1)/(task->m_A);
972  id1 = -1;
973  }
974  if(y2 > m_Pymax)
975  {
976  y2 = m_Pymax;
977  x2 = ((task->m_C)-y2)/(task->m_A);
978  id2 = -1;
979  }
980  if(y2 <m_Pymin)
981  {
982  y2 = m_Pymin;
983  x2 = ((task->m_C)-y2)/(task->m_A);
984  id2 = -1;
985  }
986  }
987 
988  VoronoiEdge newInfo;
989  newInfo.m_Left[0] = x1;
990  newInfo.m_Left[1] = y1;
991  newInfo.m_Right[0] = x2;
992  newInfo.m_Right[1] = y2;
993  newInfo.m_LineID = task->m_Edgenbr;
994 
995  if(id1>-1)
996  {
997  newInfo.m_LeftID = id1;
998  }
999  else
1000  {
1001  newInfo.m_LeftID = m_Nvert;
1002  m_Nvert++;
1003  PointType newv;
1004  newv[0]=x1;
1005  newv[1]=y1;
1006  m_OutputVD->AddVert(newv);
1007  }
1008 
1009  if(id2>-1)
1010  {
1011  newInfo.m_RightID = id2;
1012  }
1013  else
1014  {
1015  newInfo.m_RightID = m_Nvert;
1016  m_Nvert++;
1017  PointType newv;
1018  newv[0]=x2;
1019  newv[1]=y2;
1020  m_OutputVD->AddVert(newv);
1021  }
1022  m_OutputVD->AddEdge(newInfo);
1023 }
1024 
1025 
1026 template <typename TCoordRepType>
1027 void
1029 makeEndPoint(FortuneEdge *task, bool lr, FortuneSite *ends)
1030 {
1031  task->m_Ep[lr] = ends;
1032  if ((task->m_Ep[1-lr]) == NULL)
1033  return;
1034 
1035  clip_line(task);
1036 
1037 }
1038 
1039 
1040 template <typename TCoordRepType>
1041 void
1044 {
1045 
1046  unsigned int i;
1047 
1048  /* Build SeedSites. */
1049  m_SeedSites.resize(m_NumberOfSeeds);
1050  for(i = 0; i < m_NumberOfSeeds; i++)
1051  {
1052  m_SeedSites[i].m_Coord = m_Seeds[i];
1053  m_SeedSites[i].m_Sitenbr = i;
1054  }
1055 /* Initialize Boundary. */
1056  m_Pxmax = m_VorBoundary[0];
1057  m_Pymax = m_VorBoundary[1];
1058 
1059  m_Deltay = m_Pymax - m_Pymin;
1060  m_Deltax = m_Pxmax - m_Pxmin;
1061  m_SqrtNSites = vcl_sqrt((float) (m_NumberOfSeeds + 4));
1062 
1063  /* Initialize outputLists. */
1064  m_Nedges = 0;
1065  m_Nvert = 0;
1066  m_OutputVD->LineListClear();
1067  m_OutputVD->EdgeListClear();
1068  m_OutputVD->VertexListClear();
1069 
1070  /* Initialize the Hash Table for Circle Event and Point Event. */
1071  m_PQcount = 0;
1072  m_PQmin = 0;
1073  m_PQhashsize = (int)(4 * m_SqrtNSites);
1074  m_PQHash.resize(m_PQhashsize);
1075  for (i = 0; i < m_PQhashsize; i++)
1076  {
1077  m_PQHash[i].m_Next = NULL;
1078  }
1079  m_ELhashsize = (int)(2 * m_SqrtNSites);
1080  m_ELHash.resize(m_ELhashsize);
1081  for (i = 0; i < m_ELhashsize; i++)
1082  {
1083  m_ELHash[i] = NULL;
1084  }
1085  createHalfEdge(&(m_ELleftend), NULL, 0);
1086  createHalfEdge(&(m_ELrightend), NULL, 0);
1087  m_ELleftend.m_Left = NULL;
1088  m_ELleftend.m_Right = &(m_ELrightend);
1089  m_ELrightend.m_Left = &(m_ELleftend);
1090  m_ELrightend.m_Right = NULL;
1091  m_ELHash[0] = &(m_ELleftend);
1092  m_ELHash[m_ELhashsize - 1] = &(m_ELrightend);
1093 
1094  m_BottomSite = &(m_SeedSites[0]);
1095  FortuneSite *currentSite = &(m_SeedSites[1]);
1096 
1097  PointType currentCircle;
1098  currentCircle.Fill(0.0);
1099  FortuneHalfEdge *leftHalfEdge;
1100  FortuneHalfEdge *rightHalfEdge;
1101  FortuneHalfEdge *left2HalfEdge;
1102  FortuneHalfEdge *right2HalfEdge;
1103  FortuneHalfEdge *newHE;
1104  FortuneSite *findSite;
1105  FortuneSite *topSite;
1106  FortuneSite *saveSite;
1107  FortuneEdge *newEdge;
1108  FortuneSite *meetSite;
1109  FortuneSite *newVert;
1110  bool saveBool;
1111 
1112  std::vector<FortuneHalfEdge> HEpool;
1113  std::vector<FortuneEdge> Edgepool;
1114  std::vector<FortuneSite> Sitepool;
1115  HEpool.resize(5*m_NumberOfSeeds);
1116  Edgepool.resize(5*m_NumberOfSeeds);
1117  Sitepool.resize(5*m_NumberOfSeeds);
1118 
1119  int HEid = 0;
1120  int Edgeid = 0;
1121  int Siteid = 0;
1122 
1123  i = 2;
1124  bool ok = 1;
1125  while(ok)
1126  {
1127  if(m_PQcount != 0)
1128  {
1129  PQshowMin(&currentCircle);
1130  }
1131  if( (i <= m_NumberOfSeeds) && ((m_PQcount == 0) || comp(currentSite->m_Coord, currentCircle)) )
1132  {
1133  /* Handling Site Event. */
1134  leftHalfEdge = findLeftHE(&(currentSite->m_Coord));
1135  rightHalfEdge = leftHalfEdge->m_Right;
1136 
1137  findSite = getRightReg(leftHalfEdge);
1138 
1139  bisect(&(Edgepool[Edgeid]),findSite, currentSite);
1140  newEdge = &(Edgepool[Edgeid]);
1141  Edgeid++;
1142 
1143  createHalfEdge( &(HEpool[HEid]), newEdge, 0);
1144  newHE = &(HEpool[HEid]);
1145  HEid++;
1146 
1147  insertEdgeList(leftHalfEdge, newHE);
1148 
1149  intersect(&(Sitepool[Siteid]),leftHalfEdge, newHE);
1150  meetSite = &(Sitepool[Siteid]);
1151 
1152  if((meetSite->m_Sitenbr) == -5)
1153  {
1154  deletePQ(leftHalfEdge);
1155  insertPQ(leftHalfEdge, meetSite, dist(meetSite, currentSite));
1156  Siteid++;
1157  }
1158 
1159  leftHalfEdge = newHE;
1160  createHalfEdge( &(HEpool[HEid]), newEdge, 1);
1161  newHE = &(HEpool[HEid]);
1162  HEid++;
1163 
1164  insertEdgeList(leftHalfEdge, newHE);
1165 
1166  intersect(&(Sitepool[Siteid]),newHE, rightHalfEdge);
1167  meetSite = &(Sitepool[Siteid]);
1168  if((meetSite->m_Sitenbr) == -5)
1169  {
1170  Siteid++;
1171  insertPQ(newHE, meetSite, dist(meetSite, currentSite));
1172  }
1173  if (i < m_SeedSites.size())
1174  {
1175  currentSite = &(m_SeedSites[i]);
1176  }
1177  i++;
1178  }
1179  else if(m_PQcount != 0)
1180  {
1181  /* Handling Circle Event. */
1182 
1183  leftHalfEdge = getPQmin();
1184  left2HalfEdge = leftHalfEdge->m_Left;
1185  rightHalfEdge = leftHalfEdge->m_Right;
1186  right2HalfEdge = rightHalfEdge->m_Right;
1187  findSite = getLeftReg(leftHalfEdge);
1188  topSite = getRightReg(rightHalfEdge);
1189 
1190  newVert = leftHalfEdge->m_Vert;
1191  newVert->m_Sitenbr = m_Nvert;
1192  m_Nvert++;
1193  m_OutputVD->AddVert(newVert->m_Coord);
1194 
1195  makeEndPoint(leftHalfEdge->m_Edge, leftHalfEdge->m_RorL, newVert);
1196  makeEndPoint(rightHalfEdge->m_Edge, rightHalfEdge->m_RorL, newVert);
1197  deleteEdgeList(leftHalfEdge);
1198  deletePQ(rightHalfEdge);
1199  deleteEdgeList(rightHalfEdge);
1200 
1201  saveBool = 0;
1202  if( (findSite->m_Coord[1]) > (topSite->m_Coord[1]) )
1203  {
1204  saveSite = findSite;
1205  findSite = topSite;
1206  topSite = saveSite;
1207  saveBool = 1;
1208  }
1209 
1210  bisect(&(Edgepool[Edgeid]),findSite, topSite);
1211  newEdge = &(Edgepool[Edgeid]);
1212  Edgeid++;
1213 
1214  createHalfEdge( &(HEpool[HEid]), newEdge, saveBool);
1215  newHE = &(HEpool[HEid]);
1216  HEid++;
1217 
1218  insertEdgeList(left2HalfEdge, newHE);
1219  makeEndPoint(newEdge, 1-saveBool, newVert);
1220 
1221  intersect(&(Sitepool[Siteid]),left2HalfEdge, newHE);
1222  meetSite = &(Sitepool[Siteid]);
1223 
1224  if((meetSite->m_Sitenbr) == -5)
1225  {
1226  Siteid++;
1227  deletePQ(left2HalfEdge);
1228  insertPQ(left2HalfEdge, meetSite, dist(meetSite, findSite));
1229  }
1230 
1231  intersect(&(Sitepool[Siteid]),newHE, right2HalfEdge);
1232  meetSite = &(Sitepool[Siteid]);
1233  if((meetSite->m_Sitenbr) == -5)
1234  {
1235  Siteid++;
1236  insertPQ(newHE, meetSite, dist(meetSite, findSite));
1237  }
1238  }
1239  else
1240  {
1241  ok = 0;
1242  }
1243  }
1244 
1245  for( (leftHalfEdge=m_ELleftend.m_Right);
1246  (leftHalfEdge != (&m_ELrightend));
1247  (leftHalfEdge=(leftHalfEdge->m_Right)) )
1248  {
1249  newEdge = leftHalfEdge->m_Edge;
1250  clip_line(newEdge);
1251  }
1252 }
1253 
1254 }//end namespace
1255 
1256 #endif

Generated at Sun May 19 2013 00:13:50 for Orfeo Toolbox with doxygen 1.8.3.1