Beispiel #1
0
void Cone::Compute_Cylinder_Data()
{
    DBL tmpf;
    Vector3d axis;

    axis = apex - base;

    tmpf = axis.length();

    if (tmpf < EPSILON)
    {
        throw POV_EXCEPTION_STRING("Degenerate cylinder, base point = apex point."); // TODO FIXME - should a possible error
    }
    else
    {
        axis /= tmpf;

        Compute_Coordinate_Transform(Trans, base, axis, apex_radius, tmpf);
    }

    dist = 0.0;

    /* Recalculate the bounds */

    Compute_BBox();
}
void Compute_Cylinder_Data(OBJECT *Object)
{
  DBL tmpf;
  VECTOR axis;
  CONE *Cone = (CONE *)Object;

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

  VLength(tmpf, axis);

  if (tmpf < EPSILON)
  {
    Error("Degenerate cylinder, base point = apex point.");
  }
  else
  {
    VInverseScaleEq(axis, tmpf);

    Compute_Coordinate_Transform(Cone->Trans, Cone->base, axis, Cone->apex_radius, tmpf);
  }

  Cone->dist = 0.0;

  /* Recalculate the bounds */

  Compute_Cone_BBox(Cone);
}
Beispiel #3
0
void Lemon::Compute_Lemon_Data(GenericMessenger& messenger, pov_base::ITextStream *FileHandle, pov_base::ITextStream::FilePos & Token_File_Pos, int Token_Col_No )
{
    DBL len;
    Vector3d axis;

    /* 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 lemon.");
    }
    else
    {
        axis /= len; //normalize
    }
    /* adjust the various radius */
    apex_radius /= len;
    base_radius /= len;
    inner_radius /= len;
    /* Determine alignment and scale */
    Compute_Coordinate_Transform(Trans, base, axis, len, len);

    /* check constraint on inner_radius before solving the system of equation to find the
     * center of the minor circle of the torus
     *
     * base is at origin (0,0)
     * apex is at (0,1)
     * let's note base_radius as a, a>=0
     * let's note apex_radius as b, b>=0
     * let's note inner_radius as r, r>=0
     * center of minor circle is at (x,y), with x<=0
     *
     * (x-a)^2 + y^2 - r^2 = 0  : minor circle must pass on circle at base
     * (x-b)^2 + (1-y)^2 - r^2 = 0 : minor circle must pass on circle at apex
     *
     * r must be equal or greater than sqrt( a^4-2a^2(b^2-1)+(b^2+1)^2 ) / 2
     *
     * then with f = sqrt((a^2-2ab+b^2-4r^2+1)/(a^2-2ab+b^2+1))
     *
     *     x = (a+b-f)/2
     *     y = (f(b-a)+1)/2
     */
    DBL low = sqrt(base_radius*base_radius*base_radius*base_radius - 2*base_radius*base_radius*(apex_radius*apex_radius-1.0)+(apex_radius*apex_radius+1.0)*(apex_radius*apex_radius+1.0))/2.0;
    if (inner_radius < low )
    {
        std::stringstream o;
        inner_radius = low;
        o << "Inner (last) radius of lemon is too small. Minimal would be "<< (inner_radius*len) << ". Value has been adjusted.";
        messenger.WarningAt(kWarningGeneral, FileHandle->name(), Token_File_Pos.lineno, Token_Col_No, FileHandle->tellg().offset,"%s",o.str().c_str());
    }

    DBL f = sqrt(-(base_radius*base_radius-2.0*base_radius*apex_radius+apex_radius*apex_radius-4.0*inner_radius*inner_radius+1.0)/(base_radius*base_radius-2.0*base_radius*apex_radius+apex_radius*apex_radius+1.0));
    /*
     * Attention: valid HorizontalPosition is negative, always (or null)
     * It is of particular importance when using with torus evaluation and normal computation
     */
    HorizontalPosition = (base_radius+apex_radius-f)/2.0;
    VerticalPosition = ((apex_radius-base_radius)*f+1.0)/2.0;
}
Beispiel #4
0
void Disc::Compute_Disc()
{
    Compute_Coordinate_Transform(Trans, center, normal, 1.0, 1.0);

    Compute_BBox();
}
Beispiel #5
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();
}
Beispiel #6
0
void Compute_Disc(DISC *Disc)
{
  Compute_Coordinate_Transform(Disc->Trans, Disc->center, Disc->normal, 1.0, 1.0);

  Compute_Disc_BBox(Disc);
}
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);
}