/******************************************************************************
* CagdPrim.c - Primitive surfaces' constructors.                 	      *
*******************************************************************************
* (C) Gershon Elber, Technion, Israel Institute of Technology                 *
*******************************************************************************
* Written by Gershon Elber, Dec. 96.					      *
******************************************************************************/

#include <string.h>
#include "cagd_loc.h"

static CagdPtStruct
    Origin = { NULL, NULL, { 0.0, 0.0, 0.0 } };

/*****************************************************************************
* DESCRIPTION:                                                               M
*   A surface constructor of a sphere, centered at Center and radius Radius. M
*                                                                            *
* PARAMETERS:                                                                M
*   Center:   of constructed sphere.                                         M
*   Radius:   of constructed sphere.                                         M
*   Rational: If TRUE exact ration sphere is created.  If FALSE an	     M
*		 approximated integral surface is created.		     M
*                                                                            *
* RETURN VALUE:                                                              M
*   CagdSrfStruct *:  A Bspline surface representing a sphere.		     M
*                                                                            *
* SEE ALSO:                                                                  M
*   CagdPrimTorusSrf, CagdPrimCone2Srf, CagdPrimConeSrf, CagdPrimCylinderSrf M
*                                                                            *
* KEYWORDS:                                                                  M
*   CagdPrimSphereSrf                                                        M
*****************************************************************************/
CagdSrfStruct *CagdPrimSphereSrf(CagdVType Center,
				 CagdRType Radius,
				 CagdBType Rational)
{
    CagdMType Mat;
    CagdRType TMin, TMax;
    CagdCrvStruct *Arc180,
	*Circle = Rational ? BspCrvCreateUnitCircle() :
			     BspCrvCreateUnitPCircle();
    CagdSrfStruct *Spr;

    CagdCrvDomain(Circle, &TMin, &TMax);
    Arc180 = CagdCrvRegionFromCrv(Circle, TMin, TMin + (TMax - TMin) / 2.0);

    CagdCrvFree(Circle);

    MatGenMatRotY1(M_PI / 2, Mat);		         /* Map to YZ plane. */
    CagdCrvMatTransform(Arc180, Mat);

    if (Rational)
	Spr = CagdSurfaceRev(Arc180);
    else
        Spr = CagdSurfaceRevPolynomialApprox(Arc180);

    CagdCrvFree(Arc180);

    CagdSrfTransform(Spr, Origin.Pt, Radius);
    CagdSrfTransform(Spr, Center, 1.0);

    return Spr;
}

/*****************************************************************************
* DESCRIPTION:                                                               M
*   A surface constructor of a torus, centered at Center and radii of        M
* MajorRadius and MinorRadius.						     M
*                                                                            *
* PARAMETERS:                                                                M
*   Center:        of constructed torus.                                     M
*   MajorRadius:   of constructed torus.                                     M
*   MinorRadius:   of constructed torus.                                     M
*   Rational:      If TRUE exact ration sphere is created.  If FALSE an	     M
*		   approximated integral surface is created.		     M
*                                                                            *
* RETURN VALUE:                                                              M
*   CagdSrfStruct *:  A Bspline surface representing a torus.		     M
*                                                                            *
* SEE ALSO:                                                                  M
*   CagdPrimSphereSrf, CagdPrimCone2Srf, CagdPrimConeSrf,		     M
*   CagdPrimCylinderSrf                                                      M
*                                                                            *
* KEYWORDS:                                                                  M
*   CagdPrimTorusSrf                                                         M
*****************************************************************************/
CagdSrfStruct *CagdPrimTorusSrf(CagdVType Center,
				CagdRType MajorRadius,
				CagdRType MinorRadius,
				CagdBType Rational)
{
    CagdVType Trans;
    CagdMType Mat;
    CagdCrvStruct
	*Circle = Rational ? BspCrvCreateUnitCircle() :
			     BspCrvCreateUnitPCircle();
    CagdSrfStruct *Trs;

    PT_CLEAR(Trans);
    CagdCrvTransform(Circle, Trans, MinorRadius);
    Trans[1] = MajorRadius;
    CagdCrvTransform(Circle, Trans, 1.0);

    MatGenMatRotY1(M_PI / 2, Mat);		         /* Map to YZ plane. */
    CagdCrvMatTransform(Circle, Mat);

    if (Rational)
	Trs = CagdSurfaceRev(Circle);
    else
	Trs = CagdSurfaceRevPolynomialApprox(Circle);

    CagdCrvFree(Circle);

    CagdSrfTransform(Trs, Center, 1.0);

    return Trs;
}

/*****************************************************************************
* DESCRIPTION:                                                               M
*   A surface constructor of a truncated cone, centered at Center and radii  M
* of MajorRadius and MinorRadius. A MinorRadius of zero would construct a    M
* regular cone.  Otherwise, a truncated cone.				     M
*                                                                            *
* PARAMETERS:                                                                M
*   Center:        of constructed cone (center of its base).                 M
*   MajorRadius:   of constructed cone.                                      M
*   MinorRadius:   of constructed cone.                                      M
*   Height:	   of constructed cone.                                      M
*   Rational:      If TRUE exact ration sphere is created.  If FALSE an	     M
*		   approximated integral surface is created.		     M
*                                                                            *
* RETURN VALUE:                                                              M
*   CagdSrfStruct *:  A Bspline surface representing a cone.		     M
*                                                                            *
* SEE ALSO:                                                                  M
*   CagdPrimSphereSrf, CagdPrimTorusSrf, CagdPrimConeSrf,		     M
*   CagdPrimCylinderSrf                                                      M
*                                                                            *
* KEYWORDS:                                                                  M
*   CagdPrimCone2Srf                                                         M
*****************************************************************************/
CagdSrfStruct *CagdPrimCone2Srf(CagdVType Center,
				CagdRType MajorRadius,
				CagdRType MinorRadius,
				CagdRType Height,
				CagdBType Rational)
{
    static CagdPtStruct
	XAxisPt =  { NULL, NULL, { 1.0, 0.0, 0.0 } },
	ZXAxisPt = { NULL, NULL, { 1.0, 0.0, 1.0 } },
	ZAxisPt =  { NULL, NULL, { 0.0, 0.0, 1.0 } };
    CagdSrfStruct *Cone;
    CagdCrvStruct *CrvAux, *CrvAux2, *Cross;

    /* Build the cross section. */
    XAxisPt.Pt[0] = MajorRadius;
    ZXAxisPt.Pt[0] = MinorRadius;
    ZXAxisPt.Pt[2] = Height;
    ZAxisPt.Pt[2] = Height;
    if (APX_EQ(MinorRadius, 0.0)) {
	CrvAux2 = CagdMergePtPt(&XAxisPt, &ZAxisPt);
    }
    else {
	CrvAux = CagdMergePtPt(&ZXAxisPt, &ZAxisPt);
	CrvAux2 = CagdMergePtCrv(&XAxisPt, CrvAux);
	CagdCrvFree(CrvAux);
    }
    Cross = CagdMergePtCrv(&Origin, CrvAux2);
    CagdCrvFree(CrvAux2);

    if (Rational)
	Cone = CagdSurfaceRev(Cross);
    else
	Cone = CagdSurfaceRevPolynomialApprox(Cross);

    CagdCrvFree(Cross);

    CagdSrfTransform(Cone, Center, 1.0);

    return Cone;
}

/*****************************************************************************
* DESCRIPTION:                                                               M
*   A surface constructor of a cone, centered at Center and radii of         M
* MajorRadius and MinorRadius.	A MinorRadius of zero would construct a	     M
* regular cone.  Otherwise, a truncated cone.				     M
*                                                                            *
* PARAMETERS:                                                                M
*   Center:        of constructed cone (center of its base).                 M
*   Radius:        of constructed cone's base.                               M
*   Height:	   of constructed cone.                                      M
*   Rational:      If TRUE exact ration sphere is created.  If FALSE an	     M
*		   approximated integral surface is created.		     M
*                                                                            *
* RETURN VALUE:                                                              M
*   CagdSrfStruct *:  A Bspline surface representing a cone.		     M
*                                                                            *
* SEE ALSO:                                                                  M
*   CagdPrimSphereSrf, CagdPrimTorusSrf, CagdPrimCone2Srf,		     M
*   CagdPrimCylinderSrf                                                      M
*                                                                            *
* KEYWORDS:                                                                  M
*   CagdPrimConeSrf                                                          M
*****************************************************************************/
CagdSrfStruct *CagdPrimConeSrf(CagdVType Center,
			       CagdRType Radius,
			       CagdRType Height,
			       CagdBType Rational)
{
    return CagdPrimCone2Srf(Center, Radius, 0.0, Height, Rational);
}

/*****************************************************************************
* DESCRIPTION:                                                               M
*   A surface constructor of a Cylinder, centered at Center and radii of     M
* Radius and MinorRadius.						     M
*                                                                            *
* PARAMETERS:                                                                M
*   Center:        of constructed Cylinder (center of its base).             M
*   Radius:        of constructed Cylinder.                                  M
*   Height:	   of constructed Cylinder.                                  M
*   Rational:      If TRUE exact ration sphere is created.  If FALSE an	     M
*		   approximated integral surface is created.		     M
*                                                                            *
* RETURN VALUE:                                                              M
*   CagdSrfStruct *:  A Bspline surface representing a cylinder.	     M
*                                                                            *
* SEE ALSO:                                                                  M
*   CagdPrimSphereSrf, CagdPrimTorusSrf, CagdPrimCone2Srf, CagdPrimConeSrf   M
*                                                                            *
* KEYWORDS:                                                                  M
*   CagdPrimCylinderSrf                                                      M
*****************************************************************************/
CagdSrfStruct *CagdPrimCylinderSrf(CagdVType Center,
				   CagdRType Radius,
				   CagdRType Height,
				   CagdBType Rational)
{
    return CagdPrimCone2Srf(Center, Radius, Radius, Height, Rational);
}
