17 #ifndef __itkVoronoiDiagram2DGenerator_txx
18 #define __itkVoronoiDiagram2DGenerator_txx
23 #include "vnl/vnl_sample.h"
31 template <
typename TCoordRepType>
38 m_OutputVD=this->GetOutput();
41 template <
typename TCoordRepType>
47 template <
typename TCoordRepType>
52 Superclass::PrintSelf(os, indent);
53 os << indent <<
"Number Of Seeds: "
54 << m_NumberOfSeeds << std::endl;
58 template <
typename TCoordRepType>
65 double ymax = (double)(m_VorBoundary[1]);
66 double xmax = (double)(m_VorBoundary[0]);
67 for(
int i = 0; i < num; ++i)
71 m_Seeds.push_back(curr);
73 m_NumberOfSeeds = num;
77 template <
typename TCoordRepType>
84 for(
int i = 0; i < num; ++i)
86 m_Seeds.push_back(*ii++);
88 m_NumberOfSeeds = num;
92 template <
typename TCoordRepType>
97 m_VorBoundary[0] = vorsize[0];
98 m_VorBoundary[1] = vorsize[1];
99 m_OutputVD->SetBoundary(vorsize);
102 template <
typename TCoordRepType>
107 m_Pxmin = vorsize[0];
108 m_Pymin = vorsize[1];
109 m_OutputVD->SetOrigin(vorsize);
113 template <
typename TCoordRepType>
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;
127 template <
typename TCoordRepType>
132 std::sort(m_Seeds.begin(),m_Seeds.end(),comp);
137 template <
typename TCoordRepType>
143 for(
int i = 0; i < num; ++i)
145 m_Seeds.push_back(*ii++);
147 m_NumberOfSeeds += num;
151 template <
typename TCoordRepType>
156 m_Seeds.push_back(inputSeed);
160 template <
typename TCoordRepType>
166 answer[0]=m_Seeds[SeedID][0];
167 answer[1]=m_Seeds[SeedID][1];
171 template <
typename TCoordRepType>
177 m_OutputVD->SetSeeds(m_NumberOfSeeds, m_Seeds.begin());
178 this->GenerateVDFortune();
179 this->ConstructDiagram();
182 template <
typename TCoordRepType>
187 this->GenerateData();
194 template <
typename TCoordRepType>
199 double diffx = p1[0]-p2[0];
200 double diffy = p1[1]-p2[1];
206 template <
typename TCoordRepType>
217 template <
typename TCoordRepType>
222 PointType currVert = m_OutputVD->GetVertex(VertID);
223 if(almostsame(currVert[0],m_Pxmin))
225 else if(almostsame(currVert[1],m_Pymax))
227 else if(almostsame(currVert[0],m_Pxmax))
229 else if(almostsame(currVert[1],m_Pymin))
235 template <
typename TCoordRepType>
245 int edges = m_OutputVD->EdgeListSize();
248 for (
int i = 0; i < edges; i++)
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);
261 corner[0][0]=m_Pxmin;
262 corner[0][1]=m_Pymin;
265 m_OutputVD->AddVert(corner[0]);
266 corner[1][0]=m_Pxmin;
267 corner[1][1]=m_Pymax;
270 m_OutputVD->AddVert(corner[1]);
271 corner[2][0]=m_Pxmax;
272 corner[2][1]=m_Pymax;
275 m_OutputVD->AddVert(corner[2]);
276 corner[3][0]=m_Pxmax;
277 corner[3][1]=m_Pymin;
280 m_OutputVD->AddVert(corner[3]);
282 std::list<EdgeInfo> buildEdges;
283 typename std::list<EdgeInfo>::iterator BEiter;
288 unsigned char frontbnd;
289 unsigned char backbnd;
290 std::vector<unsigned long> cellPoints;
291 for(
unsigned int i = 0; i < m_NumberOfSeeds; i++)
294 curr=rawEdges[i].front();
295 rawEdges[i].pop_front();
296 buildEdges.push_back(curr);
299 int maxStop=
static_cast< int >( rawEdges[i].size() );
300 while(!(rawEdges[i].empty()))
303 curr=rawEdges[i].front();
304 rawEdges[i].pop_front();
305 frontbnd=Pointonbnd(front[0]);
306 backbnd=Pointonbnd(back[1]);
309 buildEdges.push_back(curr);
312 else if(curr[1]==front[0])
314 buildEdges.push_front(curr);
317 else if(curr[1]==back[1])
321 buildEdges.push_back(curr1);
324 else if(curr[0]==front[0])
328 buildEdges.push_front(curr1);
331 else if( (frontbnd != 0) || (backbnd != 0) )
333 unsigned char cfrontbnd=Pointonbnd(curr[0]);
334 unsigned char cbackbnd=Pointonbnd(curr[1]);
336 if((cfrontbnd == backbnd) &&(backbnd))
340 buildEdges.push_back(curr1);
341 buildEdges.push_back(curr);
344 else if((cbackbnd == frontbnd)&&(frontbnd))
348 buildEdges.push_front(curr1);
349 buildEdges.push_front(curr);
352 else if((cfrontbnd == frontbnd)&&(frontbnd))
356 buildEdges.push_front(curr1);
359 buildEdges.push_front(curr1);
362 else if((cbackbnd == backbnd)&&(backbnd))
366 buildEdges.push_back(curr1);
369 buildEdges.push_back(curr1);
374 rawEdges[i].push_back(curr);
379 rawEdges[i].push_back(curr);
383 curr=buildEdges.front();
384 curr1=buildEdges.back();
385 if(curr[0] != curr1[1])
387 frontbnd=Pointonbnd(curr[0]);
388 backbnd=Pointonbnd(curr1[1]);
389 if( (frontbnd!=0) && (backbnd!=0) )
391 if(frontbnd == backbnd)
395 buildEdges.push_back(curr2);
397 else if((frontbnd == backbnd+1) || (frontbnd == backbnd-3) )
399 curr2[0]=cornerID[frontbnd-1];
401 buildEdges.push_front(curr2);
404 buildEdges.push_front(curr2);
406 else if((frontbnd == backbnd-1) || (frontbnd == backbnd+3) )
408 curr2[0]=cornerID[backbnd-1];
410 buildEdges.push_front(curr2);
413 buildEdges.push_front(curr2);
417 itkDebugMacro(<<
"Numerical problem 1"<<curr[0]<<
" "<<curr1[1]);
424 m_OutputVD->ClearRegion(i);
426 for(BEiter = buildEdges.begin(); BEiter != buildEdges.end(); ++BEiter)
429 m_OutputVD->VoronoiRegionAddPointId(i,pp[0]);
431 m_OutputVD->BuildEdge(i);
433 m_OutputVD->InsertCells();
442 template <
typename TCoordRepType>
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);
457 double dyp = ((*p)[1]) - (topsite->
m_Coord[1]);
458 double dxp = ((*p)[0]) - (topsite->
m_Coord[0]);
460 if( ((!right_of_site) && ((e->
m_B)<0.0)) ||
461 (right_of_site && ((e->
m_B)>=0.0)) )
463 above = ( dyp >= (e->
m_B)*dxp );
468 above = ( (((*p)[0]) + ((*p)[1])*(e->
m_B)) > e->
m_C );
469 if(e->
m_B < 0.0 ) above = !above;
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;
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) );
487 return (el->
m_RorL? (!above):above);
491 template <
typename TCoordRepType>
503 template <
typename TCoordRepType>
508 while( (m_PQHash[m_PQmin].m_Next) ==
NULL)
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;
517 template <
typename TCoordRepType>
525 last = &(m_PQHash[PQbucket(task)]);
526 while ((last->
m_Next) != task)
534 template <
typename TCoordRepType>
541 task->
m_Edge = &(m_DELETED);
545 template <
typename TCoordRepType>
551 bucket = (int) ((task->
m_Ystar - m_Pymin)/m_Deltay * m_PQhashsize);
556 if(bucket >= static_cast<int>(m_PQhashsize))
558 bucket = m_PQhashsize -1;
560 if(bucket < static_cast<int>(m_PQmin))
567 template <
typename TCoordRepType>
587 template <
typename TCoordRepType>
594 return(vcl_sqrt(dx*dx+dy*dy));
597 template <
typename TCoordRepType>
602 if( (b<0) || (b>=static_cast<int>(m_ELhashsize)) )
615 if((he->
m_Edge) != (&m_DELETED))
625 template <
typename TCoordRepType>
631 int bucket = (int)( (((*p)[0]) - m_Pxmin)/m_Deltax * m_ELhashsize );
636 if(bucket >= static_cast<int>(m_ELhashsize))
638 bucket =
static_cast<int>(m_ELhashsize) - 1;
645 if( (he=ELgethash(bucket-i)) !=
NULL)
break;
646 if( (he=ELgethash(bucket+i)) !=
NULL)
break;
650 if( (he==(&m_ELleftend)) || ((he!=(&m_ELrightend)) && right_of(he,p)) )
656 while ( (he!=(&m_ELrightend)) && (right_of(he,p)) );
665 while ( (he!=(&m_ELleftend)) && (!right_of(he,p)) );
668 if( (bucket>0) && (bucket<static_cast<int>(m_ELhashsize)-1) )
670 m_ELHash[bucket] = he;
675 template <
typename TCoordRepType>
682 return(m_BottomSite);
694 template <
typename TCoordRepType>
701 return(m_BottomSite);
714 template <
typename TCoordRepType>
721 (lbase->
m_Right)->m_Left = lnew;
725 template <
typename TCoordRepType>
730 answer->
m_Reg[0] = s1;
731 answer->
m_Reg[1] = s2;
737 double adx = (dx>0)?dx:-dx;
738 double ady = (dy>0)?dy:-dy;
758 m_OutputVD->AddLine(outline);
763 template <
typename TCoordRepType>
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;
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)) )
824 template <
typename TCoordRepType>
835 template <
typename TCoordRepType>
844 if( ((task->
m_A) == 1.0) && ((task->
m_B) >= 0.0) )
857 if( (task->
m_A) == 1.0)
872 x1 = (task->
m_C) - (task->
m_B)*y1;
887 x2 = (task->
m_C) - (task->
m_B)*y2;
891 if( (x1>m_Pxmax) && (x2>m_Pxmax) )
895 if( (x1<m_Pxmin) && (x2<m_Pxmin) )
902 y1 = ((task->
m_C)-x1)/(task->
m_B);
908 y1 = ((task->
m_C)-x1)/(task->
m_B);
914 y2 = ((task->
m_C)-x2)/(task->
m_B);
920 y2 = ((task->
m_C)-x2)/(task->
m_B);
939 y1 = (task->
m_C) - (task->
m_A)*x1;
953 y2 = (task->
m_C) - (task->
m_A)*x2;
956 if( (y1>m_Pymax) && (y2>m_Pymax) )
960 if( (y1<m_Pymin) && (y2<m_Pymin) )
965 x1 = ((task->
m_C)-y1)/(task->
m_A);
971 x1 = ((task->
m_C)-y1)/(task->
m_A);
977 x2 = ((task->
m_C)-y2)/(task->
m_A);
983 x2 = ((task->
m_C)-y2)/(task->
m_A);
1006 m_OutputVD->AddVert(newv);
1020 m_OutputVD->AddVert(newv);
1022 m_OutputVD->AddEdge(newInfo);
1026 template <
typename TCoordRepType>
1031 task->
m_Ep[lr] = ends;
1040 template <
typename TCoordRepType>
1049 m_SeedSites.resize(m_NumberOfSeeds);
1050 for(i = 0; i < m_NumberOfSeeds; i++)
1052 m_SeedSites[i].m_Coord = m_Seeds[i];
1053 m_SeedSites[i].m_Sitenbr = i;
1056 m_Pxmax = m_VorBoundary[0];
1057 m_Pymax = m_VorBoundary[1];
1059 m_Deltay = m_Pymax - m_Pymin;
1060 m_Deltax = m_Pxmax - m_Pxmin;
1061 m_SqrtNSites = vcl_sqrt((
float) (m_NumberOfSeeds + 4));
1066 m_OutputVD->LineListClear();
1067 m_OutputVD->EdgeListClear();
1068 m_OutputVD->VertexListClear();
1073 m_PQhashsize = (int)(4 * m_SqrtNSites);
1074 m_PQHash.resize(m_PQhashsize);
1075 for (i = 0; i < m_PQhashsize; i++)
1077 m_PQHash[i].m_Next =
NULL;
1079 m_ELhashsize = (int)(2 * m_SqrtNSites);
1080 m_ELHash.resize(m_ELhashsize);
1081 for (i = 0; i < m_ELhashsize; i++)
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);
1094 m_BottomSite = &(m_SeedSites[0]);
1098 currentCircle.
Fill(0.0);
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);
1129 PQshowMin(¤tCircle);
1131 if( (i <= m_NumberOfSeeds) && ((m_PQcount == 0) || comp(currentSite->
m_Coord, currentCircle)) )
1134 leftHalfEdge = findLeftHE(&(currentSite->
m_Coord));
1135 rightHalfEdge = leftHalfEdge->
m_Right;
1137 findSite = getRightReg(leftHalfEdge);
1139 bisect(&(Edgepool[Edgeid]),findSite, currentSite);
1140 newEdge = &(Edgepool[Edgeid]);
1143 createHalfEdge( &(HEpool[HEid]), newEdge, 0);
1144 newHE = &(HEpool[HEid]);
1147 insertEdgeList(leftHalfEdge, newHE);
1149 intersect(&(Sitepool[Siteid]),leftHalfEdge, newHE);
1150 meetSite = &(Sitepool[Siteid]);
1154 deletePQ(leftHalfEdge);
1155 insertPQ(leftHalfEdge, meetSite, dist(meetSite, currentSite));
1159 leftHalfEdge = newHE;
1160 createHalfEdge( &(HEpool[HEid]), newEdge, 1);
1161 newHE = &(HEpool[HEid]);
1164 insertEdgeList(leftHalfEdge, newHE);
1166 intersect(&(Sitepool[Siteid]),newHE, rightHalfEdge);
1167 meetSite = &(Sitepool[Siteid]);
1171 insertPQ(newHE, meetSite, dist(meetSite, currentSite));
1173 if (i < m_SeedSites.size())
1175 currentSite = &(m_SeedSites[i]);
1179 else if(m_PQcount != 0)
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);
1190 newVert = leftHalfEdge->
m_Vert;
1193 m_OutputVD->AddVert(newVert->
m_Coord);
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);
1204 saveSite = findSite;
1210 bisect(&(Edgepool[Edgeid]),findSite, topSite);
1211 newEdge = &(Edgepool[Edgeid]);
1214 createHalfEdge( &(HEpool[HEid]), newEdge, saveBool);
1215 newHE = &(HEpool[HEid]);
1218 insertEdgeList(left2HalfEdge, newHE);
1219 makeEndPoint(newEdge, 1-saveBool, newVert);
1221 intersect(&(Sitepool[Siteid]),left2HalfEdge, newHE);
1222 meetSite = &(Sitepool[Siteid]);
1227 deletePQ(left2HalfEdge);
1228 insertPQ(left2HalfEdge, meetSite, dist(meetSite, findSite));
1231 intersect(&(Sitepool[Siteid]),newHE, right2HalfEdge);
1232 meetSite = &(Sitepool[Siteid]);
1236 insertPQ(newHE, meetSite, dist(meetSite, findSite));
1245 for( (leftHalfEdge=m_ELleftend.
m_Right);
1246 (leftHalfEdge != (&m_ELrightend));
1247 (leftHalfEdge=(leftHalfEdge->
m_Right)) )
1249 newEdge = leftHalfEdge->
m_Edge;