DEMO.DESIGN
Frequently Asked Questions
 
оглавление | demo party в ex-СССР | infused bytes e-mag | новости от ib/news | другие проекты | письмо | win koi lat

следующий фpагмент (2)
- Usenet echoes (21:200/1) -------------------------- COMP.GRAPHICS.ALGORITHMS - Msg : 128 of 138 From : ess@netcom.com 2:5030/144.99 18 Aug 94 18:03:48 To : All 21 Sep 93 01:36:22 Subj : (1) NURBS curve evaluator -------------------------------------------------------------------------------- Ive been asked a couple times for the code/algorithm for evaluating a NURBS curve at a given parameter. Ive included some C source below from my NURBS library (although the code below is in old-style C and the library is in C++). Its a very fast and simple evaluator for a NURBS curve at a given parameter. You can use the code for whatever you want, just give some credit to the author. ESS -$- /* A fast and clean NURBS curve evaluator for evaluating a curve at a given parameter - Eric Swildens 1994 */ typedef struct PNurbCurve_struct { int p; /* degree */ double *knot; /* knot vector */ int m; /* num of knots: m=n+p+1*/ double (*cp)[4]; /* control points: x,y,z,w */ int n; /* num of control points */ } *PNurbCurve; #ifdef PROTO void PNurb_eval(double c[][4], double knot[], double t, \ int d, int k, double p[]); void PNurbCurve_eval(PNurbCurve n, double t, double p[]); #endif PNurbCurve PNurbCurve_new(p, knot, cp, n) int p; /* degree */ double knot[]; /* knot vector */ double cp[][4]; /* control points */ int n; /* num of control points */ { PNurbCurve nc; int loop,size; nc = (PNurbCurve)malloc(sizeof(struct PNurbCurve_struct)); nc->p = p; /* calculate number of knots and copy knot vector */ nc->m = n + p + 1; nc->knot = (double *)malloc(sizeof(double) * nc->m); for (loop=0; loop<nc->m; loop++) nc->knot[loop] = knot[loop]; /* copy control points */ nc->n = n; size = sizeof(double) * nc->n * 4; nc->cp = (double (*)[4])malloc(size); for (loop=0; loop<nc->n; loop++) { nc->cp[loop][0] = cp[loop][0]; nc->cp[loop][1] = cp[loop][1]; nc->cp[loop][2] = cp[loop][2]; nc->cp[loop][3] = cp[loop][3]; } return(nc); } void PNurb_eval(c,knot,t,d,k,p) double c[][4]; /* control points */ double knot[]; /* knot vector */ double t; /* parameter */ int d; /* degree */ int k; /* location of insert knot */ double p[]; /* point */ { int i,r,s,s1; double o,o1; for (r=d+1; r>1; r--) { i = k - 1; s1 = 1; for (s=0; s<r-1; s++) { o = (knot[i+r-1] - knot[i]); if (o > 0.0) { o = (t - knot[i]) / o; o1 = 1.0 - o; c[s][0] = o*c[s][0] + o1*c[s1][0]; c[s][1] = o*c[s][1] + o1*c[s1][1]; c[s][2] = o*c[s][2] + o1*c[s1][2]; c[s][3] = o*c[s][3] + o1*c[s1][3]; } else { c[s][0] = c[s1][0]; c[s][1] = c[s1][1]; c[s][2] = c[s1][2]; c[s][3] = c[s1][3]; } i--; s1++; } } if (c[0][3] == 0.0) { /* ERROR IF THIS HAPPENS */ return; } if (c[0][3] < 0.0) c[0][3] = -c[0][3]; p[0] = c[0][0] / c[0][3]; p[1] = c[0][1] / c[0][3]; p[2] = c[0][2] / c[0][3]; } void PNurbCurve_eval(n,t,p) PNurbCurve n; double t; /* parameter [0..1) */ double p[]; /* point returned */ /* Based on: An Introduction to Splines for Use in Computer Graphics and Geometric Modeling, pg. 392 */ { double (*c)[4]; int i,k,s,size; k = n->p; while (t >= n->knot[k++]) ; k--; size = sizeof(double) * (n->p + 1) * 4; c = (double (*)[4])malloc(size); i = k - 1; for (s=0; s<n->p+1; s++) { c[s][3] = n->cp[i][3]; c[s][0] = n->cp[i][0] * c[s][3]; c[s][1] = n->cp[i][1] * c[s][3]; c[s][2] = n->cp[i][2] * c[s][3]; i--; } PNurb_eval(c,n->knot,t,n->p,k,p); free((char *)c); } main() { PNurbCurve c; double i; static double knot[10] = { 0.0, 0.0, 0.0, .25, .5, .5, .75, 1.0, 1.0, 1.0}; static double cp[][4] = { { 1.0, 0.0, 0.0, 1.0 }, { 1.0, 1.0, 0.0, 0.5 }, { -1.0, 1.0, 0.0, 0.5 }, { -1.0, 0.0, 0.0, 1.0 }, { -1.0, -1.0, 0.0, 0.5 }, { 1.0, -1.0, 0.0, 0.5 }, { 1.0, 0.0, 0.0, 1.0 } }; double point[3]; c = PNurbCurve_new(2, knot, cp, 7); /* Note that the parameterization for the sample NURBS circle here is non-linear. That means that evaluating .25 wont give you the point at 45 degrees. */ for (i = 0.0; i < 1.0; i += .1) { PNurbCurve_eval(c, i, point); printf ("%f: %f %f %f\n", i, point[0], point[1], point[2]); } }

Всего 1 фpагмент(а/ов) |пpедыдущий фpагмент (1)

Если вы хотите дополнить FAQ - пожалуйста пишите.

design/collection/some content by Frog,
DEMO DESIGN FAQ (C) Realm Of Illusion 1994-2000,
При перепечатке материалов этой страницы пожалуйста ссылайтесь на источник: "DEMO.DESIGN FAQ, http://www.enlight.ru/demo/faq".