47 double xVal = *
static_cast<double*
>( param );
63 newH1.
dx = newH2.
dx = xVal;
66 if( newH1.
dx == h1->
sx && newH1.
dy == h1->
sy ) {
74 if( newH2.
dx == h2->
sx && newH2.
dy == h2->
sy ) {
84 if( h1Y < h2Y )
return -1;
85 else if( h1Y > h2Y )
return 1;
91 if( newH1 < newH2 )
return 1;
95 if( newH1 < newH2 )
return -1;
101 if( !newH1.
isLeft() )
return -1;
105 cerr<<
"AL comp. got a left and right" << endl;
106 cerr<<
"xval: " << std::setprecision(100)<< xVal << endl;
107 cerr << std::setprecision(100) << *h1 << endl << *h2 << endl << newH1 << endl << newH2 << endl;
123 if( region[mid].dx < x ) lo = mid+1;
124 else if( region[mid].dx > x ) hi = mid;
139 if( region[mid].dx <= x ) lo = mid+1;
140 else if( region[mid].dx > x ) {
141 if( mid > 0 && region[mid-1].dx <= x )
return mid;
153 const halfsegment &h,
int & mid,
int hi=-1,
int lo=0 )
159 if( region[mid] < h ) lo = mid+1;
160 else if( region[mid] == h )
return true;
179 vector< double> & isoBounds );
189 void createStrips( vector< halfsegment> & region, vector<double> &isoBounds,
190 vector<halfsegment> & rStrips, vector< int > &stripStopIndex );
202 void partialOverlay(
const vector<halfsegment> & r1Strips,
const vector<halfsegment> & r2Strips,
203 vector<halfsegment> & result,
204 vector< int > &r1StripStopIndex, vector< int > &r2StripStopIndex,
212 double & X,
double & Y,
bool & colinear );
218 vector< halfsegment> & brokenSegs,
bool & colinear,
219 const bool includeCurrSegInBrokenSegs );
229 vector< vector<halfsegment> > &resultStrips,
230 const vector<double> &isoBounds );
239 vector<halfsegment> & result,
243 const double eventY );
247 void parallelOverlay( vector<halfsegment> &r1, vector<halfsegment> &r2, vector<halfsegment> &result,
248 int numStrips,
int numWorkerThreads )
250 vector<halfsegment> r1Strips, r2Strips;
251 vector< double > isoBounds;
252 vector< vector< halfsegment> > resultStrips;
253 vector< int > r1StripStopIndex, r2StripStopIndex;
257 if( numStrips < 0 ) {
258 numStrips = omp_get_num_procs();
260 if( numWorkerThreads > 0 ) {
261 omp_set_num_threads( numWorkerThreads );
265 int numIsoBounds = numStrips+1;
268 for(
int i = 0; i < numStrips; i++ ) {
269 resultStrips.push_back( vector<halfsegment>() );
271 for(
int i = 0; i < numIsoBounds; i++ ) {
272 isoBounds.push_back( 0 );
279 #pragma omp parallel for
280 for(
int i = 0; i < 2; i++ ){
281 if( i == 0 )
createStrips( r1, isoBounds, r1Strips, r1StripStopIndex );
282 else createStrips( r2, isoBounds, r2Strips, r2StripStopIndex );
285 int count, total = 0;
286 cout <<
"Number of segmenents in each strip (r1): , ";
287 for(
int i = 0; i < r1StripStopIndex.size( ); i++ ) {
288 count = r1StripStopIndex[i];
289 if( i > 0 ) count -= r1StripStopIndex[i-1];
291 cout << count <<
",";
293 cout <<
"\ntotal segments in all strips:, "<< total << endl;
295 cout <<
"Number of segmenents in each strip (r2): , ";
296 for(
int i = 0; i < r2StripStopIndex.size( ); i++ ) {
297 count = r2StripStopIndex[i];
298 if( i > 0 ) count -= r2StripStopIndex[i-1];
300 cout << count <<
",";
302 cout <<
"\ntotal segments in all strips:, "<< total << endl;
306 #pragma omp parallel for schedule(dynamic,1)
307 for(
int i = 0; i < numStrips; i++ ) {
308 partialOverlay( r1Strips, r2Strips, resultStrips[i], r1StripStopIndex, r2StripStopIndex, i );
322 void partialOverlay(
const vector<halfsegment> & r1Strips,
const vector<halfsegment> & r2Strips,
323 vector<halfsegment> & result,
324 vector< int > &r1StripStopIndex, vector< int > &r2StripStopIndex,
328 int r1Start, r2Start, r1Stop, r2Stop;
330 r1Start = r2Start = 0;
333 r1Start = r1StripStopIndex[stripID-1];
334 r2Start = r2StripStopIndex[stripID-1];
336 r1Stop = r1StripStopIndex[stripID];
337 r2Stop = r2StripStopIndex[stripID];
340 &(r2Strips[r2Start]), r2Stop-r2Start,
349 vector<halfsegment>& result )
352 maxSeg.
dx = maxSeg.
dy = maxSeg.
sx = maxSeg.
sy = std::numeric_limits<double>::max();
353 double eventX, eventY;
357 avl_traverser alTraverser, alAboveTraverser, alBelowTraverser;
358 halfsegment* alHsegPtr = NULL, *alInsertPtr = NULL, *alHsegAbovePtr = NULL, *alHsegBelowPtr = NULL;
359 vector< halfsegment > brokenSegs;
360 bool colinearIntersection;
361 avl_t_init( &discoveredTraverser, discoveredSegs );
369 while( discoveredSegs->
avl_count > 0 || r1Pos < r1Size || r2Pos < r2Size ) {
373 if( r1Pos < r1Size ) {
377 if( r2Pos < r2Size && r2[r2Pos]< currSeg ) {
382 if( tmpSegPtr != NULL ) {
384 if( tmpSeg < currSeg || tmpSeg == currSeg ){
390 if( segSource == 3 ) {
395 else if( segSource == 2 ){
411 currSeg.
ola = currSeg.
olb = -1;
418 if( alHsegPtr != alInsertPtr ) {
426 alHsegPtr->
ola = currSeg.
la;
427 alHsegPtr->
olb = currSeg.
lb;
430 bool needToRemoveCurr =
false;
432 avl_t_copy( &alAboveTraverser, &alTraverser );
433 avl_t_copy( &alBelowTraverser, &alTraverser );
443 if( alHsegBelowPtr != NULL ) {
451 if( belowSegCopy.
dx != belowSegCopy.
sx ) {
452 currSeg.
ola = currSeg.
olb = belowSegCopy.
la;
454 currSeg.
ola = currSeg.
olb = belowSegCopy.
lb;
458 currSeg.
ola = currSeg.
olb = belowSegCopy.
ola;
470 if(
breakHsegs( *alHsegBelowPtr, currSeg, brokenSegs, colinearIntersection,
false ) ){
471 needToRemoveCurr =
true;
474 delete alHsegBelowPtr;
475 alHsegBelowPtr = NULL;
480 if( alHsegAbovePtr != NULL ) {
481 if(
breakHsegs( *alHsegAbovePtr, currSeg, brokenSegs, colinearIntersection,
false ) ) {
482 needToRemoveCurr =
true;
485 delete alHsegAbovePtr;
486 alHsegAbovePtr = NULL;
492 *alHsegPtr = currSeg;
496 discoveredSegs, activeList,
507 if( alHsegPtr != NULL ) {
511 result.push_back( *alHsegPtr );
514 currSeg = *alHsegPtr;
516 avl_t_copy( &alAboveTraverser, &alTraverser );
517 avl_t_copy( &alBelowTraverser, &alTraverser );
526 if( alHsegBelowPtr != NULL && alHsegAbovePtr != NULL ) {
527 tmpSeg = *alHsegAbovePtr;
529 if(
breakHsegs( *alHsegBelowPtr, tmpSeg, brokenSegs, colinearIntersection,
true ) ){
532 delete alHsegBelowPtr;
533 alHsegBelowPtr = NULL;
535 delete alHsegAbovePtr;
536 alHsegAbovePtr = NULL;
539 discoveredSegs, activeList,
550 std::sort( result.begin(), result.end() );
559 vector<halfsegment> & result,
563 const double eventY )
565 for(
int i = 0; i < brokenSegs.size(); i++ ){
566 if( (brokenSegs[i].dx != brokenSegs[i].sx && ( brokenSegs[i].dx <= eventX && brokenSegs[i].sx <= eventX))
567 || (brokenSegs[i].dx == brokenSegs[i].sx && ( brokenSegs[i].dy <= eventY && brokenSegs[i].sy <= eventY)) ){
571 result.push_back( brokenSegs[i] );
573 else if ( !brokenSegs[i].isLeft()
574 || brokenSegs[i].dx > eventX
575 || ( brokenSegs[i].dx == eventX && brokenSegs[i].dy > eventY ) ) {
590 vector< halfsegment> & brokenSegs,
bool & colinear,
591 const bool includeCurrSegInBrokenSegs)
596 bool foundIntersection;
606 if( h2.
dx < curr.
dx || h2.
dy < curr.
dy ) {
610 brokenSegs.push_back( tmpSeg );
615 if( curr.
sx > h2.
sx || (curr.
sx == h2.
sx && curr.
sy > h2.
sy )) {
623 if( includeCurrSegInBrokenSegs ) {
624 brokenSegs.push_back( tmpSeg );
629 if( curr.
sx != h2.
sx || curr.
sy != h2.
sy ) {
634 if( curr.
sx > h2.
sx || (curr.
sx == h2.
sx && curr.
sy > h2.
sy )) {
640 brokenSegs.push_back( tmpSeg );
647 if( (X == curr.
dx && Y == curr.
dy ) ||
648 (X == curr.
sx && Y == curr.
sy ) ) {
661 if( includeCurrSegInBrokenSegs ) {
662 brokenSegs.push_back( tmpSeg );
668 brokenSegs.push_back( tmpSeg );
672 if( (X == h2.
dx && Y == h2.
dy ) ||
673 (X == h2.
sx && Y == h2.
sy ) ) {
682 brokenSegs.push_back( h2 );
689 brokenSegs.push_back( tmpSeg );
694 brokenSegs.push_back( tmpSeg );
699 return foundIntersection;
713 if( (h1.
dx == h2.
dx && h1.
dy == h2.
dy ) ||
714 (h1.
sx == h2.
sx && h1.
sy == h2.
sy ) ) {
715 X = std::numeric_limits<double>::max();
716 Y = std::numeric_limits<double>::max();
730 double denom = ((y4-y3)*(x2-x1)) - ((x4-x3)*(y2-y1));
731 double ua = ((x4-x3)*(y1-y3)) - ((y4-y3)*(x1-x3));
732 double ub = ((x2-x1)*(y1-y3)) - ((y2-y1)*(x1-x3));
739 if( 0.0 <= ua && ua <= 1.0 && 0.0 <= ub && ub <= 1.0 ) {
740 X = x1 + ( ua*(x2-x1) );
741 Y = y1 + ( ua*(y2-y1) );
745 X = std::numeric_limits<double>::max();
746 Y = std::numeric_limits<double>::max();
756 void createStrips( vector< halfsegment> & region, vector<double> &isoBounds,
757 vector<halfsegment> & rStrips, vector< int > &stripStopIndex )
762 for(
int i = 0; i< region.size(); i++ ) {
764 if( region[i].isLeft( ) ) {
766 for(
int j = startBound; j < isoBounds.size()-1; j++ ){
767 if( workSeg.
dx > isoBounds[j+1] ) {
774 else if( workSeg.
dx >= isoBounds[j] && workSeg.
sx < isoBounds[j+1] ) {
776 rStrips.push_back( workSeg );
786 lhs.
sx = workSeg.
dx = isoBounds[j+1];
788 rStrips.push_back( lhs );
803 std::sort( rStrips.begin(), rStrips.end(),
hsegIDSort);
805 for(
int i = 0; i < isoBounds.size()-1; i++ )
806 stripStopIndex.push_back( std::numeric_limits<int>::min() );
807 for(
int i = 0; i < rStrips.size(); i++ ){
808 if( i >= stripStopIndex[ rStrips[i].stripID ] )
809 stripStopIndex[ rStrips[i].stripID ] = i+1;
813 for(
int i = 0; i < stripStopIndex.size(); i++ ) {
814 if( stripStopIndex[i] == std::numeric_limits<int>::min() ) {
815 stripStopIndex[i] = prevVal;
817 prevVal = stripStopIndex[i];
827 cerr<<
"stopIndex: " ;
828 for(
int i = 0; i < stripStopIndex.size(); i++ )
829 cerr << stripStopIndex[i] <<
" ";
836 vector< double> & isoBounds )
840 isoBounds[0] = std::numeric_limits<double>::max() *-1;
841 isoBounds[ isoBounds.size()-1 ] = std::numeric_limits<double>::max();
844 double minX = std::numeric_limits<double>::max();
845 double maxX = std::numeric_limits<double>::max()*-1;
846 if( isoBounds.size() == 2){
849 for(
int i = 0; i < r1.size(); i++ ){
850 if( r1[i].dx < minX ) minX = r1[i].dx;
851 if( r1[i].dx > maxX ) maxX = r1[i].dx;
852 if( r1[i].sx < minX ) minX = r1[i].sx;
853 if( r1[i].sx > maxX ) maxX = r1[i].sx;
855 for(
int i = 0; i < r2.size(); i++ ){
856 if( r2[i].dx < minX ) minX = r2[i].dx;
857 if( r2[i].dx > maxX ) maxX = r2[i].dx;
858 if( r2[i].sx < minX ) minX = r2[i].sx;
859 if( r2[i].sx > maxX ) maxX = r2[i].sx;
863 double prevIsoVal = minX;
864 double stripWidth = (maxX-minX) / (isoBounds.size()-1);
865 for(
int i = 1; i < isoBounds.size()-1; i++ ) {
866 prevIsoVal += stripWidth;
867 isoBounds[i] = prevIsoVal;
871 cerr<<
"iso Bounds: " << endl;
872 cerr << minX <<
","<< maxX<<
","<< r1.size() <<
","<<r2.size() <<endl;
873 for(
int i= 0; i < isoBounds.size(); i++ ){
874 cerr << isoBounds[i] <<
", ";
880 for(
int i = 1; i < isoBounds.size()-1; i++ ) {
881 int r1Index, r2Index;
885 if( r1Index >= 0 || r2Index >= 0 ){
889 cerr <<
"riInd, r2Ind " << r1Index <<
", " << r2Index << endl;
890 double xVal = isoBounds[i+1];
891 if( r1Index < r1.size() && r1[r1Index].dx < xVal ) {
892 xVal = r1[r1Index].dx;
894 if( r2Index < r2.size() && r2[r2Index].dx < xVal ) {
895 xVal = r2[r2Index].dx;
897 if( xVal == std::numeric_limits<double>::max() ){
898 cerr <<
"Did not find xVal in splits" << endl;
902 isoBounds[i] = (isoBounds[i]+xVal)/2.0;
907 cerr<<
"iso Bounds: " << endl;
908 for(
int i= 0; i < isoBounds.size(); i++ ){
909 cerr << isoBounds[i] <<
", ";
919 vector< vector<halfsegment> > &resultStrips,
920 const vector<double> &isoBounds )
935 for(
int i = 0; i <resultStrips.size(); i++ ) {
936 for(
int j = 0; j < resultStrips[i].size(); j++ ) {
937 curr = resultStrips[i][j];
944 if( curr.
sx == isoBounds[currBound] ) {
947 cerr <<
"did not find brother 1" <<endl; exit( -1 );
950 bool invalidateLast=
false;
951 while( curr.
sx == isoBounds[currBound] ) {
953 if( (broIndex+1 < resultStrips[currStrip].size()
954 && resultStrips[currStrip][broIndex+1].dx == curr.
sx
955 && resultStrips[currStrip][broIndex+1].dy == curr.
sy )
957 && resultStrips[currStrip][broIndex-1].dx == curr.
sx
958 && resultStrips[currStrip][broIndex-1].dy == curr.
sy ) ) {
962 invalidateLast =
true;
965 resultStrips[currStrip][broIndex].la = resultStrips[currStrip][broIndex].lb = -1;
967 resultStrips[currStrip][currIndex].la = resultStrips[currStrip][currIndex].lb = -1;
971 binarySearchHalfsegment(resultStrips[ currStrip+1 ], resultStrips[currStrip+1][currIndex].getBrother(), broIndex );
973 curr.
sx = resultStrips[ currStrip+1 ][currIndex].sx;
974 curr.
sy = resultStrips[ currStrip+1 ][currIndex].sy;
979 if( invalidateLast ) {
981 resultStrips[currStrip][broIndex].la = resultStrips[currStrip][broIndex].lb = -1;
983 resultStrips[currStrip][currIndex].la = resultStrips[currStrip][currIndex].lb = -1;
987 finalResult.push_back( curr );
bool colinear(const halfsegment &rhs) const
holds a single halfsegment, along with labeling information and information indicating if the opposin...
void * avl_delete(struct avl_table *tree, const void *item)
void * avl_t_next(struct avl_traverser *trav)
bool hsegIDSort(const halfsegment &h1, const halfsegment &h2)
int avlHsegActiveListCompare(const void *first, const void *second, void *param)
int binarySearchExists(vector< halfsegment > ®ion, double x, int hi=-1, int lo=0)
int regionID
The region the seg belongs to.
void createStrips(vector< halfsegment > ®ion, vector< double > &isoBounds, vector< halfsegment > &rStrips, vector< int > &stripStopIndex)
struct avl_table * avl_create(avl_comparison_func *compare, void *param, struct libavl_allocator *allocator)
bool findIntersectionPoint(const halfsegment &h1, const halfsegment &h2, double &X, double &Y, bool &colinear)
void * avl_t_insert(struct avl_traverser *trav, struct avl_table *tree, void *item)
void partialOverlay(const vector< halfsegment > &r1Strips, const vector< halfsegment > &r2Strips, vector< halfsegment > &result, vector< int > &r1StripStopIndex, vector< int > &r2StripStopIndex, const int stripID)
void parallelOverlay(vector< halfsegment > &r1, vector< halfsegment > &r2, vector< halfsegment > &result, int numStrips, int numWorkerThreads)
double getYvalAtX(const double x) const
void * avl_insert(struct avl_table *table, void *item)
void * avl_t_find(struct avl_traverser *trav, struct avl_table *tree, void *item)
void * avl_t_prev(struct avl_traverser *trav)
void insertBrokenSegsToActiveListAndDiscoveredQueue(const vector< halfsegment > &brokenSegs, vector< halfsegment > &result, avl_table *discoveredSegs, avl_table *activeList, const double eventX, const double eventY)
void createFinalOverlay(vector< halfsegment > &finalResult, vector< vector< halfsegment > > &resultStrips, const vector< double > &isoBounds)
int binarySearchSmallestGreater(vector< halfsegment > ®ion, double x, int hi=-1, int lo=-1)
double dx
dominating and submissive points
void overlayPlaneSweep(const halfsegment r1[], int r1Size, const halfsegment r2[], int r2Size, vector< halfsegment > &result)
bool binarySearchHalfsegment(vector< halfsegment > ®ion, const halfsegment &h, int &mid, int hi=-1, int lo=0)
int la
label above, label below
int avlHsegCompare(const void *first, const void *second, void *param)
void * avl_t_copy(struct avl_traverser *trav, const struct avl_traverser *src)
void * avl_t_first(struct avl_traverser *trav, struct avl_table *tree)
void findIsoBoundaries(vector< halfsegment > &r1, vector< halfsegment > &r2, vector< double > &isoBounds)
bool breakHsegs(const halfsegment &alSeg, halfsegment &origCurr, vector< halfsegment > &brokenSegs, bool &colinear, const bool includeCurrSegInBrokenSegs)
halfsegment getBrother() const
void avl_t_init(struct avl_traverser *trav, struct avl_table *tree)