⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qhull_geom2.cxx

📁 hl2 source code. Do not use it illegal.
💻 CXX
📖 第 1 页 / 共 5 页
字号:
  
  qh_minabsval( normal, dim )
    return minimum absolute value of a dim vector
*/
realT qh_minabsval (realT *normal, int dim) {
  realT minval= 0;
  realT maxval= 0;
  realT *colp;
  int k;

  for (k= dim, colp= normal; k--; colp++) {
    maximize_(maxval, *colp);
    minimize_(minval, *colp);
  }
  return fmax_(maxval, -minval);
} /* minabsval */


/*-<a                             href="qh-c.htm#geom"
  >-------------------------------</a><a name="mindiff">-</a>
  
  qh_mindif( vecA, vecB, dim )
    return index of min abs. difference of two vectors
*/
int qh_mindiff (realT *vecA, realT *vecB, int dim) {
  realT mindiff= REALmax, diff;
  realT *vecAp= vecA, *vecBp= vecB;
  int k, mink= 0;

  for (k= 0; k < dim; k++) {
    diff= *vecAp++ - *vecBp++;
    diff= fabs_(diff);
    if (diff < mindiff) {
      mindiff= diff;
      mink= k;
    }
  }
  return mink;
} /* mindiff */



/*-<a                             href="qh-c.htm#geom"
  >-------------------------------</a><a name="orientoutside">-</a>
  
  qh_orientoutside( facet  )
    make facet outside oriented via qh.interior_point

  returns:
    True if facet reversed orientation.
*/
boolT qh_orientoutside (facetT *facet) {
  int k;
  realT dist;

  qh_distplane (qh interior_point, facet, &dist);
  if (dist > 0) {
    for (k= qh hull_dim; k--; )
      facet->normal[k]= -facet->normal[k];
    facet->offset= -facet->offset;
    return True;
  }
  return False;
} /* orientoutside */

/*-<a                             href="qh-c.htm#geom"
  >-------------------------------</a><a name="outerinner">-</a>
  
  qh_outerinner( facet, outerplane, innerplane  )
    if facet
      returns outer and inner plane for facet
      requires qh.maxoutdone, i.e., qh_check_maxout()
    else
      returns maximum outer and inner plane
    accounts for qh.JOGGLEmax

  see:
    qh_maxouter(), qh_check_bestdist(), qh_check_points()

  notes:
    outerplaner or innerplane may be NULL
    
    includes qh.DISTround for actual points
    add another qh.DISTround if testing with floating point arithmetic
*/
void qh_outerinner (facetT *facet, realT *outerplane, realT *innerplane) {
  realT dist, mindist;
  vertexT *vertex, **vertexp;

  if (outerplane) {
    if (!qh_MAXoutside || !facet || !qh maxoutdone) {
      *outerplane= qh_maxouter();       /* includes qh.DISTround */
    }else { /* qh_MAXoutside ... */
#if qh_MAXoutside 
      *outerplane= facet->maxoutside + qh DISTround;
#endif
      
    }
    if (qh JOGGLEmax < REALmax/2)
      *outerplane += qh JOGGLEmax * sqrt (qh hull_dim);
  }
  if (innerplane) {
    if (facet) {
      mindist= REALmax;
      FOREACHvertex_(facet->vertices) {
        zinc_(Zdistio);
        qh_distplane (vertex->point, facet, &dist);
        minimize_(mindist, dist);
      }
      *innerplane= mindist - qh DISTround;
    }else 
      *innerplane= qh min_vertex - qh DISTround;
    if (qh JOGGLEmax < REALmax/2)
      *innerplane -= qh JOGGLEmax * sqrt (qh hull_dim);
  }
} /* outerinner */

/*-<a                             href="qh-c.htm#geom"
  >-------------------------------</a><a name="pointdist">-</a>
  
  qh_pointdist( point1, point2, dim )
    return distance between two points

  notes:
    returns distance squared if 'dim' is negative
*/
coordT qh_pointdist(pointT *point1, pointT *point2, int dim) {
  coordT dist, diff;
  int k;
  
  dist= 0.0;
  for (k= (dim > 0 ? dim : -dim); k--; ) {
    diff= *point1++ - *point2++;
    dist += diff * diff;
  }
  if (dim > 0)
    return(sqrt(dist));
  return dist;
} /* pointdist */


/*-<a                             href="qh-c.htm#geom"
  >-------------------------------</a><a name="printmatrix">-</a>
  
  qh_printmatrix( fp, string, rows, numrow, numcol )
    print matrix to fp given by row vectors
    print string as header

  notes:
    print a vector by qh_printmatrix(fp, "", &vect, 1, len)
*/
void qh_printmatrix (FILE *fp, const char *string, realT **rows, int numrow, int numcol) {
  realT *rowp;
  realT r; /*bug fix*/
  int i,k;

  fprintf (fp, "%s\n", string);
  for (i= 0; i < numrow; i++) {
    rowp= rows[i];
    for (k= 0; k < numcol; k++) {
      r= *rowp++;
      fprintf (fp, "%6.3g ", r);
    }
    fprintf (fp, "\n");
  }
} /* printmatrix */

  
/*-<a                             href="qh-c.htm#geom"
  >-------------------------------</a><a name="printpoints">-</a>
  
  qh_printpoints( fp, string, points )
    print pointids to fp for a set of points
    if string, prints string and 'p' point ids
*/
void qh_printpoints (FILE *fp, const char *string, setT *points) {
  pointT *point, **pointp;

  if (string) {
    fprintf (fp, "%s", string);
    FOREACHpoint_(points) 
      fprintf (fp, " p%d", qh_pointid(point));
    fprintf (fp, "\n");
  }else {
    FOREACHpoint_(points) 
      fprintf (fp, " %d", qh_pointid(point));
    fprintf (fp, "\n");
  }
} /* printpoints */

  
/*-<a                             href="qh-c.htm#geom"
  >-------------------------------</a><a name="projectinput">-</a>
  
  qh_projectinput()
    project input points using qh.lower_bound/upper_bound and qh DELAUNAY
    if qh.lower_bound[k]=qh.upper_bound[k]= 0, 
      removes dimension k 
    input points in qh first_point, num_points, input_dim

  returns:
    new point array in qh first_point of qh hull_dim coordinates
    sets qh POINTSmalloc
    if qh DELAUNAY 
      projects points to paraboloid
      lowbound/highbound is also projected
    if qh ATinfinity
      adds point "at-infinity"
    if qh POINTSmalloc 
      frees old point array

  notes:
    checks that qh.hull_dim agrees with qh.input_dim, PROJECTinput, and DELAUNAY


  design:
    sets project[k] to -1 (delete), 0 (keep), 1 (add for Delaunay)
    determines newdim and newnum for qh hull_dim and qh num_points
    projects points to newpoints
    projects qh.lower_bound to itself
    projects qh.upper_bound to itself
    if qh DELAUNAY
      if qh ATINFINITY
        projects points to paraboloid
        computes "infinity" point as vertex average and 10% above all points 
      else
        uses qh_setdelaunay to project points to paraboloid
*/
void qh_projectinput (void) {
  int k,i;
  int newdim= qh input_dim, newnum= qh num_points;
  signed char *project;
  int size= (qh input_dim+1)*sizeof(*project);
  pointT *newpoints, *coord, *infinity;
  realT paraboloid, maxboloid= 0;
  
  project= (signed char*)qh_memalloc (size);
  memset ((char*)project, 0, size);
  for (k= 0; k < qh input_dim; k++) {   /* skip Delaunay bound */
    if (qh lower_bound[k] == 0 && qh upper_bound[k] == 0) {
      project[k]= -1;
      newdim--;
    }
  }
  if (qh DELAUNAY) {
    project[k]= 1;
    newdim++;
    if (qh ATinfinity)
      newnum++;
  }
  if (newdim != qh hull_dim) {
    fprintf(qh ferr, "qhull internal error (qh_projectinput): dimension after projection %d != hull_dim %d\n", newdim, qh hull_dim);
    qh_errexit(qh_ERRqhull, NULL, NULL);
  }
  if (!(newpoints=(coordT*)p_malloc(newnum*newdim*sizeof(coordT)))){
    fprintf(qh ferr, "qhull error: insufficient memory to project %d points\n",
           qh num_points);
    qh_errexit(qh_ERRmem, NULL, NULL);
  }
  qh_projectpoints (project, qh input_dim+1, qh first_point,
                    qh num_points, qh input_dim, newpoints, newdim);
  trace1((qh ferr, "qh_projectinput: updating lower and upper_bound\n"));
  qh_projectpoints (project, qh input_dim+1, qh lower_bound,
                    1, qh input_dim+1, qh lower_bound, newdim+1);
  qh_projectpoints (project, qh input_dim+1, qh upper_bound,
                    1, qh input_dim+1, qh upper_bound, newdim+1);
  qh_memfree(project, ((qh input_dim+1)*sizeof(*project)));
  if (qh POINTSmalloc)
    P_FREE (qh first_point);
  qh first_point= newpoints;
  qh POINTSmalloc= True;
  if (qh DELAUNAY && qh ATinfinity) {
    coord= qh first_point;
    infinity= qh first_point + qh hull_dim * qh num_points;
    for (k=qh hull_dim-1; k--; )
      infinity[k]= 0.0;
    for (i=qh num_points; i--; ) {
      paraboloid= 0.0;
      for (k=qh hull_dim-1; k--; ) {
        paraboloid += *coord * *coord;
	infinity[k] += *coord;
        coord++;
      }
      *(coord++)= paraboloid;
      maximize_(maxboloid, paraboloid);
    }
    /* coord == infinity */
    for (k=qh hull_dim-1; k--; )
      *(coord++) /= qh num_points;
    *(coord++)= maxboloid * 1.1;
    qh num_points++;
    trace0((qh ferr, "qh_projectinput: projected points to paraboloid for Delaunay\n"));
  }else if (qh DELAUNAY)  /* !qh ATinfinity */
    qh_setdelaunay( qh hull_dim, qh num_points, qh first_point);
} /* projectinput */

  
/*-<a                             href="qh-c.htm#geom"
  >-------------------------------</a><a name="projectpoints">-</a>
  
  qh_projectpoints( project, n, points, numpoints, dim, newpoints, newdim )
    project points/numpoints/dim to newpoints/newdim
    if project[k] == -1
      delete dimension k 
    if project[k] == 1 
      add dimension k by duplicating previous column
    n is size of project

  notes:
    newpoints may be points if only adding dimension at end

  design:
    check that 'project' and 'newdim' agree
    for each dimension
      if project == -1
        skip dimension
      else
        determine start of column in newpoints
        determine start of column in points 
          if project == +1, duplicate previous column
        copy dimension (column) from points to newpoints
*/
void qh_projectpoints (signed char *project, int n, realT *points, 
        int numpoints, int dim, realT *newpoints, int newdim) {
  int testdim= dim, oldk=0, newk=0, i,j=0,k;
  realT *newp, *oldp;
  
  for (k= 0; k < n; k++)
    testdim += project[k];
  if (testdim != newdim) {
    ivp_message( "qhull internal error (qh_projectpoints): newdim %d should be %d after projection\n",
      newdim, testdim);
    qh_errexit (qh_ERRqhull, NULL, NULL);
  }
  for (j= 0; j<n; j++) {
    if (project[j] == -1)
      oldk++;
    else {
      newp= newpoints+newk++;
      if (project[j] == +1) {
	if (oldk >= dim)
	  continue;
	oldp= points+oldk;
      }else 
	oldp= points+oldk++;
      for (i=numpoints; i--; ) {
        *newp= *oldp;
        newp += newdim;
        oldp += dim;
      }
    }
    if (oldk >= dim)
      break;
  }
  trace1((qh ferr, "qh_projectpoints: projected %d points from dim %d to dim %d\n", 
    numpoints, dim, newdim));
} /* projectpoints */
        

/*-<a                             href="qh-c.htm#geom"
  >-------------------------------</a><a name="rand">-</a>
  
  qh_rand() 
  qh_srand( seed )
    generate pseudo-random number between 1 and 2^31 -2

  notes:
    from Park & Miller's minimimal standard random number generator
       Communications of the ACM, 31:1192-1201, 1988.
    does not use 0 or 2^31 -1
       this is silently enforced by qh_srand()
    can make 'Rn' much faster by moving qh_rand to qh_distplane
*/
int qh_rand_seed= 1;  /* define as global variable instead of using qh */

int qh_rand( void) {
#define qh_rand_a 16807
#define qh_rand_m 2147483647
#define qh_rand_q 127773  /* m div a */
#define qh_rand_r 2836    /* m mod a */
  int lo, hi, test;
  int seed = qh_rand_seed;

  hi = seed / qh_rand_q;  /* seed div q */
  lo = seed % qh_rand_q;  /* seed mod q */
  test = qh_rand_a * lo - qh_rand_r * hi;
  if (test > 0)
    seed= test;
  else
    seed= test + qh_rand_m;
  qh_rand_seed= seed;
  /* seed = seed < qh_RANDOMmax/2 ? 0 : qh_RANDOMmax;  for testing */
  /* seed = qh_RANDOMmax;  for testing */
  return seed;
} /* rand */

void qh_srand( int seed) {
  if (seed < 1)
    qh_rand_seed= 1;
  else if (seed >= qh_rand_m)
    qh_rand_seed= qh_rand_m - 1;
  else
    qh_rand_seed= seed;
} /* qh_srand */

/*-<a                             href="qh-c.htm#geom"
  >-------------------------------</a><a name="randomfactor">-</a>
  
  qh_randomfactor()
    return a random factor within qh.RANDOMmax of 1.0

  notes:
    qh.RANDOMa/b are defined in global.c

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -