Courbe de Bézier, accélération, fonction accel(path,real)

Tout ce qui concerne l'utilisation ou l'installation d'Asymptote.

Modérateur: gdm_asy

Règles du forum
Merci d'éviter le style SMS dans vos messages et de penser à utiliser la fonction Recherche avant de poster un message. Pour joindre des fichiers à vos messages, consulter ce sujet.
> Penser à utiliser les balises Code pour poster du code.

Courbe de Bézier, accélération, fonction accel(path,real)

Messagepar GMaths » Vendredi 28 Octobre 2011, 14:49

Une rectification en forme d'explication : dans des exemples récents (que je vais devoir modifier), j'ai utilisé la fonction accel... qui semblait fonctionner pour ce que je proposais mais j'ai réalisé après coup que je tombais dans des cas particuliers où l'accélération tangentielle était nulle.

Pour un path (courbe de Bézier), accel ne donne pas l'accélération normale, comme je l'ai cru, mais il correspond à la somme des accélérations normale et tangentielle.

3fab51a5deb1c1a334e7c051e4a79c85.png

Code: Tout sélectionner
unitsize(1.3cm);
pair z0=(0,0), z1=(7,0),
c0=(1,3), c1=(5,5);

// On déduit du quadruplet de points précédents (z0, c0, c1, z1)
// (par construction de 6 milieux) le point z2 sur la courbe de bézier.
// En procédant de même pour les quadruplets (z0, m0, m3, z2)
// et (z2, m4, m2, z1), on obtiendrait deux nouveaux points de la courbe,
// et c'est en continuant ainsi, par récursivité, que la courbe est construite.

pair m0=(z0+c0)/2,
m1=(c0+c1)/2,
m2=(c1+z1)/2,
m3=(m0+m1)/2,
m4=(m1+m2)/2,
z2=(m3+m4)/2;

// Courbe (spline) de Bézier cubique (définie par 4 points).
path CourbeBezier = z0 .. controls c0 and c1 .. z1;
draw(CourbeBezier,2bp+blue);

// Les traits et points de construction
path lignebrisee = z0 -- c0 -- c1 -- z1;
draw(lignebrisee^^m0--m1--m2^^m3--m4,dashed);
dot(lignebrisee^^m0--m1--m2^^m3--m4^^z2,5bp+red);

// Pour finir, on ajoute le nom des points.
label("$z_0$",z0,S); label("$z_1$",z1,S);
label("$c_0$",c0,N); label("$c_1$",c1,N);
label("$m_0$",m0,NW); label("$m_1$",m1,N);
label("$m_2$",m2,NE); label("$m_3$",m3,N);
label("$m_4$",m4,N); label("$z_2$",z2,N);

draw(Label("\tiny $\vec{m_1m_0}$",LeftSide),z2--z2+(m0-m1),Arrow());
draw("\tiny $\vec{m_1m_2}$",z2+(m0-m1)--z2+(m0-m1)+(m2-m1),Arrow());
draw(Label("$\frac{1}{6}\vec{a}=\vec{m_1m_0}+\vec{m_1m_2}$",LeftSide),z2--(z2+accel(CourbeBezier,dirtime(CourbeBezier,m4-m3))/6),Arrow());
draw("$\frac{1}{3}\vec{v}=\vec{m_3m_4}$",z2--(z2+(m4-m3)),Arrow());

shipout(bbox(3mm,white));

Edition du 31/10/11 : Attention !! il y a une erreur dans le code de cette figure (que je signale dans un message qui suit) mais je la laisse pour la cohérence du sujet.

Comme c'est indiqué sur la figure, accel au point $z_2$ correspond à $6\left(\vec{m_1m_0}+\vec{m_1m_2}\right)$.

Je n'ai pas trouvé de fonction donnant le vecteur vitesse $\vec{v}$, censé être égale à $3\vec{m_3m_4}$. La fonction dir ne donne que le vecteur unitaire qui colinéaire et de même sens que $\vec{v}$.
Dernière édition par GMaths le Lundi 31 Octobre 2011, 16:04, édité 1 fois.
GMaths
Exa-utilisateur
 
Messages: 2031
Inscription: Lundi 01 Octobre 2007, 09:20
Statut actuel: Actif et salarié | Enseignant

Publicité

Re: Courbe de Bézier - Accélération - Fonction accel(path,re

Messagepar GMaths » Vendredi 28 Octobre 2011, 15:14

L'explication sera encore à parfaire car si là, cela fonctionne :

64c8534025d9492b29a8b1f92b89c083.png

Code: Tout sélectionner
unitsize(1cm);

pair z0=(0,0), z1=(7,0),
c0=(5,3), c1=(5,5);

// On déduit du quadruplet de points précédents (z0, c0, c1, z1)
// (par construction de 6 milieux) le point z2 sur la courbe de bézier.
// En procédant de même pour les quadruplets (z0, m0, m3, z2)
// et (z2, m4, m2, z1), on obtiendrait deux nouveaux points de la courbe,
// et c'est en continuant ainsi, par récursivité, que la courbe est construite.

pair m0=(z0+c0)/2,
m1=(c0+c1)/2,
m2=(c1+z1)/2,
m3=(m0+m1)/2,
m4=(m1+m2)/2,
z2=(m3+m4)/2;

// Courbe (spline) de Bézier cubique (définie par 4 points).
path CourbeBezier = z0 .. controls c0 and c1 .. z1;
draw(CourbeBezier,2bp+blue);

// Les traits et points de construction
path lignebrisee = z0 -- c0 -- c1 -- z1;
draw(lignebrisee^^m0--m1--m2^^m3--m4,dashed);
dot(lignebrisee^^m0--m1--m2^^m3--m4^^z2,5bp+red);

// Pour finir, on ajoute le nom des points.
label("$z_0$",z0,S); label("$z_1$",z1,S);
label("$c_0$",c0,N); label("$c_1$",c1,N);
label("$m_0$",m0,NW); label("$m_1$",m1,N);
label("$m_2$",m2,NE); label("$m_3$",m3,N);
label("$m_4$",m4,N); label("$z_2$",z2,N);

draw(Label("\tiny $\vec{m_1m_0}$",LeftSide),z2--z2+(m0-m1),Arrow());
draw("\tiny $\vec{m_1m_2}$",z2+(m0-m1)--z2+(m0-m1)+(m2-m1),Arrow());
draw(Label("$\frac{1}{6}\vec{a}=\vec{m_1m_0}+\vec{m_1m_2}$",LeftSide),z2--(z2+accel(CourbeBezier,dirtime(CourbeBezier,m4-m3))/6),Arrow());
draw("$\frac{1}{3}\vec{v}=\vec{m_3m_4}$",z2--(z2+(m4-m3)),Arrow());

shipout(bbox(3mm,white));


par contre là, cela explose :

a48bd69003611b7baf55615c38b88a1e.png

Code: Tout sélectionner
unitsize(1cm);

pair z0=(0,0), z1=(7,0),
c0=(5,2), c1=(5,5);

// On déduit du quadruplet de points précédents (z0, c0, c1, z1)
// (par construction de 6 milieux) le point z2 sur la courbe de bézier.
// En procédant de même pour les quadruplets (z0, m0, m3, z2)
// et (z2, m4, m2, z1), on obtiendrait deux nouveaux points de la courbe,
// et c'est en continuant ainsi, par récursivité, que la courbe est construite.

pair m0=(z0+c0)/2,
m1=(c0+c1)/2,
m2=(c1+z1)/2,
m3=(m0+m1)/2,
m4=(m1+m2)/2,
z2=(m3+m4)/2;

// Courbe (spline) de Bézier cubique (définie par 4 points).
path CourbeBezier = z0 .. controls c0 and c1 .. z1;
draw(CourbeBezier,2bp+blue);

// Les traits et points de construction
path lignebrisee = z0 -- c0 -- c1 -- z1;
draw(lignebrisee^^m0--m1--m2^^m3--m4,dashed);
dot(lignebrisee^^m0--m1--m2^^m3--m4^^z2,5bp+red);

// Pour finir, on ajoute le nom des points.
label("$z_0$",z0,S); label("$z_1$",z1,S);
label("$c_0$",c0,N); label("$c_1$",c1,N);
label("$m_0$",m0,NW); label("$m_1$",m1,N);
label("$m_2$",m2,NE); label("$m_3$",m3,N);
label("$m_4$",m4,N); label("$z_2$",z2,N);

draw(Label("\tiny $\vec{m_1m_0}$",LeftSide),z2--z2+(m0-m1),Arrow());
draw("\tiny $\vec{m_1m_2}$",z2+(m0-m1)--z2+(m0-m1)+(m2-m1),Arrow());
draw(Label("$\frac{1}{6}\vec{a}=\vec{m_1m_0}+\vec{m_1m_2}$",LeftSide),z2--(z2+accel(CourbeBezier,dirtime(CourbeBezier,m4-m3))/6),Arrow());
draw("$\frac{1}{3}\vec{v}=\vec{m_3m_4}$",z2--(z2+(m4-m3)),Arrow());

shipout(bbox(3mm,white));


Je reverrai cela plus tard.

De la lecture sur le sujet qu'il faudra que je lise... pour comprendre pourquoi cela ne fonctionne pas dans certains cas.
GMaths
Exa-utilisateur
 
Messages: 2031
Inscription: Lundi 01 Octobre 2007, 09:20
Statut actuel: Actif et salarié | Enseignant

Re: Courbe de Bézier - Accélération - Fonction accel(path,re

Messagepar GMaths » Lundi 31 Octobre 2011, 15:40

J'ai refait les calculs :
courbe_bezier.pdf
(46.69 Kio) Téléchargé 98 fois


J'ai refait un cas moins particulier : on peut choisir t.

38ac8c572494b0a5e6fe4ef37f58afb3.png

Code: Tout sélectionner
unitsize(1cm); pair z0=(0,0), z1=(9,0), c0=(1,5), c1=(5,5); real t=.45; pair m0=(1-t)*z0+t*c0, m1=(1-t)*c0+t*c1, m2=(1-t)*c1+t*z1, m3=(1-t)*m0+t*m1, m4=(1-t)*m1+t*m2, z2=(1-t)*m3+t*m4; path CourbeBezier = z0 .. controls c0 and c1 .. z1; draw(CourbeBezier,2bp+blue); path lignebrisee = z0 -- c0 -- c1 -- z1; draw(lignebrisee^^m0--m1--m2^^m3--m4,dashed); dot(lignebrisee^^m0--m1--m2^^m3--m4^^z2,5bp+red); label("$M_0$",z0,S); label("$M_1$",z1,S); label("$C_0$",c0,N); label("$C_1$",c1,N); label("$Q_0(m_0)$",m0,NW); label("$Q_1(m_1)$",m1,N); label("$Q_2(m_2)$",m2,NE); label("$Q_3(m_3)$",m3,N); label("$Q_4(m_4)$",m4,N); label("$P(z_2)$",z2,N); draw(Label("$\vec{Q_1Q_0}$",LeftSide),z2--z2+(m0-m1),Arrow()); draw("$\vec{Q_1Q_2}$",z2+(m0-m1)--z2+(m0-m1)+(m2-m1),Arrow()); draw(Label("$\tiny\frac{1}{6}\vec{a}=\vec{Q_1Q_0}+\vec{Q_1Q_2}$",LeftSide), z2--(z2+accel(CourbeBezier,t)/6),Arrow()); draw("$\tiny\frac{1}{3}\vec{v}=\vec{Q_3Q_4}$",z2--(z2+(m4-m3)),Arrow());


Attention, j'ai trouvé l'erreur signalée précédemment : l'emploi de dirtime ne fonctionnait pas dans des cas particuliers où il y a des tangentes qui sont parallèles. Le "time" renvoyé n'était pas celui du point étudié.
En plus, la solution était tout simplement de remplacer :
Code: Tout sélectionner
z2--(z2+accel(CourbeBezier,dirtime(CourbeBezier,m4-m3))/6)

par
Code: Tout sélectionner
z2--(z2+accel(CourbeBezier,t)/6)

(avec t=1/2 dans mon premier exemple (moins général que le second) ; je ne sais plus pourquoi j'avais eu l'impression que le "time" du point n'était pas simplement 1/2 dans mon premier cas... ce qui m'avait amené à ce délire avec "dirtime". Passons.).
GMaths
Exa-utilisateur
 
Messages: 2031
Inscription: Lundi 01 Octobre 2007, 09:20
Statut actuel: Actif et salarié | Enseignant

Re: Courbe de Bézier - Accélération - Fonction accel(path,re

Messagepar GMaths » Jeudi 03 Novembre 2011, 18:52

Pour être complet sur le sujet de la fonction accel, un exemple du champ de vecteurs "accélération" pour un path donné (courbe de Bézier par morceaux)
avec les constructions de ces vecteurs en trois points particuliers (conformément à l'égalité vectorielle donnée sur la figure précédente).

Image

Code: Tout sélectionner
import geometry;
size(15cm,0);
path p=(-5,0)..(20,0)..(20,10)..(0,20)..(-15,10)..(-5,15)..cycle;
draw("p",p); dot(p,2bp+black);
pair po, pa;
for(real k=0; k<length(p); k+=.01)
{
  po=point(p,k);
  pa = po+(accel(p,k))/6;
  draw(po--pa,red);
}
void acceleration(path p, int k, real t){
     pair z0=point(p,k),
          c0=postcontrol(p,k),
          z1=point(p,k+1),
          c1=precontrol(p,k+1),
          m0=(1-t)*z0+t*c0,
          m1=(1-t)*c0+t*c1,
          m2=(1-t)*c1+t*z1,
          m3=(1-t)*m0+t*m1,
          m4=(1-t)*m1+t*m2,
          z2=(1-t)*m3+t*m4;
     path CourbeBezier = z0 .. controls c0 and c1 .. z1;
     draw(CourbeBezier,1bp+blue);
     path lignebrisee = z0 -- c0 -- c1 -- z1;
     draw(lignebrisee^^m0--m1--m2^^m3--m4,linetype("4 4"));
     dot(z0^^z1^^z2,blue); dot(c0^^c1,gray);
     dot(m0--m1--m2^^m3--m4,green);
     draw(z2--(z2+accel(CourbeBezier,t)/6),.8bp+.5green,Arrow());
}
acceleration(p,1,.75);
acceleration(p,3,.75);
acceleration(p,5,.75);
addMargins(2mm,2mm);
GMaths
Exa-utilisateur
 
Messages: 2031
Inscription: Lundi 01 Octobre 2007, 09:20
Statut actuel: Actif et salarié | Enseignant


Retourner vers Asymptote

 


  • Articles en relation
    Réponses
    Vus
    Dernier message

Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 19 invités