24     #include <libqhull/qhull_a.h>    53 unsigned int doHull(
unsigned int bufferSize, 
double *buffer, 
    54             vector<Point3D> &resHull, 
Point3D &midPoint, 
bool freeHullOnExit)
    72 #if defined(__linux__) || defined(__APPLE__) || defined(__BSD__)    73     outSquelch=fopen(
"/dev/null",
"w");
    74 #elif defined(__win32__) || defined(__win64__)    75     outSquelch=fopen(
"NUL",
"w");
    93     if(outSquelch !=stderr)
    98     unsigned int numPoints=0;
   104     numPoints = qh num_vertices;    
   115         resHull.resize(numPoints);  
   117     catch(std::bad_alloc)
   126     vertex= qh vertex_list;
   128     while(vertex != qh vertex_tail)
   130         resHull[curPt]=
Point3D(vertex->point[0],
   133         midPoint+=resHull[curPt];
   135         vertex = vertex->next;
   137     midPoint*=1.0f/(float)numPoints;
   150                 bool (*
callback)(
bool),std::vector<Point3D> &curHull, 
bool freeHull)
   162     buffer =(
double*) malloc(HULL_GRAB_SIZE*3*
sizeof(
double));
   167     size_t bufferOffset=0;
   180     for(
size_t uj=0; uj<data.size(); uj++)
   183         if(curHull.empty() || midPoint.
sqrDist(data[uj].getPos())>= maxSqrDist)
   186             buffer[3*bufferOffset]=data[uj].getPos()[0];
   187             buffer[3*bufferOffset+1]=data[uj].getPos()[1];
   188             buffer[3*bufferOffset+2]=data[uj].getPos()[2];
   193             if(bufferOffset == HULL_GRAB_SIZE)
   195                 bufferOffset+=curHull.size();
   196                 tmp=(
double*)realloc(buffer,
   197                              3*bufferOffset*
sizeof(
double));
   207                 for(
size_t uk=0; uk<curHull.size(); uk++)
   209                     buffer[3*(HULL_GRAB_SIZE+uk)]=curHull[uk][0];
   210                     buffer[3*(HULL_GRAB_SIZE+uk)+1]=curHull[uk][1];
   211                     buffer[3*(HULL_GRAB_SIZE+uk)+2]=curHull[uk][2];
   214                 unsigned int errCode=0;
   216                 errCode=
doHull(bufferOffset,buffer,curHull,midPoint,freeHull);
   226                 maxSqrDist=std::numeric_limits<float>::max();
   227                 for(
size_t ui=0; ui<curHull.size(); ui++)
   228                     maxSqrDist=std::min(maxSqrDist,curHull[ui].sqrDist(midPoint));
   237         if(!progressReduce--)
   245             *progress= (
unsigned int)((
float)(n)/((
float)numPts)*100.0f);
   252     if(bufferOffset + curHull.size() > 4)
   255         tmp=(
double*)realloc(buffer,
   256                              3*(bufferOffset+curHull.size())*
sizeof(
double));
   264         #pragma omp parallel for   265         for(
size_t ui=0; ui<curHull.size(); ui++)
   267             buffer[3*(bufferOffset+ui)]=curHull[ui][0];
   268             buffer[3*(bufferOffset+ui)+1]=curHull[ui][1];
   269             buffer[3*(bufferOffset+ui)+2]=curHull[ui][2];
   272         unsigned int errCode=
doHull(bufferOffset+curHull.size(),buffer,curHull,midPoint,freeHull);
   290         unsigned int *progress, 
bool (*
callback)(
bool), vector<IonHit> &pointResult)
   301     if(points.size() < 4) 
   304     unsigned int dummyProg;
   305     vector<Point3D> theHull;
   310     for(
size_t ui=0;ui<theHull.size();ui++)
   311         midPoint+=theHull[ui];
   312     midPoint *= 1.0f/(float)theHull.size();
   321     Point3D hullCentroid(0.0f,0.0f,0.0f);
   322     float massPyramids=0.0f;
   324     facetT *curFac = qh facet_list;
   326     while(curFac != qh facet_tail)
   335         pyramidCentroid = midPoint;
   340         ASSERT(curFac->simplicial);
   341         vertex  = (vertexT *)curFac->vertices->e[ui].p;
   344             (ptArray[ui])[0]  = vertex->point[0];
   345             (ptArray[ui])[1]  = vertex->point[1];
   346             (ptArray[ui])[2]  = vertex->point[2];
   349             pyramidCentroid += ptArray[ui];
   354             vertex  = (vertexT *)curFac->vertices->e[ui].p;
   366         pyramidCentroid*= 0.25f;
   367         hullCentroid = hullCentroid + (pyramidCentroid*vol);
   373     hullCentroid *= 1.0f/massPyramids;
   375     size_t badFacetCount=0;
   376     float minDist=std::numeric_limits<float>::max();
   379         curFac=qh facet_list;
   380     while(curFac != qh facet_tail)
   388         for(
unsigned int ui=0; ui<3; ui++)
   392             vertex  = ((vertexT *)curFac->vertices->e[ui].p);
   393             vertexPt[ui] = 
Point3D(vertex->point[0],vertex->point[1],vertex->point[2]);
   413                     Point3D(curFac->normal[0],curFac->normal[1],curFac->normal[2]),hullCentroid);
   423         if(badFacetCount == qh num_facets)
   433     scaleFactor = 1  - reductionDim/ minDist;
   435     if(scaleFactor < 0.0f)
   441     vertexT *vertex = qh vertex_list;   
   444     while(vertex !=qh vertex_tail)
   449         vertex->point[0] = (vertex->point[0] - hullCentroid[0])*scaleFactor + hullCentroid[0];
   450         vertex->point[1] = (vertex->point[1] - hullCentroid[1])*scaleFactor + hullCentroid[1];
   451         vertex->point[2] = (vertex->point[2] - hullCentroid[2])*scaleFactor + hullCentroid[2];
   453         vertex = vertex->next;
   461     pointResult.reserve(points.size()/2);
   462     curFac = qh facet_list;
   465     for(
size_t uj=points.size(); uj--;)
   468         double *ptArr,*normalArr;
   474         curFac = qh facet_list;
   475         while(curFac != qh facet_tail)
   479             ptArr = ((vertexT *)curFac->vertices->e[0].p)->point;
   481             normalArr = curFac->normal;
   486                     (float)ptArr[1] - fY,
   487                     (
float)ptArr[2] - fZ,
   488                     normalArr[0], normalArr[1],
   494             goto reduced_loop_next;
   497         pointResult.push_back(points[uj]);
   510 bool dummyCallback(
bool b)
   515 #include <sys/time.h>   518 bool testConvexHull()
   520         std::vector<IonHit> ions;
   523         const float SCALE=100;
   527         ions.resize(NUM_IONS);
   528         for(
unsigned int ui=0;ui<
NUM_IONS;ui++)
   532                 xyzm[0] = SCALE*((float)rand()/RAND_MAX-0.5);
   533                 xyzm[1] = SCALE*((float)rand()/RAND_MAX-0.5);
   534                 xyzm[2] = SCALE*((float)rand()/RAND_MAX-0.5);
   535                 xyzm[3] = SCALE*((float)rand()/RAND_MAX-0.5);
   536                 ions[ui].setHit(xyzm);
   540     vector<Point3D> hullVertices;
   542     unsigned int dummy=0;
   547         ions.resize(NUM_IONS);
   548         for(
unsigned int ui=0;ui<
NUM_IONS;ui++)
   552                 xyzm[0] = SCALE*((float)rand()/RAND_MAX-0.5);
   553                 xyzm[1] = SCALE*((float)rand()/RAND_MAX-0.5);
   554                 xyzm[2] = SCALE*((float)rand()/RAND_MAX-0.5);
   555                 xyzm[3] = SCALE*((float)rand()/RAND_MAX-0.5);
   556                 ions[ui].setHit(xyzm);
   559     vector<IonHit> reducedHullPts;
   563     if(reducedHullPts.empty())
 float sqrDist(const Point3D &pt) const
Returns the square of distance to another Point3D. 
 
const unsigned int NUM_IONS
 
double pyramidVol(const Point3D *planarPts, const Point3D &apex)
 
A 3D point data class storage. 
 
unsigned int doHull(unsigned int bufferSize, double *buffer, vector< Point3D > &resHull, Point3D &midPoint, bool freeHullOnExit)
 
const size_t PROGRESS_REDUCE
 
const unsigned int HULL_GRAB_SIZE
 
float dotProduct(float a1, float a2, float a3, float b1, float b2, float b3)
Inline func for calculating a(dot)b. 
 
unsigned int GetReducedHullPts(const std::vector< IonHit > &points, float reductionDim, unsigned int *progress, bool(*callback)(bool), std::vector< IonHit > &pointResult)
Obtain a set of points that are a subset of points the convex hull that are at least "reductionDim" a...
 
bool triIsDegenerate(const Point3D &fA, const Point3D &fB, const Point3D &fC)
 
unsigned int computeConvexHull(const std::vector< IonHit > &data, unsigned int *progress, bool(*callback)(bool), std::vector< Point3D > &curHull, bool freeHull)
Obtain the convex hull of a set of ions. 
 
float distanceToFacet(const Point3D &fA, const Point3D &fB, const Point3D &fC, const Point3D &normal, const Point3D &p)