Ejemplo n.º 1
0
void calcBoundingSphere(double *center, double *radius, FaceList *fl){
  double maxDistance = 0.0;
  for( int i = 0; i < fl->vc-1; i++ ){
    for(int j = i + 1; j < fl->vc; j++){
      double *a = fl->vertices[i];
      double *b = fl->vertices[j];
      double distance = vecSquaredDistanceBetween3d(a, b);
      if( distance > maxDistance){
        midpoint(center, a, b);
        *radius = sqrt(distance) * 0.5;
        maxDistance = distance;
      }
    }
  }
}
Ejemplo n.º 2
0
void calcRitterBoundingSphere(double* center, double* radius, FaceList *fl){
  /*
  An Efficient Bounding Sphere
  by Jack Ritter
  from "Graphics Gems", Academic Press, 1990
  p. 301-303, code: p. 723-725
  */
  
  int count = 0;
  
  double x_min, x_max, y_min, y_max, z_min, z_max;
  int px_min, px_max, py_min, py_max, pz_min, pz_max;

  double *p;
  
  // Intialize
  // Select a point in the mesh as an arbitrary starting point.
  p = fl->vertices[0];
  px_min = px_max = py_min = py_max = pz_min = pz_max = 0;
  x_min = x_max = p[0];
  y_min = y_max = p[1];
  z_min = z_max = p[2];
  
  // Find 6 minima & maxima points
  for( int i = 0; i < fl->vc; i++ ){
    p = fl->vertices[i];
    if( p[0] < x_min ){
      x_min = p[0];
      px_min = i;
    }
    if( p[0] > x_max ){
      x_max = p[0];
      px_max = i;
    }
    if( p[1] < y_min ){
      y_min = p[1];
      py_min = i;
    }
    if( p[1] > y_max ){
      y_max = p[1];
      py_max = i;
    }
    if( p[2] < z_min ){
      z_min = p[2];
      pz_min = i;
    }
    if( p[2] > z_max ){
      z_max = p[2];
      pz_max = i;
    }
  } // end for

  // Find the distance between the extremal values
  double x_span_dist = vecSquaredDistanceBetween3d(fl->vertices[px_max], fl->vertices[px_min]);
  
  double y_span_dist = vecSquaredDistanceBetween3d(fl->vertices[py_max], fl->vertices[py_min]);
  
  double z_span_dist = vecSquaredDistanceBetween3d(fl->vertices[pz_max], fl->vertices[pz_min]);
  
  // Find the maximally separated pair; dia1 & dia2
  double max_span_dist = x_span_dist;
  int dia1, dia2;
  dia1 = px_min;
  dia2 = px_max;
  if( y_span_dist > max_span_dist ){
    max_span_dist = y_span_dist;
    dia1 = py_min;
    dia2 = py_max;
  }
  if( z_span_dist > max_span_dist ){
    dia1 = pz_min;
    dia2 = pz_max;
  }
  
  // dia1 and dia2 define the diameter of the intial sphere
  // calculate the center of the sphere
  double _center[3];
  midpoint(_center, fl->vertices[dia1], fl->vertices[dia2]);

  // Calculate the length of the radius
  double radius_sq_dist = vecSquaredDistanceBetween3d(fl->vertices[dia2], _center);
  double radius_dist = sqrt(radius_sq_dist);
  
  // Incrementally grow the sphere to include all points
  for( int i = 0; i < fl->vc; i++ ){
    double test_sq_dist = vecSquaredDistanceBetween3d(fl->vertices[i], _center);
    if( test_sq_dist > radius_sq_dist ){
      // the current (ith) point is outside the sphere
      double test_dist = sqrt(test_sq_dist);
      // calculate the radius of the new sphere
      radius_dist = (radius_dist + test_dist) * 0.5;
      radius_sq_dist = SQR(radius_dist);
      // calculate the center of the new sphere
      double old_to_new_dist = test_dist - radius_dist;
      for(int j = 0; j < 3; j++){
        _center[j] = (radius_dist * _center[j] + old_to_new_dist * fl->vertices[i][j]) / test_dist;
      }
      count++;
    }
  } // end for
  *radius = radius_dist;
  for(int j = 0; j < 3; j++){
    center[j] = _center[j];
  }
  //printf("Grew the sphere %d times\n", count);
}