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