/****************************************************************************** * CBspEval.c - Bezier curves handling routines - evaluation routines. * ******************************************************************************* * Written by Gershon Elber, Mar. 90. * ******************************************************************************/ #ifdef __MSDOS__ #include #endif /* __MSDOS__ */ #include #include #include #include "cagd_loc.h" /****************************************************************************** * Assumes Vec holds control points for scalar bspline curve of order Order * * length Len and knot vector KnotVector. * * Evaluates and returns that curve value at parameter value t. * * Vec is incremented by VecInc (usually by 1) after each iteration. * ******************************************************************************/ CagdRType BspCrvEvalVecAtParam(CagdRType *Vec, int VecInc, CagdRType *KnotVector, int Order, int Len, CagdRType t) { int i, IndexFirst; CagdRType R = 0.0, *BasisFunc = BspCrvCoxDeBoorBasis(KnotVector, Order, Len, t, &IndexFirst); if (VecInc == 1) { Vec += IndexFirst; for (i = 0; i < Order; i++) R += BasisFunc[i] * *Vec++; } else { Vec += IndexFirst * VecInc; for (i = 0; i < Order; i++) { R += BasisFunc[i] * *Vec; Vec += VecInc; } } return R; } /****************************************************************************** * Returns a pointer to a static data, holding the value of the curve at given * * parametric location t. The curve is assumed to be Bspline. * * Uses the Cox de Boor recursive algorithm (is this fastest for single eval?) * ******************************************************************************/ CagdRType *BspCrvEvalAtParam(CagdCrvStruct *Crv, CagdRType t) { return BspCrvEvalCoxDeBoor(Crv, t); } /****************************************************************************** * Samples the curves at FineNess location equally spaced in the Bspline * * parametric domain. * * Currently uses the Cox de Boor evaluation. * * Returns the actual number of points in polyline (<= FineNess). * ******************************************************************************/ int BspCrvEvalToPolyline(CagdCrvStruct *Crv, int FineNess, CagdRType *Points[]) { CagdBType IsNotRational = !CAGD_IS_RATIONAL_CRV(Crv); int i, Count, NumC1Disconts, n = 1 << FineNess, Len = Crv -> Length, MaxCoord = CAGD_NUM_OF_PT_COORD(Crv -> PType); CagdRType *Pt, *C1Disconts, *IsoParams, t, TMin, TMax; if (Crv -> Order == 2) { /* Simply copy the control polygon. */ CagdRType **CrvPoints = Crv -> Points; for (Count = 0; Count < n && Count < Len; Count++) for (i = IsNotRational; i <= MaxCoord; i++) Points[i][Count] = CrvPoints[i][Count]; return Count; } BspCrvDomain(Crv, &TMin, &TMax); /* Compute discontinuities along the u axis and use that to determine */ /* where to extract isolines along u. */ C1Disconts = BspKnotAllC1Discont(Crv -> KnotVector, Crv -> Order, Crv -> Length, &NumC1Disconts); IsoParams = BspKnotParamValues(TMin, TMax, n, C1Disconts, NumC1Disconts); for (Count = 0; Count < n; Count++) { t = IsoParams[Count]; Pt = BspCrvEvalAtParam(Crv, t); for (i = IsNotRational; i <= MaxCoord; i++) Points[i][Count] = Pt[i]; } CagdFree((VoidPtr) IsoParams); return n; }