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

  1. #1
    Membre expert
    Flou circulaire/radial : conversion polaire vers cartésien et inversement
    Bonjour, je suis confronté à un petit problème je n'arrive pas à voir et à saisir ou est mon erreur dans mes fonctions

    Le but est d'appliquer à une image un flou circulaire ou radial

    L'idée est simple pour le flou circulaire on transforme l'image en coordonnée polaire, on applique un flou de mouvement horizontal et on repasse l'image en coordonnée cartésienne
    Pour le flou radial c'est la même chose sauf que l'on effectue un flou de mouvement vertical

    Voila 2 captures d'écran

    Le flou radial, celui-ci me semble correcte



    Le flou circulaire, il y a une cassure au milieu de l'image et cette effet de rotation que je ne veux pas naturellement





    Voici mes fonctions en pascal de transformation polaire<-->cartesien

    Code :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
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    procedure TBZBitmapTransformations.CartesianToPolar;
    var
      x,y,dx,dy : Integer;
      dr, dt, r, theta, dtheta, SinAngle, CosAngle: Single;
      InColor : TBZColor;
      TmpBmp : TBZBitmap;
    begin
      dr := Sqrt(OwnerBitmap.CenterX * OwnerBitmap.CenterX + OwnerBitmap.CenterY * OwnerBitmap.CenterY) / OwnerBitmap.Height;
      dTheta  := 360 / OwnerBitmap.Width;
      dt := DegToRadian(dTheta);
      r := dr;
      TmpBmp := TBZBitmap.Create(OwnerBitmap.Width, OwnerBitmap.Height);
     
     
      InColor := OwnerBitmap.GetPixel(OwnerBitmap.CenterX,OwnerBitmap.CenterY);
      for x := 0 to OwnerBitmap.MaxWidth do TmpBmp.setPixel(x,0, InColor);
     
      for y := 0 to OwnerBitmap.MaxHeight do
      begin
        theta := 0.0;
        for x := 0 to OwnerBitmap.MaxWidth do
        begin
          CosAngle := System.Cos(Theta);
          SinAngle := System.Sin(Theta);
     
          dx := round(OwnerBitmap.CenterX + r * CosAngle);
          dy := round(OwnerBitmap.CenterY + r * SinAngle);
     
          if OwnerBitmap.CheckPixelBound(dx, dy) then
          begin
            InColor := OwnerBitmap.getPixel(dx,dy)
          end
          else InColor := clrTransparent;
     
          TmpBmp.setPixel(x,y,InColor);
     
          Theta := Theta + dt;
        end;
        r := r + dr;
      end;
      OwnerBitmap.FastCopy(TmpBmp);
      FreeAndNil(TmpBmp);
    end;
     
    procedure TBZBitmapTransformations.PolarToCartesian;
    var
      ii,jj,Ind1, Ind2, m,n,x,y,px,py : Integer;
      weight, dr, dt, r, theta, dtheta, SinAngle, CosAngle, dx, dy  : Single;
      AColor: TBZColor;
      xs,ys,ddx,ddy,cx,cy : Integer;
      TmpBmp : TBZBitmap;
    Const
      BiCubicRPrecal: Array[1..16] Of Single = (0.00260416666666667, 0.0208333333333333, 0.0703125, 0.166666666666667,
        0.315104166666667, 0.479166666666667, 0.611979166666667, 0.666666666666667,
        0.611979166666667, 0.479166666666667, 0.315104166666667, 0.166666666666667,
        0.0703125, 0.0208333333333333, 0.00260416666666667, 0.0);
     
    begin
      dr := System.Sqrt(OwnerBitmap.CenterX * OwnerBitmap.CenterX + OwnerBitmap.CenterY * OwnerBitmap.CenterY) / OwnerBitmap.Height;
      dTheta  := 360 / OwnerBitmap.Width;
      dt := DegToRadian(dTheta);
      r := dr;
      TmpBmp := TBZBitmap.Create(OwnerBitmap.Width, OwnerBitmap.Height);
      for y := 0 to OwnerBitmap.MaxHeight do
      begin
        theta := 0.0;
        for x := 0 to OwnerBitmap.MaxWidth do
        begin
     
          CosAngle := System.Cos(Theta);
          SinAngle := System.Sin(Theta);
     
          dx := (OwnerBitmap.CenterX + r * CosAngle);
          dy := (OwnerBitmap.CenterY + r * SinAngle);
          px := Round(dx);
          py := round(dy);
     
          if TmpBmp.CheckPixelBound(px, py) then
          begin
            AColor := OwnerBitmap.getPixel(x, y);
     
            xs := Ceil(dx - dt);
            ys := Ceil(dy - dr);
     
            cx := Floor(dx + dt);
            cy := Floor(dy + dr);
     
            ddx := cx - xs;
            ddy := cy - ys;
     
            For m := -1 To 2 Do
            Begin
              For n := -1 To 2 Do
              Begin
                Ind1 := round(4 * (m - ddx)) + 8; // Indice de correspondance avec la table précalculée
                Ind2 := round(4 * (n - ddy)) + 8; // Idem
                // Evite un bug d'indice hors limites
                Ind1 := Max(Min(Ind1, 16), 1);
                Ind2 := Max(Min(Ind2, 16), 1);
     
                weight := BiCubicRPrecal[ind1]*BiCubicRPrecal[ind2];
     
                ii := Clamp((xs + m), 0, OwnerBitmap.MaxWidth);
                jj := Clamp((ys + n), 0, OwnerBitmap.MaxHeight);
     
                TmpBmp.setPixel(Floor(ii+m*weight),Floor(jj+n*weight),AColor);
              End;
            End;
          end;
     
          Theta := Theta + dt;
        end;
        r := r + dr;
      end;
      OwnerBitmap.FastCopy(TmpBmp);
      FreeAndNil(TmpBmp);
    end;


    et de flou de mouvement :

    Code :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
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    Procedure TBZBitmapBlurFilters.MotionBlur(direction, amount : Integer);
    //Type
    //  TSumRec = packed record
    //    Red,Green, Blue, Alpha : Single;
    //  end;
    Var
      AColor, MColor:   TBZColor;
      Dir:      Single;
      x, y, xa, ya, maxh, maxw, m, s: Integer;
      incr:     Integer;
      SinDir,CosDir,delta, DeltaC:single;
      mustdraw: Boolean;
      SumRec, FColor :   TBZColorVector; //TSumRec;
    Begin
      s := Amount - 1;
      x:=0;
      y:=0;
      AColor := clrTransparent;
      MaxH := OwnerBitmap.MaxHeight + s;
      MaxW := OwnerBitmap.MaxWidth + s;
      Dir := DegToRad(direction);
     
      InitProgress(OwnerBitmap.Width,OwnerBitmap.Height);
      StartProgressSection(0,'');
      StartProgressSection(100,'Flou Motion');
      Delta := 100 / MaxH + s;
     
      SinDir :=System.sin(dir);
      CosDir:=System.cos(dir);
      For Ya := -s To MaxH Do
      Begin
        For Xa := -s To MaxW Do
        Begin
          SumRec.Create(0,0);
          //With SumRec Do
          //Begin
          //  Red := 0;
          //  Green := 0;
          //  Blue := 0;
          //  Alpha := 0;
          //End;
          Incr := 0;
          mustdraw := False;
          For m := 1 To Amount Do
          Begin
            X := Xa + round(CosDir * m);
            Y := Ya + round(SinDir * m);
            If (X >= 0) And (X <= OwnerBitmap.MaxWidth) And (Y >= 0) And (Y <= OwnerBitmap.MaxHeight) Then
            Begin
              if (TBZBitmap(OwnerBitmap).UseMask) and (TBZBitmap(OwnerBitmap).Mask.Apply) then
              begin
                MColor := TBZBitmap(OwnerBitmap).Mask.GetPixel(X,Y);
                if MColor.Red>0 then
                begin
                  FColor := OwnerBitmap.GetPixel(X, Y).AsColorVector;
                  SumRec := SumRec + FColor;
                  //With SumRec Do
                  //Begin
                  //  Red := Red + AColor.Red;
                  //  Green := Green + AColor.Green;
                  //  Blue := Blue + AColor.Blue;
                  //  Alpha := Alpha + AColor.Alpha;
                  //End;
                  Inc(Incr);
                  mustdraw := True;
                End;
              End
              else
              begin
                FColor := OwnerBitmap.GetPixel(X, Y).AsColorVector;
                SumRec := SumRec + FColor;
                //With SumRec  Do
                //Begin
                //  Red := Red + AColor.Red;
                //  Green := Green + AColor.Green;
                //  Blue := Blue + AColor.Blue;
                //  Alpha := Alpha + AColor.Alpha;
                //End;
                Inc(Incr);
                mustdraw := True;
              End;
            End;
          End;
          If mustdraw Then
          Begin
            DeltaC := Incr.Reciprocal;
            SumRec := SumRec * DeltaC;
            //With  AColor Do
            //Begin
            //  Red := ClampByte(Round(SumRec.Red * deltaC));
            //  Green := ClampByte(Round(SumRec.Green * deltaC));
            //  Blue := ClampByte(Round(SumRec.Blue * deltaC));
            //  Alpha := ClampByte(Round(SumRec.Alpha * deltaC)); // /incr
            //End;
            AColor.Create(SumRec);
            OwnerBitmap.SetPixel(x, y, AColor); {%H-}
          End;
        End;
        AdvanceProgress(Delta, 0,1,True);
      End;
      FinishProgressSection(False);
      FinishProgressSection(True);
    End;


    Pourriez vous m'aider à les corriger, pour solutionner le problème du flou circulaire. Il y a forcément quelque chose que je ne fais pas correctement, mais quoi ???
    Merci d'avance

    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é
    salut

    est tu sur des formules de calcul
    r correspondant a l'hypothenus d'un triangle rectangle
    pour retrouver l'angle il suffit de chercher tan-1(r)ce qui en pascal se nome je crois atan2

    une petite page tres instructive ici

    si je comprend bien tu prend le centre de la page comme référence 0,0 et ensuite tu fais un décalage en x et en y



    la formule de calcul est :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Function CartesianToPolar(x,y : Currency ) : TPointReal;
    Var  
      radius,angle : Currency ;
    Begin 
       radius := Sqrt((x*x) + (y*y));
       angle  := Atan2(y, x);
       Result :=  TPointReal(radius, angle);
    end;
    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 expert
    Citation Envoyé par anapurna Voir le message
    salut

    est tu sur des formules de calcul
    r correspondant a l'hypothenus d'un triangle rectangle
    pour retrouver l'angle il suffit de chercher tan-1(r)ce qui en pascal se nome je crois atan2

    une petite page tres instructive ici

    si je comprend bien tu prend le centre de la page comme référence 0,0 et ensuite tu fais un décalage en x et en y



    la formule de calcul est :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Function CartesianToPolar(x,y : Currency ) : TPointReal;
    Var  
      radius,angle : Currency ;
    Begin 
       radius := Sqrt((x*x) + (y*y));
       angle  := Atan2(y, x);
       Result :=  TPointReal(radius, angle);
    end;
    Salut, la fonction CartesianToPolar semble fonctionner correctement (mais j'ai l'impression que quelque chose ne joue pas quand même)



    par contre ma fonction PolarToCartesian est surement fausse (en partie), les coordonnées sont transformées en coordonnées sphérique au lieu de cylindrique



    J'ai lu un truc hier dans ce sens. Je vais voir en utilisant l'hypotenus plutôt que les angles je penses que le problème vient de cette projection

    Merci pour le lien et me mettre sur la bonne voie
    • "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

  4. #4
    Expert confirmé
    salut

    selons le cadran ou tu te trouve il faut ajouter des degrés pour avoir le bonne angle si je me trompe pas
    de plus si tu prend les valeur de x telquel j'ai peur que ton point centrale se retrouve en haut a gauche

    je pense qu'il faut que tu calcul

    Code :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
     
      // Calcul Point origine 
      LC := (o+IWidth) / 2; 
      HC := (o+IHeigth) / 2;
     
      For X:= 0 To IWidth do
        For y := 0 To IHeigth do
        begin    
           // Calcul du point decale de la moitie de l'image
           XT := X - LC ;
           YT := Y - HC ;
           ....
          // SI XT < 0 ET YT >= 0 
          // 4 ieme Quadran 
          // SI XT >= 0 ET YT >=0 
          // 1 ier Quadran 
          // SI XT >= 0 ET YT < 0 
          // 2 ieme Quadran 
          // SI XT < 0 ET YT < 0 
          // 3 ieme Quadran 
     
       end;
    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

  5. #5
    Rédacteur/Modérateur

    J'arrive un peu tard (peu tard du 31 décembre ?), mais j'aimerais que tu expliques cette phrase :
    L'idée est simple pour le flou circulaire on transforme l'image en coordonnée polaire, on applique un flou de mouvement horizontal et on repasse l'image en coordonnée cartésienne
    Pour le flou radial c'est la même chose sauf que l'on effectue un flou de mouvement vertical
    Pourquoi horizontal et vertical, je pense que je vois. En coordonnées polaires tu as (R,T) au lieu de (X,Y) . En jouant sur R, tu te déplaces sur un rayon, et en jouant sur T, tu te déplaces sur un arc de cercle.

    La question est sur 'on applique un flou de mouvement horizontal' par exemple.
    Quelle est la manipulation précise qui est faite dans ce cas.

    Dans le flou 'circulaire', tu as les 2 problèmes que tu signales : problème sur le demi-axe horizontal et sensation que l'image a tourné de quelque degrés.
    Dans le flou radial, tu as en fait aussi le 2ème problème. on a le sentiment que l'image fuit vers l'extérieur (particulièrement visible selon moi sur les lunettes) ; c'est le même bug.
    N'oubliez pas le bouton Résolu si vous avez obtenu une réponse à votre question.

  6. #6
    Membre expert
    Bonjour
    Citation Envoyé par tbc92 Voir le message
    J'arrive un peu tard (peu tard du 31 décembre ?), mais j'aimerais que tu expliques cette phrase :

    L'idée est simple pour le flou circulaire on transforme l'image en coordonnée polaire, on applique un flou de mouvement horizontal et on repasse l'image en coordonnée cartésienne
    Pour le flou radial c'est la même chose sauf que l'on effectue un flou de mouvement vertical
    Bon en fait, a force de lecture sur le web (dont pas mal mélange les notions de conversions polaire<-->cartésien), je me suis mélanger les pinceaux. J'ai donc repris m'a copie depuis l'intervention d'Anapurna qui m'a mis sur la bonne voie.

    Pour ce qui est du flou radial/circulaire il est dit que cet effet peut-être réalisé qu' en effectuant sur l'image source (cartesienne) une transformation des coordonnées Polaire vers Cartesienne (c'est là que je suis planter en premier lieu, car on le voit dans le site cité précédemment on peux lire ce truc erroné : Cartesian-to-polar transform par rapport à l'image du dessous)
    On applique alors un flou de mouvement vertical pour la radial et horizontal pour le circulaire. Puis enfin on retransforme l'image en coordonées Cartésienne vers Polaire

    Bref en reppartant du wiki je me suis aperçu que de un je n'avais pris en compte le Tan-1 et le fait que ArcTan2 donne des résultats compris dans l'intervalle [-pi, pi] et que en plus mes données était en degré au lieu de Radian. Plus qu'il fallait inverser certaines valeurs pour obtenir le bon résultat.

    Alors voila les fonctions corrigées :

    Transformation Cartesienne vers polaire :

    Code :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
    procedure TMainForm.Cart2Polar;
    Var
      sx,sy, Radius, theta, r, Angle, WidthFactor, SqrY : single;
      xx,yy,x,y, nx, ny : Integer;
      inColor : TBZColor;
    begin
      FDisplayBuffer.SetSize(FImageBuffer.Width, FImageBuffer.Height);
      radius := Min(FImageBuffer.Width div 2, FImageBuffer.Height Div 2);
      WidthFactor := (FImageBuffer.Width/360);
      for yy := 0 to FImageBuffer.MaxHeight do
      begin
        y := FImageBuffer.CenterY - yy;
        SqrY := (y*y);
        for xx := 0 to FImageBuffer.MaxWidth do
        begin
          x := FImageBuffer.CenterX - xx;
     
          r := System.sqrt((x*x) + SqrY);
          // 1) Faut inverser l'ordre des paramètres de la fonction ArcTan sinon tourner vers la gauche ou vers la droite si on enlève "- cPI"
          // 2) Avec l'ordre des paramètres changer si "-cPI" est absent l'image est retournée horizontalement
          // 3) Il faut inverser le paramètre "Y" si non retournement vertical
          Theta := Math.arcTan2(x, -y) - cPI;
          // Conversion de l'angle de radian vers degré
          Angle := RadianToDeg(Theta);
          // On ajuste pour que l'angle soit dans l'interval [0,360] et non pas dans l'interval [-180,180]
          if Angle<0 then Angle := Angle + 360;
     
          // Calcul des coordonées polaire
          sx := (Angle * WidthFactor);
          sy := (FImageBuffer.Height * (r /radius));
     
          nx := Clamp(floor(sx),0,FImageBuffer.MaxWidth);
          ny := Clamp(floor(sy),0, FImageBuffer.MaxHeight);
     
          if FImageBuffer.CheckPixelBound(nx,ny) then
          begin
            inColor := FImageBuffer.getPixel(nx,ny);
            FDisplayBuffer.setPixel(xx,yy,inColor);
          end;
     
        end;
      end;
     
      FImageBuffer.Assign(FDisplayBuffer);
    end;


    Resultat :



    Transformation Polaire vers Cartésienne :

    Code :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
    procedure TMainForm.Polar2Cart;
    Var
      sx,sy, Radius, theta, r, AngleRad : single;
      AngleFactor, CosAngle, SinAngle : Single;
      xx,yy,x, nx, ny : Integer;
      inColor : TBZColor;
    begin
      FDisplayBuffer.SetSize(FImageBuffer.Width, FImageBuffer.Height);
      radius := Min(FImageBuffer.Width div 2, FImageBuffer.Height Div 2);
      AngleFactor := (360 / FImageBuffer.Width);
      for yy := 0 to FImageBuffer.MaxHeight do
      begin
        r := Radius * (yy / FImageBuffer.Height);
        for xx := 0 to FImageBuffer.MaxWidth do
        begin
          x := xx - FImageBuffer.CenterX;
     
          Theta := (x * AngleFactor);
          AngleRad := DegToRadian(Theta);
     
          CosAngle := System.Cos(AngleRad);
          SinAngle := System.Sin(AngleRad);
     
          sx := FImageBuffer.CenterX + (-r * SinAngle);
          sy := FImageBuffer.CenterY + (r * CosAngle);
     
          nx := Clamp(floor(sx),0,FImageBuffer.MaxWidth);
          ny := Clamp(floor(sy),0, FImageBuffer.MaxHeight);
     
          if FImageBuffer.CheckPixelBound(nx,ny) then
          begin
            inColor := FImageBuffer.getPixel(nx,ny);
            FDisplayBuffer.setPixel(xx,yy,inColor);
          end;
        end;
      end;
     
      // FDisplayBuffer.BlurFilter.MotionBlur(180,25); --> Flou circulaire
     // FDisplayBuffer.BlurFilter.MotionBlur(90,25); --> Flou radial
      FImageBuffer.Assign(FDisplayBuffer);
     
    end;


    Resutat sur l'image précédente, retour à la normale :



    Maintenant sur l'image source (identique à celle du dessus) application de la transformation Polaire vers Cartesienne



    puis reconversion Cartesienne vers polaire

    note : les coordonnées sont rognées d'ou cet effet d'étirement



    et maintenant le résultat pour le flou radial



    Et enfin le flou circulaire



    Sur ce dernier on vois un cassure au centre, je pense qu'elle peut-être supprimée (ainsi que l'effet d'étirement). La cause les dimensions de l'image transformée reste les même que l'image source alors que par rapport à ce que dit l'auteur de l'article cité précédemment les dimensions devraient être de :

    So the transformed image is a buffer of dimensions ceil(sqrt(W^2+H^2)/2) and 2·(W+H-2).
    Voila me reste plus qu'a rajouté mes fonctions d'interpolation pour améliorer la qualité des résultats obtenus et continuer mes tests sur ce petit filtre circulaire.

    Je considère le sujet comme résolu

    Merci de votre aide

    Bonne années à tous

    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

  7. #7
    Rédacteur/Modérateur

    Sur la dernière image, on a toujours le même bug : la tête penche vers la gauche, et on a toujours une cassure nette sur un demi-axe. Ce n'est plus le demi-axe horizontal mais le demi-axe vertical.
    N'oubliez pas le bouton Résolu si vous avez obtenu une réponse à votre question.

  8. #8
    Membre expert
    Citation Envoyé par tbc92 Voir le message
    Sur la dernière image, on a toujours le même bug : la tête penche vers la gauche, et on a toujours une cassure nette sur un demi-axe. Ce n'est plus le demi-axe horizontal mais le demi-axe vertical.
    Oui la cassure ne se fait plus au même endroit, vu que j'ai rectifié les formules (en tout cas elles sont bonnes, j'ai comparé avec gimp)

    en modifiant un peu le code et en prenant en compte le changement de dimensions, on ne vois plus la cassure. Mais il y a toujours cette rotation vers la gauche (en plus flagrant aussi )



    et je ne vois pas ou se situerai cette erreur. peut-être en augmentant la résolution des calculs en utilisant des double au lieu de single ? je testerai demain si je n'ai pas trop de cheveux qui poussent à l'intérieur de mon cerveau
    • "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
    Rédacteur/Modérateur

    Dans le code de la fonction TBZBitmapBlurFilters.MotionBlur que tu as posté au début, tu avais :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     mustdraw := False;
          For m := 1 To Amount Do
          Begin
            X := Xa + round(CosDir * m);
            Y := Ya + round(SinDir * m);
            If (X >= 0) And (X <= OwnerBitmap.MaxWidth) And (Y >= 0) And (Y <= OwnerBitmap.MaxHeight) The


    Tu prends une direction (CosDir et SinDir) , et tu prends les points qui sont après le point courant quand on suit cette direction.
    Essaie cette variante :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     mustdraw := False;
          For m := 1 To Amount Do
          Begin
            X := Xa - round(CosDir * m);
            Y := Ya - round(SinDir * m);
            If (X >= 0) And (X <= OwnerBitmap.MaxWidth) And (Y >= 0) And (Y <= OwnerBitmap.MaxHeight) The

    Si j'ai bien suivi, tu devrais avoir le bug inverse (tête penchée dans l'autre sens).
    Et avec cette autre variante, ça devrait être bon ?????
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     mustdraw := False;
          For m := Amount/2 To Amount/2 Do
          Begin
            X := Xa - round(CosDir * m);
            Y := Ya - round(SinDir * m);
            If (X >= 0) And (X <= OwnerBitmap.MaxWidth) And (Y >= 0) And (Y <= OwnerBitmap.MaxHeight) The
    N'oubliez pas le bouton Résolu si vous avez obtenu une réponse à votre question.