From: <gab...@an...> - 2001-08-23 14:58:42
|
bon, comme mon précédent mail sur les courbes de bezier à fait un malheur, j'en remet une couche ! en fait, j'ait fait les calculs, et il se trouve que si on prend l'absice du bout des tangentes = à 1/3, alors on peut directement exprimer la valeur de la keyframe (par ex. x) en fonction du temps avec les formules classiques : /* t est dans 0,1 */ float CalculMoiX(Real32 t) { Real32 x0 = rVal0; // valeur de départ Real32 x1 = rVal0 + 0.33f*rSpeed0; // ordonnee du 1er point de controle Real32 x2 = rValEnd_ - 0.33f*rSpeed1; // ordonnee du 1er point de controle Real32 x3 = rValEnd_; // valeur de fin rCoef_[0] = x0; // 1er coef du polynome rCoef_[1] = 3*x1 - 3*x0; // 2e coef rCoef_[2] = 3*x2 - 6*x1 + 3*x0; // ... rCoef_[3] = x3 - 3*x2 + 3*x1 - x0; return rCoef_[0] + (rCoef_[1] + (rCoef_[2] + rCoef_[3]*t)*t)*t; } le probleme, c'est que dans le cas général, on peut déplacer le bout de la tangente, de telle sorte que son absice ne soit pas en 0.3333 ... dans ce cas la, on est obligé de calculer X et t en fonction d'un 3e paramètre, disons w, qui parcours [0,1], mais qui n'est pas égal au temps 't' si les tangentes ne font pas 1/3 sur les absisces. Voilà les deux fonctions (ce sont les mêmes ...) /* w est dans 0,1 rVal0 est la valeur de départ rVal1 est la valeur de fin rSpeed0 est la dérivée au départ (ie.pente de la tangente). rSpeed1 est la dérivée a la fin (ie.pente de la tangente). */ float CalculMoiX(Real32 w) { Real32 x0 = rVal0; // valeur de départ Real32 x1 = rVal0 + 0.33f*rSpeed0; // ordonnee du 1er point de controle Real32 x2 = rVal1- 0.33f*rSpeed1; // ordonnee du 1er point de controle Real32 x3 = rVal1; // valeur de fin rCoef_[0] = x0; // 1er coef du polynome rCoef_[1] = 3*x1 - 3*x0; // 2e coef rCoef_[2] = 3*x2 - 6*x1 + 3*x0; // ... rCoef_[3] = x3 - 3*x2 + 3*x1 - x0; return rCoef_[0] + (rCoef_[1] + (rCoef_[2] + rCoef_[3]*w)*w)*w; } /* w est dans 0,1 t0 est la valeur du temps au départ (en général, t0=0) t1 est la valeur du temps du 1er point de controle (en général, t1=0.333, mais PAS TOUJOURS !!!) t2 est la valeur du temps du 2e point de controle (en général, t2=0.666, mais PAS TOUJOURS !!!) t3 est la valeur du temps de fin (en général, t3=1) */ float CalculMoiT(Real32 w) { Real32 x0 = t0; Real32 x1 = t1; Real32 x2 = t2; Real32 x3 = t3; rCoef_[0] = x0; // 1er coef du polynome rCoef_[1] = 3*x1 - 3*x0; // 2e coef rCoef_[2] = 3*x2 - 6*x1 + 3*x0; // ... rCoef_[3] = x3 - 3*x2 + 3*x1 - x0; return rCoef_[0] + (rCoef_[1] + (rCoef_[2] + rCoef_[3]*w)*w)*w; } le fait est que, comme par magie, quand t0=0 t1=0.33 t2=0.66 t3=1 bein la fonction CalculMoiT est l'identité, cad. que l'on a t=w ! C'est pour ça que dans le cas 0.33, bein la technique de Sanx marche, à savoir que l'on chope directos X à partir de t ! mais dans le cas général, c'est faux, on est obligé de calculer toute la courbe 2d pour ensuite déterminer le bon w qui correspond au t choisi, et enfin calculer X. voilà, je pense que ce mail met à jour pas mal de choses obscures sur le fonctionnement des bezier, enfin, je suis assez fier d'avoir résolu tout seul le problème. Sanx, tu vois ce que je veux dire ? c'est vrai que c'est franchement cho à expliquer comme pbm (meme genre que les problèmes d'orientation de camera ...). gabriel |
From: Laurent M. <lau...@fx...> - 2001-08-23 20:14:15
|
> bon, comme mon pr=E9c=E9dent mail sur les courbes de bezier =E0 fait un m= alheur, > j'en remet une couche ! h=E9h=E9, tu l'as dit ;) > bein la fonction CalculMoiT est l'identit=E9, cad. que l'on a t=3Dw ! C'e= st pour > =E7a que dans le cas 0.33, bein la technique de Sanx marche, =E0 savoir q= ue l'on > chope directos X =E0 partir de t ! Tu as vraiment vu le code qu'il y a dans mon moteur ? Ou tu dis ca comme ca ? > Sanx, tu vois ce que je veux dire ? c'est vrai que c'est franchement cho = =E0 > expliquer comme pbm (meme genre que les probl=E8mes d'orientation de came= ra > ...). Bien en fait je ne pige pas tout. Moi je fais (ou plutot je faisais) comme ca, le r=E9sultat donne bien des bezier splines, mais quand je reccup=E9rais les valeurs de 3DS MAX ca d=E9lirait car les valeurs ne voulaient rien dire (enfin, faut que je revois ca avec plus de recul). // Bezier (carefull with D3D vector are in row) const vrMatrix vrInterpBezierMatrix ( -1, 3, -3, 1, 3, -6, 3, 0, -3, 3, 0, 0, 1, 0, 0, 0=09 ); // Interpolate Matrix4 Spline Methods (Hermite, Bezier, ...) float vrInterpMatrixFloat(const float t, const float v1, const float v2, const float v3, const float v4, const vrMatrix &m) { vrVect4 time, res; =09 time.x =3D t*t*t; time.y =3D t*t; time.z =3D t, time.w =3D 1; D3DXVec4Transform(&res, &time, &m); =09 return res.x*v1+res.y*v2+res.z*v3+res.w*v4; } avant je faisais ca (au d=E9but) ! et puis en fait je viens de regarder le code, et je me souvenais plus que j'avais fait ca au final : // Interpolate Bezier Spline float vrInterpBezierFloat(const float t, const float c1, const float c2, const float c3, const float c4) { float ab, bc, cd, abbc, bccd; ab =3D vrInterpLinFloat(t, c1, c2); bc =3D vrInterpLinFloat(t, c2, c3); cd =3D vrInterpLinFloat(t, c3, c4); abbc =3D vrInterpLinFloat(t, ab, bc); bccd =3D vrInterpLinFloat(t, bc, cd); return vrInterpLinFloat(t, abbc, bccd); } Et pour la 3D, c'est de la 3x1D. tu peux trouver le code dans vrAnimControler.hpp et .cpp, dans le rep Engine du moteur 3d que je t'avais pass=E9 =E0 l'=E9poque. Je sais qu'au niveau du design c'est (tr=E8s) laid. Pour ma nouvelle version du moteur je ne gererai plus les bezier spline avant un bon moment, juste les TCB que je convertirai en Hermite, comme =E0 l'ancienne ;) A+ Sanx, -- Laurent MASCHERPA (Sanx / FX Team) President of Epidemic : Epita Demoscene Organization lau...@fx... - http://sanx.fxteam.net |
From: Gabriel Peyr <nik...@wa...> - 2001-08-24 08:24:43
|
pour la 1ere m=E9thode : je suis formel : =E7a ne donne pas le m=EAme r=E9= sultat qu'un vrai spline : plus tes tangentes s'=E9loignent de l'horizonta= le, plus la vitesse de parcours du spline va =EAtre d=E9form=E9e. pour la 2e : tu utilises une =E9valuation r=E9cursive (midpoint), mais av= ec juste 2 it=E9rations, tu es s=FBr que =E7a donne un bon r=E9sultat =3F en tout cas, cette m=E9thode donne bien un spline, mais elle n'est pas concern=E9e par les remarques du pr=E9c=E9dent mail (pour = le 1/3). gabriel >Messsage du 23/08/2001 22:12 >De : <ori...@li...> >A : <ori...@li...> >Copie =E0 : >Objet : Re: [Orion3d-dev] bezier once again. > > > bon, comme mon pr=E9c=E9dent mail sur les courbes de bezier =E0 fait = un malheur, > > j'en remet une couche ! > h=E9h=E9, tu l'as dit ;) > > > bein la fonction CalculMoiT est l'identit=E9, cad. que l'on a t=3Dw != C'est pour > > =E7a que dans le cas 0.33, bein la technique de Sanx marche, =E0 savo= ir que l'on > > chope directos X =E0 partir de t ! > Tu as vraiment vu le code qu'il y a dans mon moteur =3F Ou tu dis ca > comme ca =3F > > > Sanx, tu vois ce que je veux dire =3F c'est vrai que c'est franchemen= t cho =E0 > > expliquer comme pbm (meme genre que les probl=E8mes d'orientation de = camera > > ...). > Bien en fait je ne pige pas tout. > > Moi je fais (ou plutot je faisais) comme ca, le r=E9sultat donne bien > des bezier splines, mais quand je reccup=E9rais les valeurs de 3DS MAX > ca d=E9lirait car les valeurs ne voulaient rien dire (enfin, faut que j= e > revois ca avec plus de recul). > > > // Bezier (carefull with D3D vector are in row) > const=09vrMatrix=09vrInterpBezierMatrix > ( > =09-1,=093,=09-3,=091, > =093,=09-6,=093,=090, > =09-3,=093,=090,=090, > =091,=090,=090,=090=09 > ); > > // Interpolate Matrix4 Spline Methods (Hermite, Bezier, ...) > float=09vrInterpMatrixFloat(const float t, const float v1, > =09const float v2, const float v3, const float v4, const vrMatrix &m) > { > =09vrVect4 time, res; > =09 > =09time.x =3D t*t*t; time.y =3D t*t; time.z =3D t, time.w =3D 1; > =09D3DXVec4Transform(&res, &time, &m); > =09 > =09return=09res.x*v1+res.y*v2+res.z*v3+res.w*v4; > } > > avant je faisais ca (au d=E9but) ! > > et puis en fait je viens de regarder le code, et je me souvenais plus > que j'avais fait ca au final : > > // Interpolate Bezier Spline > float=09vrInterpBezierFloat(const float t, const float c1, > =09const float c2, const float c3, const float c4) > { > =09float=09ab, bc, cd, abbc, bccd; > > =09ab =3D vrInterpLinFloat(t, c1, c2); > =09bc =3D vrInterpLinFloat(t, c2, c3); > =09cd =3D vrInterpLinFloat(t, c3, c4); > =09abbc =3D vrInterpLinFloat(t, ab, bc); > =09bccd =3D vrInterpLinFloat(t, bc, cd); > > =09return vrInterpLinFloat(t, abbc, bccd); > } > > Et pour la 3D, c'est de la 3x1D. > > tu peux trouver le code dans vrAnimControler.hpp et .cpp, dans le rep > Engine du moteur 3d que je t'avais pass=E9 =E0 l'=E9poque. Je sais qu'a= u > niveau du design c'est (tr=E8s) laid. Pour ma nouvelle version du moteu= r > je ne gererai plus les bezier spline avant un bon moment, juste les > TCB que je convertirai en Hermite, comme =E0 l'ancienne ;) > > A+ > > Sanx, > -- > Laurent MASCHERPA (Sanx / FX Team) > President of Epidemic : Epita Demoscene Organization > lau...@fx... - http://sanx.fxteam.net > > > _______________________________________________ > Orion3d-dev mailing list > Ori...@li... > http://lists.sourceforge.net/lists/listinfo/orion3d-dev > |
From: Laurent M. <lau...@fx...> - 2001-08-24 19:33:08
|
> pour la 2e : tu utilises une =E9valuation r=E9cursive (midpoint), mais av= ec juste 2 it=E9rations, tu es s=FBr que =E7a donne un bon r=E9sultat ? putain, j'avais meme pas vu que c'=E9tait un midpoint ;) Bien le resultat est pas vraiment mieux dans mon moteur, donc je peux pas dire. Sanx, -- Laurent MASCHERPA (Sanx / FX Team) President of Epidemic : Epita Demoscene Organization lau...@fx... - http://sanx.fxteam.net |