PK_TORUS_sf_t   



struct PK_TORUS_sf_s
    {
    PK_AXIS2_sf_t basis_set;    --- centre, axis and a reference direction
    double        major_radius; --- the major radius of the torus(!=0)
    double        minor_radius; --- the minor radius of the torus(>0)
    };

typedef struct PK_TORUS_sf_s PK_TORUS_sf_t;



Specific Errors:
PK_ERROR_radius_sum_le_0        sum of radii less than or equal to zero
PK_ERROR_radius_le_0           minor_radius less than or equal to zero
PK_ERROR_radius_eq_0           major_radius equals zero



The parameterisation of the torus is as follows:

    C = basis_set.location
    x = basis_set.ref_direction
    y = basis_set.axis X basis_set.ref_direction ( cross product )
    z = basis_set.axis
    R = major_radius
    r = minor_radius

    S(u, v) = C + (R + r(cos v))( ( cos u )x + ( sin u )y ) + r( sin v )z

                               where  ( 0 <= u < 2PI; -PI <= v < PI )

For certain choices of major_radius and minor_radius the torus will
self-intersect.  There are two cases for self-intersecting surfaces.

    The first case produces an inner and an outer surface.  The inner surface
    is called a lemon, while the outer surface is called an apple.  Each
    surface is bounded by two singular points, where the normal is undefined,
    and treated as a separate surface.

    The second case produces an outer surface only.  This apple has only one
    singular point, on its axis of rotation.

An apple is created by setting major_radius positive and less than or equal
to minor_radius.  If, on the other hand, major_radius is negative and the
sum of the radii is positive then a lemon is produced.