#include #include #include #include /*Corrected version of 2-d closest points*/ /*See CLR, p. 908 and Preparata & Shamos, p. 192*/ /*Assumes distinct points*/ #define sqr(x) ((x)*(x)) #define distance(x1,y1,x2,y2) sqrt(sqr(x1-x2) + sqr(y1-y2)) float CPUtime() { struct rusage rusage; getrusage(RUSAGE_SELF,&rusage); return rusage.ru_utime.tv_sec+rusage.ru_utime.tv_usec/1000000.0 + rusage.ru_stime.tv_sec+rusage.ru_stime.tv_usec/1000000.0; } float elapsedTime() { return (10000.0*times(NULL))/CLOCKS_PER_SEC; } void shellsort1(a,b,N) float *a,*b; int N; /*Sorts in ascending order using table a as the key and table b as satellite data. See Sedgewick for details*/ { int group; int i,j,h; int v,vb; for (h=1;h<=N/9; h=3*h+1) ; for (;h>0; h /= 3) for (group=0; group=h && a[j-h]>v) { a[j]=a[j-h]; b[j]=b[j-h]; j -= h; } a[j]=v; b[j]=vb; } } void shellsort2(a,b,myRefs,N) float *a,*b; int *myRefs; int N; /*Sorts in ascending order using table a as the key and table b as satellite data. See Sedgewick for details*/ /*myRefs are subscripts for another table containing the same points in a different order.*/ { int group; int i,j,h; int v,vb,vMyRefs; for (h=1;h<=N/9; h=3*h+1) ; for (;h>0; h /= 3) for (group=0; group=h && a[j-h]>v) { a[j]=a[j-h]; b[j]=b[j-h]; myRefs[j]=myRefs[j-h]; j -= h; } a[j]=v; b[j]=vb; myRefs[j]=vMyRefs; } } void closestPair(Xx,Xy,Yx,Yy,Yrefs, numPoints,closestX1,closestY1,closestX2,closestY2,closestDist) float *Xx,*Xy; /*Set of points sorted ascending by x*/ float *Yx,*Yy; /*Set of points sorted ascending by y*/ int *Yrefs; /*Entry i points to the Xx and Xy entry that is the same as the ith entry of Yx and Yy*/ int numPoints; /*Input Size*/ float *closestX1,*closestY1,*closestX2, *closestY2,*closestDist; /*Used to return the closest pair*/ { int i,j,k,closestI,closestJ; float dist; /*When dividing input,the X arrays are simply handled with pointers to the input array*/ float *Xlx,*Xly,*Xrx,*Xry; /*Y arrays get split/copied according to natural split in X*/ float *Ylx,*Yly,*Yrx,*Yry; int numPointsL,numPointsR; /*Sizes for the divided input*/ /*These work just like the input "refs"*/ int *YlRefs,*YrRefs; int lengthYl,lengthYr; /*Used for "unmerging" the Y tables*/ /*The next two declarations are for the results of the recursive calls*/ float closestLx1,closestLy1,closestLx2,closestLy2,Ldistance; float closestRx1,closestRy1,closestRx2,closestRy2,Rdistance; /*These are work variables for the combining "sweep"*/ float lx,rx; /*x-coordinate for dividing lines*/ float lLimit,rLimit; int rSideSubs[6],nextRpoint; float sweepDist,divideDist; /* dumping for the desperate printf("entering closest\n"); for (i=0;i divideDist) return; /*Impossible to find a closer pair of points*/ /*Adjust coordinates for dividing lines, another improvement*/ lLimit=rx - divideDist; rLimit=lx + divideDist; /*Find the six right side points with smallest Y-coodinates*/ j=(-1); for (nextRpoint=0;nextRpoint=lLimit) /*Only take points in Pl*/ { /*Move ahead in right side points*/ while (rSideSubs[0]!=numPointsR && Yry[rSideSubs[0]]