Ejemplo n.º 1
0
static void calc_bbox(BBOX *BBox, BBOX_TREE **Finite, long first, long  last)
{
  long i;
  DBL tmin, tmax;
  VECTOR bmin, bmax;
  BBOX *bbox;

  Make_Vector(bmin, BOUND_HUGE, BOUND_HUGE, BOUND_HUGE);
  Make_Vector(bmax, -BOUND_HUGE, -BOUND_HUGE, -BOUND_HUGE);

  for (i = first; i < last; i++)
  {
    bbox = &(Finite[i]->BBox);

    tmin = bbox->Lower_Left[X];
    tmax = tmin + bbox->Lengths[X];

    if (tmin < bmin[X]) { bmin[X] = tmin; }
    if (tmax > bmax[X]) { bmax[X] = tmax; }

    tmin = bbox->Lower_Left[Y];
    tmax = tmin + bbox->Lengths[Y];

    if (tmin < bmin[Y]) { bmin[Y] = tmin; }
    if (tmax > bmax[Y]) { bmax[Y] = tmax; }

    tmin = bbox->Lower_Left[Z];
    tmax = tmin + bbox->Lengths[Z];

    if (tmin < bmin[Z]) { bmin[Z] = tmin; }
    if (tmax > bmax[Z]) { bmax[Z] = tmax; }
  }

  Make_BBox_from_min_max(*BBox, bmin, bmax);
}
Ejemplo n.º 2
0
void calc_bbox(BoundingBox *BBox, BBOX_TREE **Finite, ptrdiff_t first, ptrdiff_t last)
{
    ptrdiff_t i;
    DBL tmin, tmax;
    Vector3d bmin, bmax;
    BoundingBox *bbox;

    bmin = Vector3d(BOUND_HUGE);
    bmax = Vector3d(-BOUND_HUGE);

    for(i = first; i < last; i++)
    {
        bbox = &(Finite[i]->BBox);

        tmin = bbox->lowerLeft[X];
        tmax = tmin + bbox->size[X];

        if(tmin < bmin[X]) { bmin[X] = tmin; }
        if(tmax > bmax[X]) { bmax[X] = tmax; }

        tmin = bbox->lowerLeft[Y];
        tmax = tmin + bbox->size[Y];

        if(tmin < bmin[Y]) { bmin[Y] = tmin; }
        if(tmax > bmax[Y]) { bmax[Y] = tmax; }

        tmin = bbox->lowerLeft[Z];
        tmax = tmin + bbox->size[Z];

        if(tmin < bmin[Z]) { bmin[Z] = tmin; }
        if(tmax > bmax[Z]) { bmax[Z] = tmax; }
    }

    Make_BBox_from_min_max(*BBox, bmin, bmax);
}
Ejemplo n.º 3
0
void Recompute_Inverse_BBox(BBOX *bbox, TRANSFORM *trans)
{
  int i;
  VECTOR lower_left, lengths, corner;
  VECTOR mins, maxs;

  if (trans == NULL)
  {
    return;
  }

  Assign_BBox_Vect(lower_left, bbox->Lower_Left);
  Assign_BBox_Vect(lengths, bbox->Lengths);

  Make_Vector(mins, BOUND_HUGE, BOUND_HUGE, BOUND_HUGE);
  Make_Vector(maxs, -BOUND_HUGE, -BOUND_HUGE, -BOUND_HUGE);

  for (i = 1; i <= 8; i++)
  {
    Assign_Vector(corner, lower_left);

    corner[X] += ((i & 1) ? lengths[X] : 0.0);
    corner[Y] += ((i & 2) ? lengths[Y] : 0.0);
    corner[Z] += ((i & 4) ? lengths[Z] : 0.0);

    MInvTransPoint(corner, corner, trans);

    if (corner[X] < mins[X]) { mins[X] = corner[X]; }
    if (corner[X] > maxs[X]) { maxs[X] = corner[X]; }
    if (corner[Y] < mins[Y]) { mins[Y] = corner[Y]; }
    if (corner[Y] > maxs[Y]) { maxs[Y] = corner[Y]; }
    if (corner[Z] < mins[Z]) { mins[Z] = corner[Z]; }
    if (corner[Z] > maxs[Z]) { maxs[Z] = corner[Z]; }
  }

  /* Clip bounding box at the largest allowed bounding box. */

  if (mins[X] < -BOUND_HUGE / 2) { mins[X] = -BOUND_HUGE / 2; }
  if (mins[Y] < -BOUND_HUGE / 2) { mins[Y] = -BOUND_HUGE / 2; }
  if (mins[Z] < -BOUND_HUGE / 2) { mins[Z] = -BOUND_HUGE / 2; }
  if (maxs[X] >  BOUND_HUGE / 2) { maxs[X] =  BOUND_HUGE / 2; }
  if (maxs[Y] >  BOUND_HUGE / 2) { maxs[Y] =  BOUND_HUGE / 2; }
  if (maxs[Z] >  BOUND_HUGE / 2) { maxs[Z] =  BOUND_HUGE / 2; }

  Make_BBox_from_min_max(*bbox, mins, maxs);
}
Ejemplo n.º 4
0
static void Compute_Polygon_BBox(POLYGON *Polyg)
{
  int i;
  VECTOR p, Puv, Min, Max;

  Min[X] = Min[Y] = Min[Z] =  BOUND_HUGE;
  Max[X] = Max[Y] = Max[Z] = -BOUND_HUGE;

  for (i = 0; i < Polyg->Data->Number; i++)
  {
    Puv[X] = Polyg->Data->Points[i][X];
    Puv[Y] = Polyg->Data->Points[i][Y];
    Puv[Z] = 0.0;

    MTransPoint(p, Puv, Polyg->Trans);

    Min[X] = min(Min[X], p[X]);
    Min[Y] = min(Min[Y], p[Y]);
    Min[Z] = min(Min[Z], p[Z]);
    Max[X] = max(Max[X], p[X]);
    Max[Y] = max(Max[Y], p[Y]);
    Max[Z] = max(Max[Z], p[Z]);
  }

  Make_BBox_from_min_max(Polyg->BBox, Min, Max);

  if (fabs(Polyg->BBox.Lengths[X]) < Small_Tolerance)
  {
    Polyg->BBox.Lower_Left[X] -= Small_Tolerance;
    Polyg->BBox.Lengths[X]    += 2.0 * Small_Tolerance;
  }

  if (fabs(Polyg->BBox.Lengths[Y]) < Small_Tolerance)
  {
    Polyg->BBox.Lower_Left[Y] -= Small_Tolerance;
    Polyg->BBox.Lengths[Y]    += 2.0 * Small_Tolerance;
  }

  if (fabs(Polyg->BBox.Lengths[Z]) < Small_Tolerance)
  {
    Polyg->BBox.Lower_Left[Z] -= Small_Tolerance;
    Polyg->BBox.Lengths[Z]    += 2.0 * Small_Tolerance;
  }
}
Ejemplo n.º 5
0
void Triangle::Compute_BBox()
{
    Vector3d Min, Max, Epsilon;

    Epsilon = Vector3d(EPSILON);

    Min[X] = min3(P1[X], P2[X], P3[X]);
    Min[Y] = min3(P1[Y], P2[Y], P3[Y]);
    Min[Z] = min3(P1[Z], P2[Z], P3[Z]);

    Max[X] = max3(P1[X], P2[X], P3[X]);
    Max[Y] = max3(P1[Y], P2[Y], P3[Y]);
    Max[Z] = max3(P1[Z], P2[Z], P3[Z]);

    Min -= Epsilon;
    Max += Epsilon;

    Make_BBox_from_min_max(BBox, Min, Max);
}
Ejemplo n.º 6
0
void Compute_Triangle_BBox(TRIANGLE *Triangle)
{
  VECTOR Min, Max, Epsilon;

  Make_Vector(Epsilon, EPSILON, EPSILON, EPSILON);

  Min[X] = min3(Triangle->P1[X], Triangle->P2[X], Triangle->P3[X]);
  Min[Y] = min3(Triangle->P1[Y], Triangle->P2[Y], Triangle->P3[Y]);
  Min[Z] = min3(Triangle->P1[Z], Triangle->P2[Z], Triangle->P3[Z]);

  Max[X] = max3(Triangle->P1[X], Triangle->P2[X], Triangle->P3[X]);
  Max[Y] = max3(Triangle->P1[Y], Triangle->P2[Y], Triangle->P3[Y]);
  Max[Z] = max3(Triangle->P1[Z], Triangle->P2[Z], Triangle->P3[Z]);

  VSubEq(Min, Epsilon);
  VAddEq(Max, Epsilon);

  Make_BBox_from_min_max(Triangle->BBox, Min, Max);
}
Ejemplo n.º 7
0
void Recompute_Inverse_BBox(BoundingBox *bbox, const TRANSFORM *trans)
{
    int i;
    Vector3d lower_left, lengths, corner;
    Vector3d mins, maxs;

    if(trans == NULL)
        return;

    lower_left = Vector3d(bbox->lowerLeft);
    lengths    = Vector3d(bbox->size);

    mins = Vector3d(BOUND_HUGE);
    maxs = Vector3d(-BOUND_HUGE);

    for(i = 1; i <= 8; i++)
    {
        corner = lower_left;

        corner[X] += ((i & 1) ? lengths[X] : 0.0);
        corner[Y] += ((i & 2) ? lengths[Y] : 0.0);
        corner[Z] += ((i & 4) ? lengths[Z] : 0.0);

        MInvTransPoint(corner, corner, trans);

        if(corner[X] < mins[X]) { mins[X] = corner[X]; }
        if(corner[X] > maxs[X]) { maxs[X] = corner[X]; }
        if(corner[Y] < mins[Y]) { mins[Y] = corner[Y]; }
        if(corner[Y] > maxs[Y]) { maxs[Y] = corner[Y]; }
        if(corner[Z] < mins[Z]) { mins[Z] = corner[Z]; }
        if(corner[Z] > maxs[Z]) { maxs[Z] = corner[Z]; }
    }

    // Clip bounding box at the largest allowed bounding box.
    if(mins[X] < -BOUND_HUGE / 2) { mins[X] = -BOUND_HUGE / 2; }
    if(mins[Y] < -BOUND_HUGE / 2) { mins[Y] = -BOUND_HUGE / 2; }
    if(mins[Z] < -BOUND_HUGE / 2) { mins[Z] = -BOUND_HUGE / 2; }
    if(maxs[X] >  BOUND_HUGE / 2) { maxs[X] =  BOUND_HUGE / 2; }
    if(maxs[Y] >  BOUND_HUGE / 2) { maxs[Y] =  BOUND_HUGE / 2; }
    if(maxs[Z] >  BOUND_HUGE / 2) { maxs[Z] =  BOUND_HUGE / 2; }

    Make_BBox_from_min_max(*bbox, mins, maxs);
}
Ejemplo n.º 8
0
void Polygon::Compute_BBox()
{
    int i;
    Vector3d p, Puv, Min, Max;

    Min[X] = Min[Y] = Min[Z] =  BOUND_HUGE;
    Max[X] = Max[Y] = Max[Z] = -BOUND_HUGE;

    for (i = 0; i < Data->Number; i++)
    {
        Puv[X] = Data->Points[i][X];
        Puv[Y] = Data->Points[i][Y];
        Puv[Z] = 0.0;

        MTransPoint(p, Puv, Trans);

        Min = min(Min, p);
        Max = max(Max, p);
    }

    Make_BBox_from_min_max(BBox, Min, Max);

    if (fabs(BBox.size[X]) < SMALL_TOLERANCE)
    {
        BBox.lowerLeft[X] -= SMALL_TOLERANCE;
        BBox.size[X]    += 2.0 * SMALL_TOLERANCE;
    }

    if (fabs(BBox.size[Y]) < SMALL_TOLERANCE)
    {
        BBox.lowerLeft[Y] -= SMALL_TOLERANCE;
        BBox.size[Y]    += 2.0 * SMALL_TOLERANCE;
    }

    if (fabs(BBox.size[Z]) < SMALL_TOLERANCE)
    {
        BBox.lowerLeft[Z] -= SMALL_TOLERANCE;
        BBox.size[Z]    += 2.0 * SMALL_TOLERANCE;
    }
}
Ejemplo n.º 9
0
void BicubicPatch::Compute_BBox()
{
    int i, j;
    Vector3d Min, Max;

    Min = Vector3d(BOUND_HUGE);
    Max = Vector3d(-BOUND_HUGE);

    for (i = 0; i < 4; i++)
    {
        for (j = 0; j < 4; j++)
        {
            Min[X] = min(Min[X], Control_Points[i][j][X]);
            Min[Y] = min(Min[Y], Control_Points[i][j][Y]);
            Min[Z] = min(Min[Z], Control_Points[i][j][Z]);
            Max[X] = max(Max[X], Control_Points[i][j][X]);
            Max[Y] = max(Max[Y], Control_Points[i][j][Y]);
            Max[Z] = max(Max[Z], Control_Points[i][j][Z]);
        }
    }

    Make_BBox_from_min_max(BBox, Min, Max);
}
Ejemplo n.º 10
0
void Compute_Bicubic_Patch_BBox(BICUBIC_PATCH *Bicubic_Patch)
{
  int i, j;
  VECTOR Min, Max;

  Make_Vector(Min, BOUND_HUGE, BOUND_HUGE, BOUND_HUGE);
  Make_Vector(Max, -BOUND_HUGE, -BOUND_HUGE, -BOUND_HUGE);

  for (i = 0; i < 4; i++)
  {
    for (j = 0; j < 4; j++)
    {
      Min[X] = min(Min[X], Bicubic_Patch->Control_Points[i][j][X]);
      Min[Y] = min(Min[Y], Bicubic_Patch->Control_Points[i][j][Y]);
      Min[Z] = min(Min[Z], Bicubic_Patch->Control_Points[i][j][Z]);
      Max[X] = max(Max[X], Bicubic_Patch->Control_Points[i][j][X]);
      Max[Y] = max(Max[Y], Bicubic_Patch->Control_Points[i][j][Y]);
      Max[Z] = max(Max[Z], Bicubic_Patch->Control_Points[i][j][Z]);
    }
  }
  
  Make_BBox_from_min_max(Bicubic_Patch->BBox, Min, Max);
}
Ejemplo n.º 11
0
void Compute_Quadric_BBox(QUADRIC *Quadric, VECTOR ClipMin, VECTOR  ClipMax)
{
  DBL A, B, C, D, E, F, G, H, I, J;
  DBL a, b, c, d;
  DBL rx, ry, rz, rx1, rx2, ry1, ry2, rz1, rz2, x, y, z;
  DBL New_Volume, Old_Volume;
  VECTOR Min, Max, TmpMin, TmpMax, NewMin, NewMax, T1;
  BBOX Old;
  OBJECT *Sib;

  /*
   * Check for 'normal' form. If the quadric isn't in it's normal form
   * we can't do anything (we could, but that would be to tedious!
   * Diagonalising the quadric's 4x4 matrix, i.e. finding its eigenvalues
   * and eigenvectors -> solving a 4th order polynom).
   */

  /* Get quadrics coefficients. */

  A = Quadric->Square_Terms[X];
  E = Quadric->Square_Terms[Y];
  H = Quadric->Square_Terms[Z];
  B = Quadric->Mixed_Terms[X] / 2.0;
  C = Quadric->Mixed_Terms[Y] / 2.0;
  F = Quadric->Mixed_Terms[Z] / 2.0;
  D = Quadric->Terms[X] / 2.0;
  G = Quadric->Terms[Y] / 2.0;
  I = Quadric->Terms[Z] / 2.0;
  J = Quadric->Constant;

  /* Set small values to 0. */

  if (fabs(A) < EPSILON) A = 0.0;
  if (fabs(B) < EPSILON) B = 0.0;
  if (fabs(C) < EPSILON) C = 0.0;
  if (fabs(D) < EPSILON) D = 0.0;
  if (fabs(E) < EPSILON) E = 0.0;
  if (fabs(F) < EPSILON) F = 0.0;
  if (fabs(G) < EPSILON) G = 0.0;
  if (fabs(H) < EPSILON) H = 0.0;
  if (fabs(I) < EPSILON) I = 0.0;
  if (fabs(J) < EPSILON) J = 0.0;

  /* Non-zero mixed terms --> return */

  if ((B != 0.0) || (C != 0.0) || (F != 0.0))
  {
    return;
  }

  /* Non-zero linear terms --> get translation vector */

  if ((D != 0.0) || (G != 0.0) || (I != 0.0))
  {
    if (A != 0.0)
    {
      T1[X] = -D / A;
    }
    else
    {
      if (D != 0.0)
      {
       T1[X] = J / (2.0 * D);
      }
      else
      {
        T1[X] = 0.0;
      }
    }

    if (E != 0.0)
    {
      T1[Y] = -G / E;
    }
    else
    {
      if (G != 0.0)
      {
        T1[Y] = J / (2.0 * G);
      }
      else
      {
        T1[Y] = 0.0;
      }
    }

    if (H != 0.0)
    {
      T1[Z] = -I / H;
    }
    else
    {
      if (I != 0.0)
      {
        T1[Z] = J / (2.0 * I);
      }
      else
      {
        T1[Z] = 0.0;
      }
    }

    /* Recalculate coefficients. */

    D += A * T1[X];
    G += E * T1[Y];
    I += H * T1[Z];
    J -= T1[X]*(A*T1[X] + 2.0*D) + T1[Y]*(E*T1[Y] + 2.0*G) + T1[Z]*(H*T1[Z] + 2.0*I);
  }
  else
  {
    Make_Vector(T1, 0.0, 0.0, 0.0);
  }

  /* Get old bounding box. */

  Old = Quadric->BBox;

  /* Init new bounding box. */

  NewMin[X] = NewMin[Y] = NewMin[Z] = -BOUND_HUGE/2;
  NewMax[X] = NewMax[Y] = NewMax[Z] =  BOUND_HUGE/2;

  /* Get the bounding box of the clipping object. */

  if (Quadric->Clip != NULL)
  {
    Min[X] = Min[Y] = Min[Z] = -BOUND_HUGE;
    Max[X] = Max[Y] = Max[Z] =  BOUND_HUGE;

    /* Intersect the members bounding boxes. */

    for (Sib = Quadric->Clip; Sib != NULL; Sib = Sib->Sibling)
    {
      if (!Test_Flag(Sib, INVERTED_FLAG))
      {
        if (Sib->Methods == &Plane_Methods)
        {
          Compute_Plane_Min_Max((PLANE *)Sib, TmpMin, TmpMax);
        }
        else
        {
          Make_min_max_from_BBox(TmpMin, TmpMax, Sib->BBox);
        }

        Min[X] = max(Min[X], TmpMin[X]);
        Min[Y] = max(Min[Y], TmpMin[Y]);
        Min[Z] = max(Min[Z], TmpMin[Z]);
        Max[X] = min(Max[X], TmpMax[X]);
        Max[Y] = min(Max[Y], TmpMax[Y]);
        Max[Z] = min(Max[Z], TmpMax[Z]);
      }
    }

    Assign_Vector(ClipMin, Min);
    Assign_Vector(ClipMax, Max);
  }

  /* Translate clipping box. */

  VSubEq(ClipMin, T1);
  VSubEq(ClipMax, T1);

  /* We want A to be non-negative. */

  if (A < 0.0)
  {
    A = -A;
    D = -D;
    E = -E;
    G = -G;
    H = -H;
    I = -I;
    J = -J;
  }

  /*
   *
   * Check for ellipsoid.
   *
   *    x*x     y*y     z*z
   *   ----- + ----- + ----- - 1 = 0
   *    a*a     b*b     c*c
   *
   */

  if ((A > 0.0) && (E > 0.0) && (H > 0.0) && (J < 0.0))
  {
    a = sqrt(-J/A);
    b = sqrt(-J/E);
    c = sqrt(-J/H);

    NewMin[X] = -a;
    NewMin[Y] = -b;
    NewMin[Z] = -c;
    NewMax[X] = a;
    NewMax[Y] = b;
    NewMax[Z] = c;
  }

  /*
   *
   * Check for cylinder (x-axis).
   *
   *    y*y     z*z
   *   ----- + ----- - 1 = 0
   *    b*b     c*c
   *
   */

  if ((A == 0.0) && (E > 0.0) && (H > 0.0) && (J < 0.0))
  {
    b = sqrt(-J/E);
    c = sqrt(-J/H);

    NewMin[Y] = -b;
    NewMin[Z] = -c;
    NewMax[Y] = b;
    NewMax[Z] = c;
  }

  /*
   *
   * Check for cylinder (y-axis).
   *
   *    x*x     z*z
   *   ----- + ----- - 1 = 0
   *    a*a     c*c
   *
   */

  if ((A > 0.0) && (E == 0.0) && (H > 0.0) && (J < 0.0))
  {
    a = sqrt(-J/A);
    c = sqrt(-J/H);

    NewMin[X] = -a;
    NewMin[Z] = -c;
    NewMax[X] = a;
    NewMax[Z] = c;
  }

  /*
   *
   * Check for cylinder (z-axis).
   * 
   *    x*x     y*y
   *   ----- + ----- - 1 = 0
   *    a*a     b*b
   *
   */

  if ((A > 0.0) && (E > 0.0) && (H == 0.0) && (J < 0.0))
  {
    a = sqrt(-J/A);
    b = sqrt(-J/E);

    NewMin[X] = -a;
    NewMin[Y] = -b;
    NewMax[X] = a;
    NewMax[Y] = b;
  }

  /*
   *
   * Check for cone (x-axis).
   *
   *    x*x     y*y     z*z
   *   ----- - ----- - ----- = 0
   *    a*a     b*b     c*c
   *
   */

  if ((A > 0.0) && (E < 0.0) && (H < 0.0) && (J == 0.0))
  {
    a = sqrt(1.0/A);
    b = sqrt(-1.0/E);
    c = sqrt(-1.0/H);

    /* Get radii for lower x value. */

    x = ClipMin[X];

    ry1 = fabs(x * b / a);
    rz1 = fabs(x * c / a);

    /* Get radii for upper x value. */

    x = ClipMax[X];

    ry2 = fabs(x * b / a);
    rz2 = fabs(x * c / a);

    ry = max(ry1, ry2);
    rz = max(rz1, rz2);

    NewMin[Y] = -ry;
    NewMin[Z] = -rz;
    NewMax[Y] = ry;
    NewMax[Z] = rz;
  }

  /*
   *
   *  Check for cone (y-axis).
   *
   *    x*x     y*y     z*z
   *   ----- - ----- + ----- = 0
   *    a*a     b*b     c*c
   *
   */

  if ((A > 0.0) && (E < 0.0) && (H > 0.0) && (J == 0.0))
  {
    a = sqrt(1.0/A);
    b = sqrt(-1.0/E);
    c = sqrt(1.0/H);

    /* Get radii for lower y value. */

    y = ClipMin[Y];

    rx1 = fabs(y * a / b);
    rz1 = fabs(y * c / b);

    /* Get radii for upper y value. */

    y = ClipMax[Y];

    rx2 = fabs(y * a / b);
    rz2 = fabs(y * c / b);

    rx = max(rx1, rx2);
    rz = max(rz1, rz2);

    NewMin[X] = -rx;
    NewMin[Z] = -rz;
    NewMax[X] = rx;
    NewMax[Z] = rz;
  }

  /*
   *
   * Check for cone (z-axis).
   * 
   *    x*x     y*y     z*z
   *   ----- + ----- - ----- = 0
   *    a*a     b*b     c*c
   *
   */

  if ((A > 0.0) && (E > 0.0) && (H < 0.0) && (J == 0.0))
  {
    a = sqrt(1.0/A);
    b = sqrt(1.0/E);
    c = sqrt(-1.0/H);

    /* Get radii for lower z value. */

    z = ClipMin[Z];

    rx1 = fabs(z * a / c);
    ry1 = fabs(z * b / c);

    /* Get radii for upper z value. */

    z = ClipMax[Z];

    rx2 = fabs(z * a / c);
    ry2 = fabs(z * b / c);

    rx = max(rx1, rx2);
    ry = max(ry1, ry2);

    NewMin[X] = -rx;
    NewMin[Y] = -ry;
    NewMax[X] = rx;
    NewMax[Y] = ry;
  }

  /*
   *
   * Check for hyperboloid (x-axis).
   *
   *    x*x     y*y     z*z
   *   ----- - ----- - ----- + 1 = 0
   *    a*a     b*b     c*c
   *
   */

  if ((A > 0.0) && (E < 0.0) && (H < 0.0) && (J > 0.0))
  {
    /* Get radii for lower x value. */

    x = ClipMin[X];

    d = 1.0 + A * Sqr(x);

    ry1 = sqrt(-d / E);
    rz1 = sqrt(-d / H);

    /* Get radii for upper x value. */

    x = ClipMax[X];

    d = 1.0 + A * Sqr(x);

    ry2 = sqrt(-d / E);
    rz2 = sqrt(-d / H);

    ry = max(ry1, ry2);
    rz = max(rz1, rz2);

    NewMin[Y] = -ry;
    NewMin[Z] = -rz;
    NewMax[Y] = ry;
    NewMax[Z] = rz;
  }

  /*
   *
   * Check for hyperboloid (y-axis).
   * 
   *    x*x     y*y     z*z
   *   ----- - ----- + ----- - 1 = 0
   *    a*a     b*b     c*c
   *
   */

  if ((A > 0.0) && (E < 0.0) && (H > 0.0) && (J < 0.0))
  {
    /* Get radii for lower y value. */

    y = ClipMin[Y];

    d = 1.0 - E * Sqr(y);

    rx1 = sqrt(d / A);
    rz1 = sqrt(d / H);

    /* Get radii for upper y value. */

    y = ClipMax[Y];

    d = 1.0 - E * Sqr(y);

    rx2 = sqrt(d / A);
    rz2 = sqrt(d / H);

    rx = max(rx1, rx2);
    rz = max(rz1, rz2);

    NewMin[X] = -rx;
    NewMin[Z] = -rz;
    NewMax[X] = rx;
    NewMax[Z] = rz;
  }

  /*
   *
   * Check for hyperboloid (z-axis).
   *
   *    x*x     y*y     z*z
   *   ----- + ----- - ----- - 1 = 0
   *    a*a     b*b     c*c
   *
   */

  if ((A > 0.0) && (E > 0.0) && (H < 0.0) && (J < 0.0))
  {
    /* Get radii for lower z value. */

    z = ClipMin[Z];

    d = 1.0 - H * Sqr(z);

    rx1 = sqrt(d / A);
    ry1 = sqrt(d / E);

    /* Get radii for upper z value. */

    z = ClipMax[Z];

    d = 1.0 - H * Sqr(z);

    rx2 = sqrt(d / A);
    ry2 = sqrt(d / E);

    rx = max(rx1, rx2);
    ry = max(ry1, ry2);

    NewMin[X] = -rx;
    NewMin[Y] = -ry;
    NewMax[X] = rx;
    NewMax[Y] = ry;
  }

  /*
   *
   * Check for paraboloid (x-axis).
   *
   *        y*y     z*z
   *   x - ----- - ----- = 0
   *        b*b     c*c
   *
   */

  if ((A == 0.0) && (D != 0.0) && (E != 0.0) && (H != 0.0) && (J == 0.0))
  {
    /* Get radii for lower x value. */

    x = ClipMin[X];

    ry1 = sqrt(fabs(2.0 * D * x / E));
    rz1 = sqrt(fabs(2.0 * D * x / H));

    /* Get radii for upper x value. */

    x = ClipMax[X];

    ry2 = sqrt(fabs(2.0 * D * x / E));
    rz2 = sqrt(fabs(2.0 * D * x / H));

    ry = max(ry1, ry2);
    rz = max(rz1, rz2);

    NewMin[Y] = -ry;
    NewMin[Z] = -rz;
    NewMax[Y] = ry;
    NewMax[Z] = rz;
  }

  /*
   *
   * Check for paraboloid (y-axis).
   *
   *        x*x     z*z
   *   y - ----- - ----- = 0
   *        a*a     c*c
   *
   */

  if ((E == 0.0) && (G != 0.0) && (A != 0.0) && (H != 0.0) && (J == 0.0))
  {
    /* Get radii for lower y-value. */

    y = ClipMin[Y];

    rx1 = sqrt(fabs(2.0 * G * y / A));
    rz1 = sqrt(fabs(2.0 * G * y / H));

    /* Get radii for upper y value. */

    y = ClipMax[Y];

    rx2 = sqrt(fabs(2.0 * G * y / A));
    rz2 = sqrt(fabs(2.0 * G * y / H));

    rx = max(rx1, rx2);
    rz = max(rz1, rz2);

    NewMin[X] = -rx;
    NewMin[Z] = -rz;
    NewMax[X] = rx;
    NewMax[Z] = rz;
  }

  /*
   *
   * Check for paraboloid (z-axis).
   *
   *        x*x     y*y
   *   z - ----- - ----- = 0
   *        a*a     b*b
   *
   */

  if ((H == 0.0) && (I != 0.0) && (A != 0.0) && (E != 0.0) && (J == 0.0))
  {
    /* Get radii for lower z-value. */

    z = ClipMin[Z];

    rx1 = sqrt(fabs(2.0 * I * z / A));
    ry1 = sqrt(fabs(2.0 * I * z / E));

    /* Get radii for upper z value. */

    z = ClipMax[Z];

    rx2 = sqrt(fabs(2.0 * I * z / A));
    ry2 = sqrt(fabs(2.0 * I * z / E));

    rx = max(rx1, rx2);
    ry = max(ry1, ry2);

    NewMin[X] = -rx;
    NewMin[Y] = -ry;
    NewMax[X] = rx;
    NewMax[Y] = ry;
  }

  /* Intersect clipping object's and quadric's bounding boxes */

  NewMin[X] = max(NewMin[X], ClipMin[X]);
  NewMin[Y] = max(NewMin[Y], ClipMin[Y]);
  NewMin[Z] = max(NewMin[Z], ClipMin[Z]);

  NewMax[X] = min(NewMax[X], ClipMax[X]);
  NewMax[Y] = min(NewMax[Y], ClipMax[Y]);
  NewMax[Z] = min(NewMax[Z], ClipMax[Z]);

  /* Use old or new bounding box? */

  New_Volume = (NewMax[X] - NewMin[X]) * (NewMax[Y] - NewMin[Y]) * (NewMax[Z] - NewMin[Z]);

  BOUNDS_VOLUME(Old_Volume, Old);

  if (New_Volume < Old_Volume)
  {
    /* Add translation. */
	Quadric->Automatic_Bounds = true;

    VAddEq(NewMin, T1);
    VAddEq(NewMax, T1);

    Make_BBox_from_min_max(Quadric->BBox, NewMin, NewMax);

    /* Beware of bounding boxes to large. */

    if ((Quadric->BBox.Lengths[X] > CRITICAL_LENGTH) ||
        (Quadric->BBox.Lengths[Y] > CRITICAL_LENGTH) ||
        (Quadric->BBox.Lengths[Z] > CRITICAL_LENGTH))
    {
      Make_BBox(Quadric->BBox, -BOUND_HUGE/2, -BOUND_HUGE/2, -BOUND_HUGE/2,
        BOUND_HUGE, BOUND_HUGE, BOUND_HUGE);
    }
  }
}