Home Up Feedback Contents Search | ||
Lucrarea nr.7 Curbe de aproximare si interpolare: |
A.Descriere1. Puncte de controlEcuatiile analitice ale curbelor care descriu formele diverselor obiecte reale sunt de cele mai multe ori deosebit de complicate. In aceasta situatie este insa suficient sa cunoastem un set de puncte ale curbei respective si sa incercam sa conectam aceste puncte printr-o curba a carei ecuatie analitica este in general simpla. Aceste puncte le vom numi in continuare puncte de control. In grafica pe calculator, ceea ce prezinta interes in primul rand este aspectul vizual al curbei reprezentate si mai putin proprietatile sale matematice. Pronind de la un set de puncte de control, constructia unei curbe controlate de acestea poate fi realizata utilizand metode de interpolare sau de aproximare. In primul caz, curba obtinuta va trece prin punctele de control. In cel de-al doilea caz, curba nu va mai trece in mod necesar prin punctele de control ci prin vecinatatea acestora: 2. Curbe BezierO curba Bezier plana este o curba neteda care este definita prin n puncte specificate prin coordonatele carteziene Xi, Yi. In forma parametrica, este data de ecuatiile: Functiile Bk,m sunt functii polinomiale Bernstein: Se observa ca x(0) = x1, x(1) = xn, y(0) = y1, y(1) = yn, deci curba porneste de la primul punct de control si sfarseste la ultimul. Curba Bezier nu trece in mod necesar prin alt punct de control dar are proprietatea de a se mentine tot timpul in interiorul poligonului convex definit de aceste puncte. Utilizand o secventa de curbe Bezier de grad 3 se obtine o curba de aproximare formata din portiuni avand proprietatea de a trece prin punctele Pi si Pi+3 ale setului de puncte din control panta tangentei la curba in punctul Pi+3, ceea ce permite constructia unei curbe ce trece printr-un set de puncte avand forma controlata de punctele intermediare: Prin alegerea punctelor P2, P3, P4 coliniare se va obtine aspectul neted al curbei in P3. Utilizand forma parametrica cu 0 <= t <=1 pentru fiecare curba componenta Ci determinata de punctele [Pi, Pi+1, Pi+2, Pi+3], vom avea: Atunci cand parametrul t parcurge intervalul [0,1], formula de mai sus furnizeaza punctele curbei dintre punctul corespunzator punctului de control Pi si cel corespunzator lui Pi+1. Curba finala se obtine prin trasarea segmentelor de curba pentru valorile i=1, i=4, …, i=3*(j-1)+1.
B. Implementare/*======================================================================*/ /* G2Dcurbe.h */ /*======================================================================*/ /* contine rutine pentru trasarea curbelor Bezier */ /*----------------------------------------------------------------------*/ /* * Traseaza curba Bezier generala controlata de un set de puncte de * control incluse in fisierul "nume_set"; curba este aproximata * prin 'ns' segmente de dreapta. */ extern void curba_Bezier (char *nume_set, int ns); /*======================================================================*/ /* End of G2Dcurbe.h */ /*======================================================================*/ /*======================================================================*/ /* G2Dcurbe.c */ /*======================================================================*/ /* contine rutine pentru trasarea curbelor Bezier */ /*----------------------------------------------------------------------*/ #include <stdio.h> #include <errno.h> #include "G2Dnucleu.h" #include "G2Dprimitive.h" #include "G2Dcurbe.h" static lista_puncte lista; #define MAXB 20 typedef double coeficienti[MAXB]; static coeficienti coef_bezier; /* Prototipuri Private -------------------------------------------------*/ static void citeste_puncte (char *nume_set); static void traseaza (int ns); static void calculeaza_coeficienti (int m); static void punct_Bezier (double t, double *px, double *py); static double valoare (int m, int k, double t); /* Rutine Publice ------------------------------------------------------*/ /* * Traseaza curba Bezier generala controlata de un set de puncte de * control incluse in fisierul "nume_set"; curba este aproximata * prin 'ns' segmente de dreapta. */ void curba_Bezier (char *nume_set, int ns) { citeste_puncte (nume_set); traseaza (ns); } /* curba_Bezier */ /* Rutine Private ------------------------------------------------------*/ static void citeste_puncte (char *nume_set) { /* * Citeste punctele de control din fisierul text cu numele dat de * parametrul nume_set si le stocheaza in variabila 'lista' */ } /* citeste_puncte */ /* * Se considera domeniul de variatie al parametrului ca fiind * impartit intr-un numar de 'ns' intervale egale; se calculeaza * punctele curbei in capetele subintervalelor si se unesc * prin segmente de dreapta. */ static void traseaza (int ns) { double x1, y1; double x2, y2; int i; if (lista.n > 0) { calculeaza_coeficienti (lista.n-1); punct_Bezier (0.0, &x1, &y1); for (i = 0; i < ns; i++) { punct_Bezier ((i+1.0)/ns, &x2, &y2); linie_2d (x1, y1, x2, y2); x1 = x2; y1 = y2; } } } /* traseaza */ static void calculeaza_coeficienti (int m) { int k; coef_bezier[0] = 1.0; for (k = 1; k < (m+1); k++) { coef_bezier[k] = coef_bezier[k-1] * (m-k+1) / k; } } /* calculeaza_coeficienti */ static void punct_Bezier (double t, double *px, double *py) { double bv; int k, m; *px = 0.0; *py = 0.0; m = lista.n - 1; for (k = 0; k < (m+1); k++) { bv = valoare (m, k, t); *px += bv * lista.x[k]; *py += bv * lista.y[k]; } } /* punct_Bezier */ static double valoare (int m, int k, double t) { double bv; double v; int i; bv = coef_bezier[k]; for (i = 1; i <= k; i++) { bv *= t; } v = 1.0 - t; for (i = 1; i <= m-k; i++) { bv *= v; } return (bv); } /* valoare */ /*======================================================================*/ /* End of G2Dcurbe.c */ /*======================================================================*/ Download G2Dcurbe.h, G2Dcurbe.c. C. Aplicatii
a) 0,20 5,15 10,10 12,12 15,-1 20,-10 25,-15 30,-10 35,10 b) 5,20 10,15 15,20 20,0 25,-5 22,7 18,-5 15,0 22,10 30,15 35,20 c) 30,40 25,35 20,25 25,15 30,10 35,8 40,15 45,5 40,35 35,37 30,40 (curba inchisa)
|
[ Home ][ Up ][ Previous ][ Next ] Send mail to sorin@aspc.cs.utt.ro
with questions or comments about this web site.
|