Example #1
0
void Cone::Compute_Cone_Data()
{
    DBL tlen, len, tmpf;
    Vector3d tmpv, axis, origin;

    /* Process the primitive specific information */

    /* Find the axis and axis length */

    axis = apex - base;

    len = axis.length();

    if (len < EPSILON)
    {
        throw POV_EXCEPTION_STRING("Degenerate cone/cylinder."); // TODO FIXME - should a possible error
    }
    else
    {
        axis /= len;
    }
    /* we need to trap that case first */
    if (fabs(apex_radius - base_radius) < EPSILON)
    {
        /* What we are dealing with here is really a cylinder */

        Set_Flag(this, CYLINDER_FLAG);

        Compute_Cylinder_Data();

        return;
    }

    if (apex_radius < base_radius)
    {
        /* Want the bigger end at the top */

        tmpv = base;
        base = apex;
        apex = tmpv;

        tmpf = base_radius;
        base_radius = apex_radius;
        apex_radius = tmpf;
        axis.invert();
    }
    /* apex & base are different, yet, it might looks like a cylinder */
    tmpf = base_radius * len / (apex_radius - base_radius);

    origin = base - axis * tmpf;

    tlen = tmpf + len;
    /* apex is always bigger here */
    if (((apex_radius - base_radius)*len/tlen) < EPSILON)
    {
        /* What we are dealing with here is really a cylinder */

        Set_Flag(this, CYLINDER_FLAG);

        Compute_Cylinder_Data();

        return;
    }

    dist = tmpf / tlen;
    /* Determine alignment */
    Compute_Coordinate_Transform(Trans, origin, axis, apex_radius, tlen);

    /* Recalculate the bounds */

    Compute_BBox();
}
Example #2
0
void Compute_Cone_Data(OBJECT *Object)
{
  DBL tlen, len, tmpf;
  VECTOR tmpv, axis, origin;
  CONE *Cone = (CONE *)Object;

  /* Process the primitive specific information */

  if (fabs(Cone->apex_radius - Cone->base_radius) < EPSILON)
  {
    /* What we are dealing with here is really a cylinder */

    Set_Flag(Cone, CYLINDER_FLAG);

    Compute_Cylinder_Data(Object);

    return;
  }

  if (Cone->apex_radius < Cone->base_radius)
  {
    /* Want the bigger end at the top */

    Assign_Vector(tmpv,Cone->base);
    Assign_Vector(Cone->base,Cone->apex);
    Assign_Vector(Cone->apex,tmpv);

    tmpf = Cone->base_radius;
    Cone->base_radius = Cone->apex_radius;
    Cone->apex_radius = tmpf;
  }

  /* Find the axis and axis length */

  VSub(axis, Cone->apex, Cone->base);

  VLength(len, axis);

  if (len < EPSILON)
  {
    Error("Degenerate cone/cylinder.");
  }
  else
  {
    VInverseScaleEq(axis, len);
  }

  /* Determine alignment */

  tmpf = Cone->base_radius * len / (Cone->apex_radius - Cone->base_radius);

  VScale(origin, axis, tmpf);

  VSub(origin, Cone->base, origin);

  tlen = tmpf + len;

  Cone->dist = tmpf / tlen;

  Compute_Coordinate_Transform(Cone->Trans, origin, axis, Cone->apex_radius, tlen);

  /* Recalculate the bounds */

  Compute_Cone_BBox(Cone);
}