Bezier : y en fonction de x

Résolu
Utilisateur anonyme - 16 août 2008 à 14:47
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 - 18 août 2008 à 01:37
Salut à tous,

Je me permets de vous exposer un petit problème : J'ai un tableau de 4 points relatifs (A,B,C,D) à une courbe de bezier que j'ai tracé dans un TImage.
La théorie de Bezier induit 2 équations paramétriques :
X=(1-t)^3*Xa+3t*(1-t)^2Xb*+3t^2*(1-t)*Xc+t^3*Xd
Y=(1-t)^3*Ya+3t*(1-t)^2Yb*+3t^2*(1-t)*Yc+t^3*Yd

 t est un réel allant de zéro à 1.

J'ai besoin de relier X à Y : Pour cela j'ai utiliser la fonction suivante :

Function Bezier_Result(X:Integer;BP:Array Of TPoint):Integer;
Var
  T,XVal:Real;
Begin
  //On définit la valeur du résultat par défaut
  Result:=BP[0].X;
  //On définit la valeur de T par défaut
  T:=0;
  //On répète jusqu'à ce que T soit égal à 1
  While T<1 Do
    Begin
      //On défininit XVal comme (1-t)^3*Xa+3t*(1-t)^2Xb*+3t^2*(1-t)*Xc+t^3*Xd
      XVal:=Power(1-T,3)*BP[0].X+3*T*Power(1-T,2)*BP[1].X+3*Power(T,2)*(1-T)*BP[2].X+Power(T,3)*BP[3].X;
      //Si XVal est égalà X à plus ou moins 1 près alors
      If (XVal>X-1) And (XVal<X+1) Then
      //Le résultat est (1-t)^3*Ya+3t*(1-t)^2Yb*+3t^2*(1-t)*Yc+t^3*Yd
      Result:=Round(Power(1-T,3)*BP[0].Y+3*T*Power(1-T,2)*BP[1].Y+3*Power(T,2)*(1-T)*BP[2].Y+Power(T,3)*BP[3].Y);
      //On incrémente T de 10-^4
      T:=T+1 / 10000;
      //On defreeze le système
      Application.ProcessMessages;
    End;
End;

J'ai plusieurs problèmes :
1)Je trouve pas cela terrible
2)Quel pas pour T je dois utiliser ? en effet un pas petit induit beaucoup de calculs mais un grand pas induit un risque de passer à coter de la valeur de X ou une forte imprecision (XVal>X-Truc et XVal<X+Truc).

J'ai cherché des algos mais j'ai rien trouvé

Merci

A++

3 réponses

f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
17 août 2008 à 04:10
function BezierCalcul(const PtStart, PtCtrl1, PtCtrl2, PtEnd: TPoint; const T: single): TPoint;
var
  TPow2,
  TPow3 : single;
begin
  if T = 0 then
  begin
    result := PtStart;
    exit;
  end
  else
  if T = 1 then
  begin
    result := PtEnd;
    exit;
  end;

  TPow2   := T * T;
  TPow3   := T * TPow2;

  result.X := round(
                ((1 - 3*T + 3*TPow2 - TPow3)*PtStart.x) +
                ((3*T - 6*TPow2 + 3*TPow3)*PtCtrl1.x) +
                ((3*TPow2 - 3*TPow3)*PtCtrl2.x) +
                (TPow3*PtEnd.x)
              );
  result.Y := round(
                ((1 - 3*T + 3*TPow2 - TPow3)*PtStart.y) +
                ((3*T - 6*TPow2 + 3*TPow3)*PtCtrl1.y) +
                ((3*TPow2 - 3*TPow3)*PtCtrl2.y) +
                (TPow3*PtEnd.y)
              );
end;








T:=T+1 / 10000;

=

T := T + 1*0.0001;

soit :

for N := 0 to 10000 do
  R := BezierCalcul(A, B, C, D, N*0.0001);

<hr size="2" width="100%" />
3
Utilisateur anonyme
17 août 2008 à 12:17
Merci
0
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
18 août 2008 à 01:37
T:= T+1 / 10000;

=
T :T + 1*0.0001;

T := T + 0.0001; // tout simplement

<hr size ="2" width="100%" />
0
Rejoignez-nous