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)