vector<Interval> intervalIntersection(vector<Interval>& A, vector<Interval>& B) { auto cmp = [](const Interval &a, const Interval &b) { return a.end < b.end; }; sort(A.begin(), A.end(), cmp); sort(B.begin(), B.end(), cmp); int i=0, j=0; int n = A.size(), m = B.size(); vector<Interval> intersect; while(i < n && j < m) { if(B[j].start <= A[i].end && A[i].end <= B[j].end) { intersect.push_back(GetOverlap(A[i], B[j])); ++i; } else if(A[i].start <= B[j].end && B[j].end <= A[i].end) { intersect.push_back(GetOverlap(A[i], B[j])); ++j; } else if(A[i].end < B[j].start) ++i; else ++j; } return intersect; }
/// Symmetrical overlap is defined as length(intersection(loc1, loc2) / (length(loc1) + length(loc2)) /// intra-loc overlaps are merged (otherwise non-sensical results are possible) double GetSymmetricalOverlap() const { return GetOverlap(eOverlap_vs_Union); }
/// Relative overlap is defined as ratio of the length of the overlap to the length of the shorter feature double GetRelativeOverlap() const { return GetOverlap(eOverlap_vs_Shorter); }
static void SplitAndDistributData(RSTREE R, int depth, typDATAent *newentry, int M, int m) { ValueArray edgearray, spacearray; RectArray rectarray; refparameters par; refDATAnode n; refinterval re; IndexArray I; Side sortside, currsortside, axsortside; int axis; int mlow, mhigh, index, backind, axisindex; typrect leftrect, rightrect; double leftspace, rightspace, leftedge, rightedge, edge, validedge, backvaledge, axisedge, ovlp, value, validvalue, backvalvalue; int i, j, ii; par= &(*R).parameters._; (*R).Ntosplit= (*R).N[depth]; (*R).N[depth]= (*R).helpdatanode; (*R).helpdatanode= (*R).Ntosplit; for (j= 0; j <= M; j++) { I[j]= j; } mhigh= M-m+1; mlow= m-1; n= &(*(*R).Ntosplit).DATA; (*n).entries[M]= *newentry; for (i= 0; i <= (*par).maxdim; i++) { sortside= low; currsortside= low; QuickSortDataEnt(0,M,i,low,(*n).entries,I); CopyRect(R,(*n).entries[I[M]].rect,rightrect); rightrect[i].l= (*n).entries[I[mhigh]].rect[i].l; for (j= M-1; j >= m; j--) { for (ii= 0; ii <= (*par).maxdim; ii++) { re= &(*n).entries[I[j]].rect[ii]; if ((*re).l < rightrect[ii].l) { rightrect[ii].l= (*re).l; } if ((*re).h > rightrect[ii].h) { rightrect[ii].h= (*re).h; } } if (j <= mhigh) { rightedge= 0.0; rightspace= 1.0; for (ii= 0; ii <= (*par).maxdim; ii++) { rightedge+= rightrect[ii].h - rightrect[ii].l; rightspace*= rightrect[ii].h - rightrect[ii].l; } CopyRect(R,rightrect,rectarray[j]); edgearray[j]= rightedge; spacearray[j]= rightspace; } } /* fill array from M-m+1 down to m with rightrect, rightedge, rightspace */ CopyRect(R,(*n).entries[I[0]].rect,leftrect); for (j= 1; j < mhigh; j++) { for (ii= 0; ii <= (*par).maxdim; ii++) { re= &(*n).entries[I[j]].rect[ii]; if ((*re).l < leftrect[ii].l) { leftrect[ii].l= (*re).l; } if ((*re).h > leftrect[ii].h) { leftrect[ii].h= (*re).h; } } if (j >= mlow) { leftedge= 0.0; for (ii= 0; ii <= (*par).maxdim; ii++) { leftedge+= leftrect[ii].h - leftrect[ii].l; } if (Overlaps(R,leftrect,rectarray[j+1])) { GetOverlap(R,leftrect,rectarray[j+1],&ovlp); if (j == mlow) { validedge= leftedge+edgearray[j+1]; validvalue= ovlp; index= m; } else { edge= leftedge+edgearray[j+1]; validedge= validedge+edge; value= ovlp; if (value < validvalue) { validvalue= value; index= j+1; } } } else { leftspace= 1.0; for (ii= 0; ii <= (*par).maxdim; ii++) { leftspace*= leftrect[ii].h - leftrect[ii].l; } if (j == mlow) { validedge= leftedge+edgearray[j+1]; validvalue= -1.0/(leftspace+spacearray[j+1]); index= m; } else { edge= leftedge+edgearray[j+1]; validedge= validedge+edge; value= -1.0/(leftspace+spacearray[j+1]); if (value < validvalue) { validvalue= value; index= j+1; } } } } } /* Compute sum of the edges from leftedge[m-1]+rightedge[m] up to leftedge[M-m]+rightedge[M-m+1], -> axis; minimal area resp. overlap, -> index. */ currsortside= high; QuickSortDataEnt(0,M,i,high,(*n).entries,I); CopyRect(R,(*n).entries[I[0]].rect,leftrect); leftrect[i].h= (*n).entries[I[mlow]].rect[i].h; for (j= 1; j < mhigh; j++) { for (ii= 0; ii <= (*par).maxdim; ii++) { re= &(*n).entries[I[j]].rect[ii]; if ((*re).l < leftrect[ii].l) { leftrect[ii].l= (*re).l; } if ((*re).h > leftrect[ii].h) { leftrect[ii].h= (*re).h; } } if (j >= mlow) { leftedge= 0.0; leftspace= 1.0; for (ii= 0; ii <= (*par).maxdim; ii++) { leftedge+= leftrect[ii].h - leftrect[ii].l; leftspace*= leftrect[ii].h - leftrect[ii].l; } CopyRect(R,leftrect,rectarray[j]); edgearray[j]= leftedge; spacearray[j]= leftspace; } } /* fill array from m-1 up to M-m with leftrect, leftedge, leftspace */ CopyRect(R,(*n).entries[I[M]].rect,rightrect); for (j= M-1; j >= m; j--) { for (ii= 0; ii <= (*par).maxdim; ii++) { re = &(*n).entries[I[j]].rect[ii]; if ((*re).l < rightrect[ii].l) { rightrect[ii].l= (*re).l; } if ((*re).h > rightrect[ii].h) { rightrect[ii].h= (*re).h; } } if (j <= mhigh) { rightedge= 0.0; for (ii= 0; ii <= (*par).maxdim; ii++) { rightedge+= rightrect[ii].h- rightrect[ii].l; } if (Overlaps(R,rightrect,rectarray[j-1])) { GetOverlap(R,rightrect,rectarray[j-1],&ovlp); if (j == mhigh) { backvaledge= rightedge+edgearray[j-1]; backvalvalue= ovlp; backind= j; } else { edge= rightedge+edgearray[j-1]; backvaledge= backvaledge+edge; value= ovlp; if (value < backvalvalue) { backvalvalue= value; backind= j; } } } else { rightspace= 1.0; for (ii= 0; ii <= (*par).maxdim; ii++) { rightspace*= rightrect[ii].h - rightrect[ii].l; } if (j == mhigh) { backvaledge= rightedge+edgearray[j-1]; backvalvalue= -1.0/(rightspace+spacearray[j-1]); backind= j; } else { edge= rightedge+edgearray[j-1]; backvaledge= backvaledge+edge; value= -1.0/(rightspace+spacearray[j-1]); if (value < backvalvalue) { backvalvalue= value; backind= j; } } } } } /* Compute sum of the edges from rightedge[M-m+1]+leftedge[M-m] down to rightedge[m] +leftedge[m-1], -> axis; minimal area resp. overlap, -> index. */ if (backvalvalue <= validvalue) { sortside= high; index= backind; } validedge= validedge+backvaledge; if (i == 0) { axsortside= sortside; axis= i; axisedge= validedge; axisindex= index; } else if (validedge < axisedge) { axsortside= sortside; axis= i; axisedge= validedge; axisindex= index; } } if (axis != (*par).maxdim || axsortside != currsortside) { QuickSortDataEnt(0,M,axis,axsortside,(*n).entries,I); } n= &(*(*R).N[depth]).DATA; (*n).nofentries= axisindex; for (j= 0; j < (*n).nofentries; j++) { (*n).entries[j]= (*(*R).Ntosplit).DATA.entries[I[j]]; } /* printf("%3d",axisindex); */ /* N[depth] gets entries 0 up to axisindex-1 */ n= &(*(*R).Nsibling).DATA; (*n).nofentries= M-axisindex+1; for (j= 0; j < (*n).nofentries; j++) { (*n).entries[j]= (*(*R).Ntosplit).DATA.entries[I[axisindex+j]]; } /* printf("%3d",M-axisindex+1); */ /* printf("%3d\n",M+1); */ }