IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Traitement d'images Discussion :

Courbe de Bézier continue


Sujet :

Traitement d'images

  1. #1
    Expert confirmé
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut Courbe de Bézier continue
    Bonjour à tous

    Je voudrais savoir comment calculer extraire les points de contrôles d'une courbe de bezier quadractique (et cubique serait un plus) à partir d'un tableau de N points pour dessiner une courbe de bezier continue. comme ci-dessous

    Nom : 2020-07-31_115633.jpg
Affichages : 917
Taille : 22,6 Ko

    Le but final de cette courbe est de me permettre de modifier les composantes RVB d'une image comme dans Gimp par exemple

    J'ai chercher ici et sur le web, mais je n'ai pas trouvé de réponses compréhensible pour mon petit cerveau.

    A l'heure actuelle (en pascal) voila ce que je sais faire avec un courbe de bezier quadratique (idem pour les cubique):
    • Calculer la dérivée à un instant T :
      Code Pascal : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      function TBZ2DQuadraticBezierCurve.GetDerivativeAt(t : Single) : TBZFloatPoint;
      var
        f, tm, tm2 : Single;
        {$CODEALIGN VARMIN=16}
        t1,t2,t3 : TBZFloatPoint;
        {$CODEALIGN VARMIN=4}
      begin
       
        //dt(t) /t := P1 * (2t-2) + (2*P3-4*P2) * t + 2 * P2
       
        tm := 1.0 - t;
        t1 := (FControlPoint - FStartPoint);
        t1 := (t1 + t1) * tm;
        t2 := (FEndPoint - FControlPoint);
        t2 := (t2 + t2) * t;
        Result := t1 + t2;
      end;
    • Calculer la normale à un instant T (et donc aussi extraire la tangente) :
      Code Pascal : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      function TBZ2DQuadraticBezierCurve.GetNormalAt(t : Single) : TBZFloatPoint;
      Var
      {$CODEALIGN VARMIN=16}
         dr : TBZFloatPoint;
      {$CODEALIGN VARMIN=4}
      begin
        dr := Self.getDerivativeAt(t);
        Dr := dr.Normalize;
        Result.X := -dr.Y;
        Result.Y := dr.X;
      end;
    • Calculer les coordonnées d'un point de la courbe à un instant T :
      Code Pascal : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      function TBZ2DQuadraticBezierCurve.ComputePointAt(t : single) : TBZFloatPoint;
      var
        t1,coef1,coef2,t2: single;
      begin
        t1:=  1-t;
        coef1 := t1 * t1;
        coef2 := t1 * (t + t);
        t2 := t*t;
        Result := (FStartPoint * Coef1) + (FControlPoint * Coef2) + (FEndPoint * t2);
      end;
    • Calculer les coordonnées des lignes constituant la courbe de bezier :
      Code Pascal : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      function TBZ2DQuadraticBezierCurve.ComputePolyLinePoints(Const nbStep : Integer) : TBZArrayOfFloatPoints;
      var
        nbSteps,i : Integer;
        Delta : Single;
        aTime : Single;
        {$CODEALIGN VARMIN=16}
        APoint : TBZFloatPoint;
        {$CODEALIGN VARMIN=4}
        Points : TBZArrayOfFloatPoints;
      begin
        if nbStep <= 0 then nbSteps := ComputeSteps(FTolerance)
        else nbSteps := nbStep;
       
        if nbSteps > 1 then
        begin
          Points := TBZArrayOfFloatPoints.Create(nbSteps+1);
       
          Delta := 1 / nbSteps;
          aTime := 0;
          For i := 0 to nbSteps-1 do
          begin
            APoint := ComputePointAt(aTime);
            Points.Add(APoint);
            aTime := aTime + Delta;
          end;
          Points.Add(FEndPoint);
        end
        else
        begin
          Points := TBZArrayOfFloatPoints.Create(1);
          Points.Add(FStartPoint);
        end;
        Result := Points;
      end;


    Donc il faudrait que je puisse extraire les points de contrôles pour chaque courbe de bezier
    Cela ne me semble pas compliqué (virtuellement) sachant que je doit en fait ajuster et décaler 2 points a chaque fois, mais il me manque quelque chose pour obtenir quelque chose de correcte.
    J'ai tenté ceci :

    ou :
    - FControlPoints sont les points de contrôle de la courbe que je souhaite dessiner (de 2 à 32 points)
    - FBezierControlPoints les points de contrôles intermédiaires calculés des courbes de bezier quadratique

    Code Pascal : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    procedure TBZCustomCurveEditor.UpdateBezierControlPoints;
    Var
      i, j : Integer;
      p1,p2, NewPt, delta1, Delta2 : TBZFloatPoint;
    begin
      j := 0;
      // Courbe ouverte
      for i := 0 to (FNbPoints[FSelectedChannel] - 2) do
      begin
        p1 := FControlPoints[FSelectedChannel, i].AsVector2f; 
        p2 := FControlPoints[FSelectedChannel, i + 1].AsVector2f;
        Delta1 := p2 - p1;
        Delta2 := (Delta1 * 2) / 3;
        Delta1 := Delta1 / 3;
        NewPt := p1 + Delta1;
        FBezierControlPoints[FSelectedChannel, j] := NewPt;
        NewPt := p1 + Delta2;
        FBezierControlPoints[FSelectedChannel, j + 1] := NewPt;
        j := j + 2;
      end; 
    end;

    - FBezierAnchorPoints : ce sont les points d'ancrages (de fin) calculés d'une courbe de bezier quadratique
    Code Pascal : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    procedure TBZCustomCurveEditor.UpdateBezierAnchorPoints;
    var
     i, j : Integer;
     p1, p2, NewPt : TBZFloatPoint;
    begin
       FBezierAnchorPoints[FSelectedChannel,0] := FControlPoints[FSelectedChannel, 0].AsVector2f;
       FBezierAnchorPoints[FSelectedChannel,(FNbPoints[FSelectedChannel] - 1)] := FControlPoints[FSelectedChannel, (FNbPoints[FSelectedChannel] - 1)].AsVector2f;
       j := 1;
       for i := 1 to (FNbPoints[FSelectedChannel] - 2) do
       begin
          p1 := FControlPoints[FSelectedChannel, j].AsVector2f;
          p2 := FControlPoints[FSelectedChannel, j + 1].AsVector2f;
          NewPt := (p1 + p2) * 0.5;
          FBezierAnchorPoints[FSelectedChannel, i] := NewPt;
          j := j + 2;
       end;
    end;

    et la méthode d'affichage :
    Code Pascal : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    procedure TBZCustomCurveEditor.DrawBezierCurve;
    Var
      i, j, k, l : Integer;
      BezierCurveTool : TBZ2DQuadraticBezierCurve;
      PolyLinePoints : TBZArrayOfFloatPoints;
      ptFrom, ptTo : TBZFloatPoint;
    begin
      j := 0;
      With FDisplayBuffer.Canvas do
      begin
        Antialias := True;
        Brush.Style := bsClear;
        Pen.Style := ssSolid;
        Pen.Color := clrRed;
        Pen.Width := 1;
        MoveTo(7,263);
        LineTo(263,7);
      end;
     
      for i := 0 to (FNbPoints[FSelectedChannel] - 1) do
      begin
         // /!\ NOTE : pour la 1ere courbe le premier point devrait-être FBezierAnchorPoints[FSelectedChannel, 0]
     
         BezierCurveTool :=  CreateQuadraticBezierCurve(FBezierControlPoints[FSelectedChannel, j],
                                                        FBezierControlPoints[FSelectedChannel, j + 1],
                                                        FBezierAnchorPoints[FSelectedChannel, i]);
         PolyLinePoints := BezierCurveTool.ComputePolyLinePoints(256);
     
         For l := 0 To 255 Do
         Begin
     
           PolyLinePoints.items[l] := PolyLinePoints.items[l].Clamp(0,255);
         end;
         FDisplayBuffer.Canvas.Pen.Color := clrRed;
         For l := 0 To 255 Do
         Begin
           k := (i + 1) Mod 256;
           if k=0 then Continue;
     
           FLUT[FSelectedChannel, l] := Round(PolyLinePoints.items[l].Y);
     
           ptFrom := PolyLinePoints.items[l];
           ptTo := PolyLinePoints.items[k];
           ptFrom.X := 7 + ptFrom.X;
           ptTo.X   := 7 + ptTo.X;
           ptFrom.Y := 255 - ptFrom.Y + 7;
           ptTo.Y   := 255 - ptTo.Y + 7;
           FDisplayBuffer.Canvas.Line(ptFrom, ptTo);
     
         end;
     
         FreeAndNil(PolyLinePoints);
         FreeAndNil(BezierCurveTool);
     
     
        j := j + 2;
      end;
     
      FDisplayBuffer.Canvas.Antialias := False;
    end;

    Mais je me retrouve avec un affichage chaotique. Il y a quelque chose que j'ai raté.

    Nom : 2020-07-31_121121.jpg
Affichages : 746
Taille : 9,9 Ko

    Merci d'avance pour votre aide

    Bonne journée

    Jérôme
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  2. #2
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 418
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 418
    Points : 5 816
    Points
    5 816
    Par défaut
    salut

    je suppose que tu as lu cela avant
    ainsi que ceci

    un autre site intéressant ici
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  3. #3
    Membre émérite

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    Décembre 2010
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 77
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 333
    Points : 2 570
    Points
    2 570
    Billets dans le blog
    9
    Par défaut Courbe de Bézier continue
    Bonjour,

    Citation Envoyé par BeanzMaster Voir le message
    ... Je voudrais savoir comment calculer extraire les points de contrôles d'une courbe de bezier quadractique (et cubique serait un plus) à partir d'un tableau de N points pour dessiner une courbe de bezier continue ...
    Le but final de cette courbe est de me permettre de modifier les composantes RVB d'une image comme dans Gimp par exemple ...
    Est-il vraiment indispensable de recourir aux courbes de Bézier pour obtenir des distorsions de teinte, telles qu'elles sont présentées dans le document en lien ? J'ai l'impression que tu t'exposes à des difficultés inutiles, alors qu'un expression polynomiale appropriée conviendrait pleinement.

    Nom : 2 graphes.png
Affichages : 211
Taille : 50,4 Ko

    En notant (x) l'indice de couleur et (m) sa valeur maximale, égale à 255, on peut envisager des expressions de complexité croissante:

    1°) Un ré-haussement de la luminosité de l'image est obtenu par la fonction parabolique:
    F(x) = x + Ax(m - x) ;
    représentée par le premier graphe, et dont on vérifie immédiatement l'adéquation aux valeurs extrêmes:
    F(0) = 0 ; F(m) = m ;
    le paramètre (A) dépend alors des coordonnées du point médian (a = m/2ou 128 , b>a), par la relation:
    b - a = Aa(m - a) .
    La dérivée de la fonction F'(x) = 1 + A(m - 2x) ne peut être négative, de sorte que (A) est limité supérieurement; il vient au point le plus élevé (x = m): 1 - Am>= 0 , ce qui entraîne: A <= 1/m .

    2°) L'accentuation du contraste de clarté est obtenu par la fonction de degré trois:
    G(x) = x + Ax(m - x)(2x - m) ;
    on retrouve comme auparavant:
    G(0) = 0 ; G(m) = m ,
    relations auxquelles s'ajoute le centre de symétrie du graphe: G(m/2) = m/2 .
    Le paramètre (A) est déterminé dès l'introduction d'un point supplémentaire (a, b):
    b - a = Aa(m - a)(2a - m) .
    Il intervient comme auparavant une fonction monotone croissante, dont la dérivée ne peut être négative:
    G'(x) = 1 + A[(m - x)(2x - m) - x(2x - m) + 2x(m - x)] = 1 + A[6mx - m2 - 6x2) ,
    ce qui donne aux points extrêmes (x = 0 ou m): G'(x) = 1 - Am2 ;
    la condition G'(x) >= 0 conduit alors à A <= 1/m2 .

    3°)) Dans le cas d'un graphe dissymétrique du troisième degré interviennent deux paramètres (A, B) que l'on peut déterminer à partir de deux points donnés
    (a1, b1) , (a2, b2)
    en partant de l'équation:
    G(x) = x + (A + Bx)x(m - x) .
    Les calculs ne sont pas difficiles; la seule chose à vérifier est que la valeur renvoyée par l'expression obtenue ne sorte pas de l'intervalle [0 ; m] - cela peut se produire avec les expressions polynomiales.


    Le français, notre affaire à tous
    Grand Dictionnaire Terminologique

  4. #4
    Expert confirmé
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    Bonjour

    Citation Envoyé par wiwaxia Voir le message
    Bonjour,

    Est-il vraiment indispensable de recourir aux courbes de Bézier pour obtenir des distorsions de teinte, telles qu'elles sont présentées dans le document en lien ? J'ai l'impression que tu t'exposes à des difficultés inutiles, alors qu'un expression polynomiale appropriée conviendrait pleinement.
    Citation Envoyé par anapurna Voir le message
    salut

    je suppose que tu as lu cela avant
    ainsi que ceci

    un autre site intéressant ici
    Merci pour les liens, le premier pourrait m'être utiles

    @wiwaxia tu as raison. Je me complique la vie pour cet effet. Faudrait que j'ouvre une nouvelle discussion par rapport à la réduction de degrés des courbes de Bezier (j'ai trouvé un PDF sur le sujet mais je suis largué. Et un lien en relation avec ce que je souhaite faire, mais ce n'est pas tout à fait le résultat que je souhaite obtenir)

    En fait, à la base, ce que je souhaitait faire c'était découper une liste de points de contrôle en plusieurs courbes de bezier quadratique et/ou cubique. (par forcément lissées) car les points de contrôles peuvent ne pas être colinéaires et à distance égale du point d’ancrage ; vue que ce sont des points rentrés par l'utilisateur.
    Une fois les points de contrôles de chaque courbe trouvés, appliquer un lissage ne devrait pas être compliqué, mais ce n'était pas mon but.

    Je vais creuser la suggestion de wiwaxia

    Merci

    Bonne journée

    Jérôme
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  5. #5
    Membre émérite

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    Décembre 2010
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 77
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 333
    Points : 2 570
    Points
    2 570
    Billets dans le blog
    9
    Par défaut Courbe de Bézier continue
    Encore une fois, je n'ai rien contre les courbes de Bézier, mais je ne vois vraiment pas la raison de leur intervention dans la modification des couleurs ... à moins que quelque chose ne m'échappe dans ton projet.

    Citation Envoyé par BeanzMaster Voir le message
    ... Le but final de cette courbe est de me permettre de modifier les composantes RVB d'une image comme dans Gimp par exemple ...
    On dispose, avec les polynômes, d'un très large éventail de fonctions dont un bref aperçu a été donné auparavant.

    D'autres options sont possibles: le recours aux fonctions homographiques, par exemple, permet de couvrir tout le domaine [0..255]×[0..255]; il suffit d'envisager la fonction:
    H(x) = (bm + 1)x/(bx + 1) ,
    en convenant de prendre m = 255, et b = 2h/(m/2 - h)2 avec -m < h < m .
    Nom : 5 courbes homographiques.png
Affichages : 736
Taille : 91,7 Ko
    J'ai pris ici h = 0 , ± 75 , ± 150 (présentation bordélique, faute de temps)


    Le français, notre affaire à tous
    Grand Dictionnaire Terminologique

  6. #6
    Membre émérite

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    Décembre 2010
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 77
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 333
    Points : 2 570
    Points
    2 570
    Billets dans le blog
    9
    Par défaut Courbe de Bézier continue
    Il est possible d'obtenir des graphes de forme appropriée, semblables à ceux décrits sur le site que tu as mentionné et passant par cinq points imposés, à condition d'envisager des polynômes du quatrième degré.
    Nom : Calcul_1.png
Affichages : 680
Taille : 131,9 Ko
    Nom : 4 Déterminants.png
Affichages : 677
Taille : 51,1 Ko
    On obtient alors: I = Di/Dijk ; J = Dj/Dijk ; K = Dk/Dijk .

    Les solutions numériques ont été vérifiées sur calculatrice, ainsi que la forme des graphes correspondants.

    Afin que ces derniers ne présentent pas de boucles trop amples, il faut que les écarts (yM - xM) ne soient pas trop importants, et que les abscisses choisies soient aussi proches que possible des valeurs suivantes:
    xA = m/4 ~ 64 ; xB = m/2 ~ 128 ; xA = 3m/4 ~ 191 ;
    c'est l'inconvénient classique des expressions polynomiales, qui peuvent conduire à des écarts énormes entre les points imposés lorsqu'elles sont utilisées sans prudence.

    On peut imposer une condition d'écrêtage pour prévenir toute sortie de l'intervalle [0..m], du type:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    IF (y<0) THEN y:= 0;
    IF (y>m) THEN y:= m;


    Le français, notre affaire à tous
    Grand Dictionnaire Terminologique

  7. #7
    Membre émérite

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    Décembre 2010
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 77
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 333
    Points : 2 570
    Points
    2 570
    Billets dans le blog
    9
    Par défaut Courbe de Bézier continue
    La programmation est relativement lourde, mais moins cependant qu'il ne semblait au premier abord si l'on prend soin de regrouper certaines expressions.

    Voici ce que donne la modification d'une seule composante - ici le vert - dans son domaine de plus faible luminance; on a pris successivement pour les trois points (A, B, C) les coordonnées:
    a) (63, 103) , (127, 127) , (191, 191) ;
    b) (63, 23) , (127, 127) , (191, 191) ;
    La correction de teinte a été résolument appuyée; il a fallu, dans le second cas, annuler les résultats négatifs obtenus au voisinage de zéro.

    Au départ, une vue de Rimini:

    Nom : Rimini_00.png
Affichages : 654
Taille : 494,2 Ko

    Image (a), obtenue par exaltation du vert:

    Nom : Rimini_VertAp40.png
Affichages : 692
Taille : 483,3 Ko

    Image (b), résultant de l'atténuation de la même composante:

    Nom : Rimini_VertAm40.png
Affichages : 684
Taille : 502,7 Ko


    Le français, notre affaire à tous
    Grand Dictionnaire Terminologique

  8. #8
    Expert confirmé
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    Bonjour

    Citation Envoyé par wiwaxia Voir le message
    Encore une fois, je n'ai rien contre les courbes de Bézier, mais je ne vois vraiment pas la raison de leur intervention dans la modification des couleurs ... à moins que quelque chose ne m'échappe dans ton projet.
    Ma question, est trompeuse, je me suis mal exprimé.
    Pour la modification des couleurs, photoshop / Gimp utilisent des courbes cubique naturelle. (Natural BSpline).
    Dans l'absolue comme tu le disais on peut utiliser des fonctions de type y = f(x).

    Comme je le disais j'ai déjà implémenté les courbes de Bezier quadratique et cubique et c'est pour cela que je voulais utiliser celles-ci (c'est du 2 en 1 en gros)

    A l'heure actuelle, ma courbe peut avoir entre 2 et 64 points de contrôles. Il faut donc que je découpe ces points en groupe de 3 ou 4 points de contrôles pour dessiner ma courbe.

    voici une représentation approximative d'un cas possible :

    Nom : path839b.png
Affichages : 674
Taille : 12,2 Ko

    Pour simplifier le problème de mes courbes de bezier, deux autres solutions s'offre à moi pour obtenir un point sur la courbe à un instant T avec T dans l'intervalle [0,1] :
    1) Utiliser l'algorithme de De Casteljau
    2) Calculer le polynôme de Berstein indépendamment du degré de la courbe

    Une troisième solution serai également possible. Si les points de contrôles sont sur la courbe. En prenant les points 2 par 2 (point de début et de fin de segment) Il faudrait que je calcul les "points de contrôles" intermédiaires (en vert)

    Nom : path839a.png
Affichages : 676
Taille : 14,8 Ko

    Pour pouvoir ensuite découper cette courbe en courbe quadratique ou cubique.
    C'est possible dans ce cas de trouver les points de contrôle, d'après ce que j'ai lu en passant par le calcul de la 1ere dérivée.


    Si non, j'ai commencé à regarder du coté des BSpline, mais là, les points de contrôle sont des points de la courbe.
    J'ouvrirai une autre discussion sur ces BSpline un peu plus tard sur ce sujet. Le temps que j'analyse les documents, articles que j'ai trouvé.
    Je me suis encore lancé dans un truc pas mal compliqué mathématiquement parlant. Car il existe pas mal d'algorithmes et de type de courbes différents (Courbes BSpline basique, cubique (Lagrange, Hermite, monotone, naturelle, Catmull-Rom), uniforme, non-uniforme, etc ...). Algortihme tridagonal, Cox-DeBoor, Band-Matrix.... Bref encore un vaste sujet mais ça cela sera pour une prochaine fois.

    Faut déjà que j'arrive à solutionner mon "problème" avec ces courbes de bezier

    Merci

    A+

    Bonne journée
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  9. #9
    Membre émérite

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    Décembre 2010
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 77
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 333
    Points : 2 570
    Points
    2 570
    Billets dans le blog
    9
    Par défaut Courbe de Bézier continue
    Citation Envoyé par BeanzMaster Voir le message
    ... Pour simplifier le problème de mes courbes de bezier, deux autres solutions s'offre à moi pour obtenir un point sur la courbe à un instant T avec T dans l'intervalle [0,1] :
    ... / ...
    2) Calculer le polynôme de Berstein indépendamment du degré de la courbe ...
    La fonction proposée
    y = F(x) = x + x(m – x)[I.(m – x)2 + J.x(m – x) + K.x2]
    utilise sans les nommer une combinaison linéaire de 3 polynômes de Bernstein d'ordre 4, construite sur 5 points fixes:
    F(x) - x = I.x(m – x)3 + J.x2(m - x)2 + K.x3(m - x) ,
    soit en posant t = x/m:
    F(x) - x = Im4.t(1-t)3 + Jm4.t2(1 - t)2 + Km4.t3(1 - t)
    = (Im4/4).B14(t) + (Jm4/6).B24(t) + (Km4/4).B34(t) .
    Les variantes envisageables sont bien sûr en nombre illimité; je m'en suis tenu à la solution la plus simple conforme à ce qui était présenté dans le document de Gimp. Le procédé employé, quel qu'il soit, conduit le plus souvent à des combinaisons de termes de la forme k.xp(m - x)q
    Des améliorations sont possibles - et même souhaitables en ce qui concerne les pentes aux extrémités; les courbes de Bézier, qui préviennent toute sortie du domaine [0 ; m], apparaissent sous ce rapport plus satisfaisantes.


    Le français, notre affaire à tous
    Grand Dictionnaire Terminologique

  10. #10
    Membre émérite

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    Décembre 2010
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 77
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 333
    Points : 2 570
    Points
    2 570
    Billets dans le blog
    9
    Par défaut Courbe de Bézier continue
    Citation Envoyé par BeanzMaster Voir le message
    ... Comme je le disais j'ai déjà implémenté les courbes de Bezier quadratique et cubique et c'est pour cela que je voulais utiliser celles-ci (c'est du 2 en 1 en gros)

    A l'heure actuelle, ma courbe peut avoir entre 2 et 64 points de contrôles. Il faut donc que je découpe ces points en groupe de 3 ou 4 points de contrôles pour dessiner ma courbe.
    ... / ...
    Faut déjà que j'arrive à solutionner mon "problème" avec ces courbes de Bézier ...
    Afin d'assurer la continuité de la pente de l'ensemble au point de raccordement (P4), arrange-toi pour réaliser l'alignement des points (P3, P4) et (P5).
    Nom : Bézier_6 points.png
Affichages : 710
Taille : 51,8 Ko
    Et comme cette condition n'est probablement pas réalisée, détermine deux nouveaux points (P'3, P'5) tels que les segments (P'3P4, P4P'5) présentent des pentes égales, ce qui va se traduire par la relation:
    (Y4 - Y3')/(X4 - X3) = (Y5' - Y4)/(X5 - X4) = p .
    La valeur commune (p) correspond à la valeur moyenne des pentes des segments initiaux:
    p = 0.5((Y4- Y3)/(X4 - X3) + (Y5 - Y4)/(X5 - X4)) .
    On peut aussi retenir pour pente moyenne:
    p' = (Y5 - Y3)/(X5 - X3) .

    Si la modification de (P3) présente des difficultés, garde tout simplement ce point (P3' = P3); l'ordonnée de l'autre est alors toute trouvée:
    (Y4 - Y3)/(X4 - X3) = (Y5' - Y4)/(X5 - X4) .

    Les impossibilités géométriques ne sont pas exclues.


    Le français, notre affaire à tous
    Grand Dictionnaire Terminologique

  11. #11
    Expert confirmé
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    Bonjour j'ai trouvé ce site FreeCodeCamp dans lequel la formule mathématique de la courbe de bezier est très bien expliquée

    J'ai codé la version pascal qui fonctionne pas trop mal

    Code Pascal : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    function TBZ2DBezierSplineCurve.ComputeOptimalSteps(Const aTolerance: Single): Integer;
    Var
      {$CODEALIGN VARMIN=16}
      P1, P2 : TBZFloatPoint;
      {$CODEALIGN VARMIN=4}
      i : Integer;
      d : Single;
    begin
      d := 0;
      For i := 0 to (Self.PointsList.Count - 2) do
      begin
        P1 := Self.Points[i];
        P2 := Self.Points[i+1];
        d := Max(d, P1.DistanceSquare(P2));
      end;
      d := System.Sqrt(System.Sqrt(d) / aTolerance) * 2;
      if (d < cEpsilon) then d := 1.0;
      Result := Round(d);
    end;
     
    function TBZ2DBezierSplineCurve.ComputeCoef(n, k: Integer): Double;
    Var
      Coef : Single;
      i, j : integer;
    begin
      Coef := 1;
      j := n - k + 1;
      for i := j to n do
      begin
        Coef := Coef * i;
      end;
      for i := 1 to k do
      begin
        Coef := Coef / i;
      end;
      Result := Coef;
    end;
     
    function TBZ2DBezierSplineCurve.ComputePointAt(t: Single): TBZFloatPoint;
    Var
      i, n : integer;
      b, nt : Double;
    begin
      n := Self.PointsList.Count - 1;
      Result.Create(0,0);
      nt := 1 - t;
      for i := 0 to n do
      begin
        b := ComputeCoef(n, i) * BZMath.Pow(nt, (n-i)) * BZMath.Pow(t, i);
        Result := Result + (Self.Points[i]	* b);
      end;
    end;
     
    function TBZ2DBezierSplineCurve.ComputePolyLinePoints(Const nbStep: Integer): TBZArrayOfFloatPoints;
    var
      nbSteps, j : Integer;
      Delta, aTime : Single;
      pt : TBZFloatPoint;
    begin
      Result := nil;
      if nbStep <= 0 then nbSteps := ComputeOptimalSteps(FTolerance)
      else nbSteps := nbStep;
     
      Result := TBZArrayOfFloatPoints.Create(nbSteps + 1);
      if nbSteps > 1 then
      begin
        aTime := 0;
        Delta := 1.0 / nbSteps;
        for j := 0 to (nbSteps - 1) do
        begin
          pt :=ComputePointAt(aTime);
          Result.Add(pt);
          aTime := aTime + Delta;
        end;
      end
      else
      begin
        Result.Add(Self.Points[0]);
        Result.Add(Self.Points[(Self.PointsList.Count - 1)]);
      end;
    end;

    Nom : 2020-08-08_124502.jpg
Affichages : 715
Taille : 211,5 Ko

    Le seul hic au delà de 35 points de contrôle ma courbe ne s'affiche pas. J'ai l'impression que je doit dépasser les limites des virgules flottantes ou c'est la fonction Math.power / BZMath.pow qui atteigne leurs limites. Ou bien autre chose, je vais approfondir.

    A partir de là, comment calculer la dérivée de cette courbe à un instant T ? voila comment je fais pour des bezier quadratique et cubique

    Code Pascal : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    function TBZ2DQuadraticBezierCurve.GetDerivativeAt(t : Single) : TBZFloatPoint;
    var
      f, tm, tm2 : Single;
      {$CODEALIGN VARMIN=16}
      t1,t2,t3 : TBZFloatPoint;
      {$CODEALIGN VARMIN=4}
    begin
     
      //dt(t) /t := P1 * (2t-2) + (2*P3-4*P2) * t + 2 * P2
     
      tm := 1.0 - t;
      t1 := (FControlPoint - FStartPoint);
      t1 := (t1 + t1) * tm;
      t2 := (FEndPoint - FControlPoint);
      t2 := (t2 + t2) * t;
      Result := t1 + t2;
    end; 
     
    function TBZ2DCubicBezierCurve.GetDerivativeAt(t : Single) : TBZFloatPoint;
    var
      f, tm, tm2 : Single;
      {$CODEALIGN VARMIN=16}
      t1,t2,t3 : TBZFloatPoint;
      {$CODEALIGN VARMIN=4}
    begin
     
      // cubic derivative = dP(t) / dt =  -3(1-t)^2 * P0 +  3(1-t)^2 * P1
      //                                   - 6t(1-t) * P1 - 3t^2 * P2 + 6t(1-t) * P2
      //                                  + 3t^2 * P3
     
     
      tm := 1.0 - t;
      f := 3.0 * tm * tm;
      t1 := (FControlPoints[1] - FControlPoints[0]) * f;
      f := 6.0 * t * tm;
      t2 := (FControlPoints[2] - FControlPoints[1]) * f;
      f := 3.0 * t * t;
      t3 := (FControlPoints[3] - FControlPoints[2]) * f;
     
      Result := t1 + t2 +t3;
    end;

    Sinon je me tournerai vers Casteljau.

    Merci
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  12. #12
    Expert confirmé
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    J'ai réussi à diviser ma courbe en plusieurs courbes cubique et quadratique (le problème était en fait simple)

    Code Pascal : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    function TBZ2DCurve.ComputeContiniousBezierCurve : TBZArrayOfFloatPoints;
    Var
      RenderingPoints : TBZArrayOfFloatPoints;
      QuadraticCurve : TBZ2DQuadraticBezierCurve;
      CubicCurve : TBZ2DCubicBezierCurve;
      {$CODEALIGN VARMIN=16}
      p0, p1, p2, p3 : TBZFloatPoint;
      {$CODEALIGN VARMIN=4}
      i, j : Integer;
    begin
      QuadraticCurve := TBZ2DQuadraticBezierCurve.Create;
      CubicCurve := TBZ2DCubicBezierCurve.Create;
      Self.PointsList.Add(Self.Points[(Self.PointsList.Count - 1)]);
      i := 0;
      RenderingPoints := TBZArrayOfFloatPoints.Create(32);
      Result := TBZArrayOfFloatPoints.Create(32);
      While (i < (Self.PointsList.Count - 2)) do
      begin
        p0 := Self.Points[i];
        p1 := Self.Points[i + 1];
        p2 := Self.Points[i + 2];
     		if ( (i + 3) > (Self.PointsList.Count - 1) ) then
        begin
          QuadraticCurve.StartPoint := p0;
          QuadraticCurve.ControlPoint := p1;
          QuadraticCurve.EndPoint := p2;
          RenderingPoints := QuadraticCurve.ComputePolyLinePoints();
          for j := 0 to RenderingPoints.Count - 1 do
          begin
            Result.Add(RenderingPoints.Items[j]);
          end;
          inc(i, 2);
        end
        else
        begin
          p3 := Self.Points[i + 3];
          CubicCurve.StartPoint := p0;
          CubicCurve.ControlPointA := p1;
          CubicCurve.ControlPointB := p2;
          CubicCurve.EndPoint := p3;
          RenderingPoints := CubicCurve.ComputePolyLinePoints();
          for j := 0 to RenderingPoints.Count - 1 do
          begin
            Result.Add(RenderingPoints.Items[j]);
          end;
          inc(i, 3);
        end;
     
      end;
      FreeAndNil(CubicCurve);
      FreeAndNil(QuadraticCurve);
    end;

    La courbe en blanc est issue de mon précédent message et en violet la courbe "découpée". Les résultats sont très différents

    Nom : 2020-08-08_132432.jpg
Affichages : 700
Taille : 210,5 Ko

    Je vais maintenant essayer de trouver le moyen de calculer ma courbe de bezier, mais passant par les points de contrôle. (donc en trouvant les points de contrôle intermédiaires) J'ai lu une discussion sur un forum parlant de l'algorithme de "Thomas" (faut que je fasse des recherches là dessus)

    A+
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  13. #13
    Membre émérite

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    Décembre 2010
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 77
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 333
    Points : 2 570
    Points
    2 570
    Billets dans le blog
    9
    Par défaut
    Comment fais-tu pour construire la courbe de Bézier sur 16 points en te limitant aux polynômes de degré 2 ou 3, qui n'utilisent que 3 ou 4 points, et sans qu'il y ait de discontinuité de raccordement ?

    Là de trouve le noeud du problème.

    PS: L'un les liens précédemment donné (#4) paraît très intéressant. Le temps me manque , malheureusement, pour entrer dans les détails.


    Le français, notre affaire à tous
    Grand Dictionnaire Terminologique

  14. #14
    Expert confirmé
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par wiwaxia Voir le message
    Comment fais-tu pour construire la courbe de Bézier sur 16 points en te limitant aux polynômes de degré 2 ou 3, qui n'utilisent que 3 ou 4 points, et sans qu'il y ait de discontinuité de raccordement ?
    C'est juste comment j'ai placé mes points

    Nom : 2020-08-08_133917.jpg
Affichages : 682
Taille : 192,5 Ko

    Tous les codes que j'utilise, sont dans les messages précédents

    A+
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  15. #15
    Membre émérite

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    Décembre 2010
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 77
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 333
    Points : 2 570
    Points
    2 570
    Billets dans le blog
    9
    Par défaut Courbe de Bézier continue
    Je crois avoir compris: il y a des points (quasiment) alignés qui ont été intercalés dans une séquence initiale.
    D'où la courbe tracée en violet, assemblage de courbes de Bézier cubiques se raccordant tangentiellement en leurs extrémités..

    Nom : Courbe 16 points_700x386.png
Affichages : 1190
Taille : 174,1 Ko

    Comment procèdes-tu ensuite pour obtenir la seconde ?


    Le français, notre affaire à tous
    Grand Dictionnaire Terminologique

  16. #16
    Membre émérite

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    Décembre 2010
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 77
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 333
    Points : 2 570
    Points
    2 570
    Billets dans le blog
    9
    Par défaut Courbe de Bézier continue
    Pour l'image donnée en #14, les points communs ne sont plus alignés avec leurs voisins, et il n'y a plus de continuité au niveau des tangentes.


    Le français, notre affaire à tous
    Grand Dictionnaire Terminologique

  17. #17
    Expert confirmé
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    Et voila ce que ça donne avec la solution du lien en #4

    Ce n'est pas le top de mon point de vue.
    Le premier point est supprimé et il faut un nombre impair de point pour que le dernier point soit pris en compte. De plus la continuité n'est pas forcément présente

    Code Pascal : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    function TBZ2DCurve.ComputeContiniousBezierCurve : TBZArrayOfFloatPoints;
    Var
      OutControlPoints, RenderingPoints : TBZArrayOfFloatPoints;
      QuadraticCurve : TBZ2DQuadraticBezierCurve;
     
      CubicCurve : TBZ2DCubicBezierCurve;
      {$CODEALIGN VARMIN=16}
      p0, p1, p2, p3 : TBZFloatPoint;
      {$CODEALIGN VARMIN=4}
      i, j : Integer;
    begin
      QuadraticCurve := TBZ2DQuadraticBezierCurve.Create;
      CubicCurve := TBZ2DCubicBezierCurve.Create;
      //Self.PointsList.Add(Self.Points[(Self.PointsList.Count - 1)]);
     
      RenderingPoints := TBZArrayOfFloatPoints.Create(32);
      OutControlPoints := TBZArrayOfFloatPoints.Create(32);
      Result := TBZArrayOfFloatPoints.Create(32);
     
      //OutControlPoints.Add(Self.Points[0]);
      i := 1;
    	While (i <= (Self.PointsList.Count - 1)) do
      begin
        OutControlPoints.Add(Self.Points[i - 1].Center(Self.Points[i]));
        OutControlPoints.Add(Self.Points[i]);
        OutControlPoints.Add(Self.Points[i + 1]);
     
    		if ( (i + 2) < (Self.PointsList.Count - 1) ) then
        begin
          OutControlPoints.Add(Self.Points[i + 1].Center(Self.Points[i + 2]));
        end;
     
        inc(i, 2);
      end;
     
      i := 0;
      While (i < (OutControlPoints.Count - 2)) do
        begin
          p0 := OutControlPoints.Items[i];
          p1 := OutControlPoints.Items[i + 1];
          p2 := OutControlPoints.Items[i + 2];
       		if ( (i + 3) > (Self.PointsList.Count - 1) ) then
          begin
            QuadraticCurve.StartPoint := p0;
            QuadraticCurve.ControlPoint := p1;
            QuadraticCurve.EndPoint := p2;
            RenderingPoints := QuadraticCurve.ComputePolyLinePoints();
            for j := 0 to RenderingPoints.Count - 1 do
            begin
              Result.Add(RenderingPoints.Items[j]);
            end;
            //inc(i, 2);
          end
          else
          begin
            p3 := OutControlPoints.Items[i + 3];
            CubicCurve.StartPoint := p0;
            CubicCurve.ControlPointA := p1;
            CubicCurve.ControlPointB := p2;
            CubicCurve.EndPoint := p3;
            RenderingPoints := CubicCurve.ComputePolyLinePoints();
            for j := 0 to RenderingPoints.Count - 1 do
            begin
              Result.Add(RenderingPoints.Items[j]);
            end;
            //inc(i, 3);
          end;
          inc(i, 4);
        end;
     
      FreeAndNil(OutControlPoints);
      FreeAndNil(CubicCurve);
      FreeAndNil(QuadraticCurve);
    end;

    Nom : 2020-08-08_141940.jpg
Affichages : 671
Taille : 131,0 Ko

    Nom : 2020-08-08_142501.jpg
Affichages : 668
Taille : 148,3 Ko

    Citation Envoyé par wiwaxia Voir le message
    Je crois avoir compris: il y a des points (quasiment) alignés qui ont été intercalés dans une séquence initiale.
    D'où la courbe tracée en violet, assemblage de courbes de Bézier cubiques se raccordant tangentiellement en leurs extrémités..

    Nom : Courbe 16 points_700x386.png
Affichages : 1190
Taille : 174,1 Ko

    Comment procèdes-tu ensuite pour obtenir la seconde ?
    Que veux tu dire par "obtenir la seconde" ?
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  18. #18
    Membre émérite

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    Décembre 2010
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 77
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 333
    Points : 2 570
    Points
    2 570
    Billets dans le blog
    9
    Par défaut Courbe de Bézier continue
    La seconde courbe, tracée en blanc, et dont les boucles sont nettement plus réduites.
    Mais la réponse se trouve peut-être dans la référence donnée (#4), cependant je n'ai vraiment pas le temps d'approfondir.

    J'ai l'impression que le découpage de la séquence de points est défectueuse, sur la fin:

    Nom : Courbe_13 Points_700x431.png
Affichages : 681
Taille : 255,0 Ko

    Il manque apparemment deux points de tangence (Td, Te) , qui feront probablement disparaître les deux points anguleux. La séquence devrait sans doute se terminer par une courbe d'ordre 2.


    Le français, notre affaire à tous
    Grand Dictionnaire Terminologique

  19. #19
    Expert confirmé
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    Bonjour
    Citation Envoyé par wiwaxia Voir le message
    La seconde courbe, tracée en blanc, et dont les boucles sont nettement plus réduites.
    Mais la réponse se trouve peut-être dans la référence donnée (#4), cependant je n'ai vraiment pas le temps d'approfondir.
    La courbe en blanc, avec le code est donnée en #11


    Citation Envoyé par wiwaxia Voir le message
    J'ai l'impression que le découpage de la séquence de points est défectueuse, sur la fin:

    Il manque apparemment deux points de tangence (Td, Te) , qui feront probablement disparaître les deux points anguleux. La séquence devrait sans doute se terminer par une courbe d'ordre 2.
    Oui et le 1er point n'est pas pris en compte. C'est la 1ere boucle qui foire.
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  20. #20
    Expert confirmé
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    Bon, en cherchant un peu sur le web je suis tombé sur une solution qui génère une courbe de bezier en préservant la continuité

    En blanc la courbe calculée avec Bernstein cf #11
    En Violet la courbe ne préservant pas la continuité
    En Bleu la courbe avec la préservation de la continuité

    Nom : 2020-08-09_101146.jpg
Affichages : 647
Taille : 150,8 Ko
    Nom : 2020-08-09_101229.jpg
Affichages : 638
Taille : 129,1 Ko


    Fait intéressant, jusqu'à une courbe de degré 3 (cubique) la courbe en blanc et celle en violet sont quasi identiques. Au delà elle deviennent différentes.

    Nom : 2020-08-09_101846.jpg
Affichages : 650
Taille : 67,3 Ko
    Nom : 2020-08-09_102403.jpg
Affichages : 637
Taille : 116,2 Ko

    Voici le code pour la courbe en violet

    Code pascal : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
     
    function TBZ2DCurve.ComputeBezierCurve : TBZArrayOfFloatPoints;
    Var
      OutControlPoints, RenderingPoints : TBZArrayOfFloatPoints;
      QuadraticCurve : TBZ2DQuadraticBezierCurve;
     
      CubicCurve : TBZ2DCubicBezierCurve;
      {$CODEALIGN VARMIN=16}
      p0, p1, p2, p3 : TBZFloatPoint;
      {$CODEALIGN VARMIN=4}
      i, j : Integer;
    begin
      QuadraticCurve := TBZ2DQuadraticBezierCurve.Create;
      CubicCurve := TBZ2DCubicBezierCurve.Create;
      if (odd(Self.PointsList.Count)) then Self.PointsList.Add(Self.Points[(Self.PointsList.Count - 1)]);
     
      RenderingPoints := TBZArrayOfFloatPoints.Create(32);
      OutControlPoints := TBZArrayOfFloatPoints.Create(32);
      Result := TBZArrayOfFloatPoints.Create(32);
     
      i := 0;
      While (i < (Self.PointsList.Count - 2)) do
      begin
        p0 := Self.Points[i];
        p1 := Self.Points[i + 1];
        p2 := Self.Points[i + 2];
     		if ( (i + 3) > (Self.PointsList.Count - 1) ) then
        begin
          QuadraticCurve.StartPoint := p0;
          QuadraticCurve.ControlPoint := p1;
          QuadraticCurve.EndPoint := p2;
          RenderingPoints := QuadraticCurve.ComputePolyLinePoints();
          for j := 0 to RenderingPoints.Count - 1 do
          begin
            Result.Add(RenderingPoints.Items[j]);
          end;
          inc(i, 2);
        end
        else
        begin
          p3 := Self.Points[i + 3];
          CubicCurve.StartPoint := p0;
          CubicCurve.ControlPointA := p1;
          CubicCurve.ControlPointB := p2;
          CubicCurve.EndPoint := p3;
          RenderingPoints := CubicCurve.ComputePolyLinePoints();
          for j := 0 to RenderingPoints.Count - 1 do
          begin
            Result.Add(RenderingPoints.Items[j]);
          end;
          inc(i, 3);
        end;
      end;
     
      FreeAndNil(RenderingPoints);
      FreeAndNil(OutControlPoints);
      FreeAndNil(CubicCurve);
      FreeAndNil(QuadraticCurve);
    end;

    Et celui de la courbe en bleu
    Code pascal : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
     
    function TBZ2DCurve.ComputeSmoothBezierCurve : TBZArrayOfFloatPoints;
    Var
      i,j, k  : Integer;
      OutControlPoints, OutAnchorPoints, RenderingPoints : TBZArrayOfFloatPoints;
      CubicCurve : TBZ2DCubicBezierCurve;
      {$CODEALIGN VARMIN=16}
      p0, p1, p2, p3, p4, tn : TBZFloatPoint;
      {$CODEALIGN VARMIN=4}
    begin
     
      if (PointsList.Count < 2) then exit;
     
      CubicCurve := TBZ2DCubicBezierCurve.Create;
      RenderingPoints := TBZArrayOfFloatPoints.Create(32);
      OutControlPoints := TBZArrayOfFloatPoints.Create(32);
      OutAnchorPoints := TBZArrayOfFloatPoints.Create(32);
      Result := TBZArrayOfFloatPoints.Create(32);
     
      // Controls points
      for i := 0 to (Self.PointsList.Count - 2) do
      begin
        p0 := Self.Points[i];
        p1 := Self.Points[i + 1];
        tn := p1 - p0;
        p1 := tn / 3.0;
        p2 := (tn + tn) / 3.0;
        p3 := p0 + p1;
        p4 := p0 + p2;
        OutControlPoints.Add(p3);
        OutControlPoints.Add(p4);
      end;
      // if FClosed then
      //begin
      //end;
     
      // Anchor Points
      //if FClosed then
      //begin
        //p0 := OutControlPoints.Items[0];
      //end;
      //else
      OutAnchorPoints.Add(Self.Points[0]);
      j := 1;
      for i := 0 to  (Self.PointsList.Count - 3) do
      begin
        p1 := OutControlPoints.Items[j];
        p2 := OutControlPoints.Items[j + 1];
        p3 := (p1 + p2) * 0.5;
        OutAnchorPoints.Add(p3);
        inc(j, 2);
      end;
      // if FClosed then OutControlPoints.Add(Self.Points[0])
      //else
      OutAnchorPoints.Add(Self.Points[(Self.PointsList.Count - 1)]);
     
      // Update curve control points
      j := 0;
      for i := 0 to  (OutAnchorPoints.Count - 2) do
      begin
        //Result.Add(OutAnchorPoints.Items[i]);
        //Result.Add(OutControlPoints.Items[j]);
        //Result.Add(OutControlPoints.Items[j + 1]);
        //Result.Add(OutAnchorPoints.Items[i + 1]);
        RenderingPoints.Clear;
        CubicCurve.StartPoint := OutAnchorPoints.Items[i];
        CubicCurve.ControlPointA := OutControlPoints.Items[j];
        CubicCurve.ControlPointB := OutControlPoints.Items[j + 1];
        CubicCurve.EndPoint := OutAnchorPoints.Items[i + 1];
        RenderingPoints := CubicCurve.ComputePolyLinePoints();
        for k := 0 to RenderingPoints.Count - 1 do
        begin
          Result.Add(RenderingPoints.Items[k]);
        end;
        inc(j, 2);
      end;
     
      FreeAndNil(RenderingPoints);
      FreeAndNil(OutAnchorPoints);
      FreeAndNil(OutControlPoints);
      FreeAndNil(CubicCurve);
    end;

    prochaine étape faire en sorte que la courbe passe par les points de contrôle.
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

Discussions similaires

  1. Courbe de Bézier
    Par acacia dans le forum Mathématiques
    Réponses: 11
    Dernier message: 31/03/2010, 17h59
  2. Courbes de bézier sous CSS 2?
    Par sirbaldur dans le forum Mise en page CSS
    Réponses: 1
    Dernier message: 18/09/2007, 15h27
  3. Position sur une Courbe de Bézier
    Par Kurisu dans le forum Mathématiques
    Réponses: 2
    Dernier message: 29/06/2007, 07h49
  4. recherche doc sur les courbe de bézier
    Par amaury pouly dans le forum OpenGL
    Réponses: 4
    Dernier message: 29/04/2003, 22h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo