home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- * CagdSRev.c - Surface of revolution out of a given profile. *
- *******************************************************************************
- * Written by Gershon Elber, Mar. 91. *
- ******************************************************************************/
-
- #ifdef __MSDOS__
- #include <stdlib.h>
- #include <string.h>
- #include <alloc.h>
- #endif /* __MSDOS__ */
-
- #include "cagd_loc.h"
-
- static int CircKnotVector[12] = { 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4 };
-
- /******************************************************************************
- * Constructs a surface of revolution around the Z axis of the given profile *
- * curve. Resulting surface will be a Bspline surface, while input may be *
- * either a Bspline or a Bezier curve. Curve must be 3d (I.e. P3 or E3). *
- ******************************************************************************/
- CagdSrfStruct *CagdSurfaceRev(CagdCrvStruct *Crv)
- {
- int i, j, i9,
- Len = Crv -> Length;
- CagdPointType
- PType = Crv -> PType;
- CagdRType **SrfPoints,
- sin45 = sin( M_PI / 4.0 ),
- **CrvPoints = Crv -> Points;
- CagdSrfStruct
- *Srf = BspSrfNew(9, Len, 3, Crv -> Order, CAGD_PT_P3_TYPE);
-
- for (i = 0; i < 12; i++)
- Srf -> UKnotVector[i] = (CagdRType) CircKnotVector[i];
-
- switch (Crv -> GType) {
- case CAGD_CBEZIER_TYPE:
- BspKnotUniformOpen(Len, Crv -> Order, Srf -> VKnotVector);
- break;
- case CAGD_CBSPLINE_TYPE:
- GEN_COPY(Srf -> VKnotVector, Crv -> KnotVector, sizeof(CagdRType) *
- (Len + Crv -> Order));
- break;
- case CAGD_CPOWER_TYPE:
- FATAL_ERROR(CAGD_ERR_POWER_NO_SUPPORT);
- return NULL;
- default:
- FATAL_ERROR(CAGD_ERR_UNDEF_CRV);
- return NULL;
- }
-
- SrfPoints = Srf -> Points;
-
- /* For each control point in the original curve - generate 9 points that */
- /* Form a circle perpendicular to the Z axis. */
- for (i = i9 = 0; i < Len; i++, i9 += 9) {
- SrfPoints[W][i9] = 1.0;
- switch (PType) {
- case CAGD_PT_P3_TYPE:
- SrfPoints[W][i9] = CrvPoints[W][i];
- case CAGD_PT_E3_TYPE:
- SrfPoints[X][i9] = CrvPoints[X][i];
- SrfPoints[Y][i9] = CrvPoints[Y][i];
- SrfPoints[Z][i9] = CrvPoints[Z][i];
- break;
- default:
- FATAL_ERROR(CAGD_ERR_UNSUPPORT_PT);
- break;
- }
-
- /* Last point is exactly the same as first one in circle - copy it. */
- for (j = W; j <= Z; j++) SrfPoints[j][i9 + 8] = SrfPoints[j][i9];
-
- /* The Z components are identical in all circle, while the XY */
- /* components are rotated 45 degrees at a time: */
- for (j = 1; j < 8; j++) {
- SrfPoints[W][i9 + j] = SrfPoints[W][i9];
- SrfPoints[X][i9 + j] = SrfPoints[X][i9 + j - 1] * sin45 -
- SrfPoints[Y][i9 + j - 1] * sin45;
- SrfPoints[Y][i9 + j] = SrfPoints[X][i9 + j - 1] * sin45 +
- SrfPoints[Y][i9 + j - 1] * sin45;
- SrfPoints[Z][i9 + j] = SrfPoints[Z][i9];
- }
-
- /* And finally we need to compensate for the W's on every second pt. */
- for (j = 1; j < 8; j += 2) {
- SrfPoints[W][i9 + j] *= sin45;
- SrfPoints[Z][i9 + j] *= sin45;
- }
- }
-
- return Srf;
- }
-