/****************************************************************************** * CagdSRev.c - Surface of revolution out of a given profile. * ******************************************************************************* * Written by Gershon Elber, Mar. 91. * ******************************************************************************/ #ifdef __MSDOS__ #include #include #include #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; }