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

Langage Delphi Discussion :

Graphisme : problème de mode de combinaisons de couleurs


Sujet :

Langage Delphi

  1. #1
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut Graphisme : problème de mode de combinaisons de couleurs
    Bonjour,

    Lorsque j'utilise le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    procedure TForm1.SpeedButton3Click(Sender: TObject);
    begin     
              with image1.canvas do begin
                   pen.mode:=pmNotXor; pen.color:=clLime; pen.width:=18;
                   moveTo(20,50);  lineTo(200,200);
                   moveTo(20,200); lineTo(200,50);
              end;
    end;
    ... lors du premier click cela me trace sur un arrière-plan blanc une croix mais avec un losange blanc au croisement des deux droites et qui me gêne
    ... et bien entendu lors du 2ième click cela m'efface la croix et le canvas est de nouveau tout blanc.

    Or je souhaiterais remplacer les moveTo ... lineTo par un code utilisant scanline où je détecterais le moment où la deuxième droite croise la première de sorte que la croix soit, lors du 1er click, entièrement de la même couleur y compris dans la zone de leur croisement et qu'elle disparaisse entièrement lors du 2ième click.
    Ceci suppose que lors du 1er click et du tracé de la 2ième droite j'affecte à la zone du croisement une combinaison de la couleur du crayon et de la couleur de l'arrière-plan autre que du NotXor puis une autre combinaison qui entre en jeu lors du 2ième click afin de faire disparaître entièrement le tracé.
    La détection de la zone du croisement n'est pas un problème puisque il suffit de détecter le moment où l'on rencontre des pixels d'arrière-plan de même couleur que celle du crayon.
    Par contre je galère pour trouver quelles combinaisons de couleurs je dois utiliser dans la zone du croisement pour obtenir les résultats visés lors du tracé et lors de l'effacement ???.
    Quelqu'un aurait-il-elle une idée ???

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  2. #2
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 745
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 745
    Points : 13 306
    Points
    13 306
    Par défaut
    Perso, je ferais différemment

    Je dessinerais une fois pour toute une croix dans un bitmap à fond noir et ferais la copie par BitBlt(..., SRCINVERT).

  3. #3
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Bonjour,

    AndNotOr :
    Je dessinerais une fois pour toute une croix dans un bitmap à fond noir et ferais la copie par BitBlt(..., SRCINVERT).
    ... Pour simplifier mon message d'introduction j'avais pris l'exemple d'une croix, mais en réalité il s'agit d'une série de dessins déplaçables tracés en mode vectoriel sur un BitMap unique, donc ta solution m'obligerait à multiplier les manipulations de BitMap's ce que je crains car cela risque d'alourdir et de ralentir mon usine à gaz.

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  4. #4
    Membre confirmé
    Homme Profil pro
    Santé
    Inscrit en
    Septembre 2010
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Santé
    Secteur : Santé

    Informations forums :
    Inscription : Septembre 2010
    Messages : 290
    Points : 534
    Points
    534
    Par défaut
    Salut,

    Et pourquoi pas, tout simplement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    procedure TForm1.SpeedButton1Click(Sender: TObject);
    begin
      with image1.canvas do begin
        if pen.color=clLime then pen.color:=image1.canvas.Brush.Color 
                            else pen.color:=clLime;
        pen.width:=18;
        moveTo(20,50);  lineTo(200,200);
        moveTo(20,200); lineTo(200,50);
      end;
    end;

  5. #5
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 745
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 745
    Points : 13 306
    Points
    13 306
    Par défaut
    Citation Envoyé par Gilbert Geyer Voir le message
    ... Pour simplifier mon message d'introduction j'avais pris l'exemple d'une croix, mais en réalité il s'agit d'une série de dessins déplaçables tracés en mode vectoriel sur un BitMap unique, donc ta solution m'obligerait à multiplier les manipulations de BitMap's ce que je crains car cela risque d'alourdir et de ralentir mon usine à gaz.
    Si tu veux un rendu correct, tu devras passer par plusieurs bitmaps qui constitueront les layers de ton image finale

    Et pas certain que dessiner une fois "offline" un bitmap suivi d'un appel simple à une API (BitBlt) soit plus lent ou plus compliqué à coder que la calculation de vecteurs suivi de boucles sur des Scanline (A l'ajout et surtout à la suppression ).

  6. #6
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Bonjour,

    A Caribensila : Merci pour ta suggestion. Je viens de la tester mais j'ai toujours le losange blanc à la coisée des deux droites.

    A Andnotor :
    Si tu veux un rendu correct, tu devras passer par plusieurs bitmaps qui constitueront les layers de ton image finale
    ... c'est déjà ce que je fais pour le cas particulier de l'affichage d'un bout de texte formant titre avec des caractères texturés et ombrés collés sur une courbe de Bezier mais cela ralentit pas mal le déplacement du texte et je ne voudrais pas généraliser ce ralentissement sans oublier que pour réduire ce ralentissement chaque bitMap n'a que la taille du rectangle circonscrit à un seul caractère plus ou moins incliné alors que la taille des autres dessins dépend de l'utilisateur. Donc j'essaye de trouver une solution plus simple avant de me lancer sur la multiplication des BitMap's.

    J'ai la conviction que c'est faisable en jouant sur les combinaisons de couleur crayon/arrière-plan pour la raison suivante. Si j'utilise le code suivant sous le mode pmNotXor :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Canvas.Polygon([Point(282, 372), Point(234, 518), Point(359, 427), Point(207, 430), Point(328, 514)]);
    ... cela m'affiche au 1er click une étoile à cinq branches qui se croisent et se re-croisent et dont la couleur est constante y compris dans les zones de croisement, et tout s'efface correctement au 2ième click.

    Mais manque de chance je n'ai pas accès au code-source de la méthode Polygon pour voir comment ses concepteurs se sont débrouillés pour régler le problème du NotXor dans les zones de croisement.
    Donc si quelqu'un pouvait y avoir accès cela pourrait me simplifier le smilblick.

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  7. #7
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 448
    Points
    28 448
    Par défaut
    Canvas.Polygon fait appel à la fonction de l'API Windows du même nom, c'est tout

    comme tu lances plusieurs ordres graphiques (deux lignes) le second XOR annule le premier, c'est bien le principe d'ailleurs.

    il faudrait essaye ceci

    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
     
      Canvas.Polygon([
        Point(20, 50),
        Point(200, 200),
        Point(110, 125),
        Point(20, 200),
        Point(200,50),
        Point(110, 125),
        Point(20, 50)
      ]);
     
    // ou
     
      Canvas.Polyline([
        Point(20, 50),
        Point(200, 200),
        Point(110, 125),
        Point(20, 200),
        Point(200,50)
      ]);
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  8. #8
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Bonjour,

    Merci Paul THOT. J'ai testé Canvas.Polyline sous pmNotXor lors du tracé puis du déplacement d'un trèfle à quatre feuilles (équation polaire) formé par des tronçons de droite tous les 5 degrés (dont les extrémités se recouvrent donc) et ca marche avec un rendu impeccable.

    comme tu lances plusieurs ordres graphiques (deux lignes) le second XOR annule le premier, c'est bien le principe d'ailleurs
    ... absolument d'accord. Par contre j'aurais bien aimé comprendre comment Polyline se débrouille dans la zone des recouvrements ou des croisements pour éviter que le second Xor n'annule pas le premier (cela calmerait mes neurones) car cela fait plusieurs jours que je tourne en rond en essayant toutes sorte de combinaisons couleur crayon/arrière-plan et certaines n'ont marché que dans des cas particulier mais lorsque des dessins différents se croisent au même endroit l'effacement était incomplet ... et j'aime bien comprendre.

    En tous cas merci déjà pour Polyline.

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  9. #9
    Membre confirmé
    Homme Profil pro
    Santé
    Inscrit en
    Septembre 2010
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Santé
    Secteur : Santé

    Informations forums :
    Inscription : Septembre 2010
    Messages : 290
    Points : 534
    Points
    534
    Par défaut
    @Gilbert Geyer

    - Si tu as toujours le losange blanc en appliquant ma méthode, c'est que tu es resté en mode pmNotXor. Il faut que tu te mettes en pmCopy et ça fonctionne parfaitement.

    - Pour le problème de ralentissement lors de l'animation de ton texte, il est possible que cela soit dû au fait que tes petits Bitmap's soient transparents (c'est très gourmand). Si c'est le cas, il faudrait que tu supprimes la transparence et que tu leur appliques un fond blanc. Bien sûr, dans ce cas, il faudra faire défiler ton texte sur un fond blanc uni.

    - Il est sans doute possible de travailler avec Scanline comme tu le suggérais. Ce serait la méthode la plus rapide (plusieurs centaines de fois plus rapide !), mais tu te priverais alors de tous les outils de TCanvas (comme LineTo, etc...), et il faudrait tout réinventer.

    - Pour les différents modes, je crois que Delphi n'en utilise que quelques uns parmis les plus courants des 255 possibles. Il faudrait peut-être travailler avec les Api's pour avoir accès à tous les modes possibles (et je ne pense pas qu'ils soient documentés). Mais ce sera un sacré boulot, surtout qu'il faudrait aussi tester le changement de mode entre chaque ordre graphique...

  10. #10
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Re-bonjour,

    A Caribensila :
    - Si tu as toujours le losange blanc en appliquant ma méthode, c'est que tu es resté en mode pmNotXor. Il faut que tu te mettes en pmCopy et ça fonctionne parfaitement.
    ... je vien de tester : le losage blanc disparait effectivement mais au 2ième click l'effacement efface le tout y compris l'arrière-plan. Mais la solution de Paul THOT fonctionne.

    - Pour le problème de ralentissement lors de l'animation de ton texte, il est possible que cela soit dû au fait que tes petits Bitmap's soient transparents (c'est très gourmand). Si c'est le cas, il faudrait que tu supprimes la transparence et que tu leur appliques un fond blanc. Bien sûr, dans ce cas, il faudra faire défiler ton texte sur un fond blanc uni.
    ... Ok, merci je vais neutraliser la transparence.

    - Il est sans doute possible de travailler avec Scanline comme tu le suggérais. Ce serait la méthode la plus rapide (plusieurs centaines de fois plus rapide !), mais tu te priverais alors de tous les outils de TCanvas (comme LineTo, etc...), et il faudrait tout réinventer.
    ... j'avais créé une procedure qui trace une droite avec extrémités arrondies avec Scanline et en mode pmNotXor (couleur NotXor = Not (CouleurCrayon Xor CouleurArrière-plan) mais je galère pour éviter le pb du losange blanc aux croisements. Par contre quand tu dis "plusieurs centaines de fois plus rapide" il faudrait préciser que tu as écrit ceci sur Codes-sources dans le cadre de tes comparaisons avec Pixels[]. Mais je ne suis pas certain qu'avec Scanline on puisse dépasser la vitesse de Polyline.

    - Pour les différents modes, je crois que Delphi n'en utilise que quelques uns parmis les plus courants des 255 possibles. Il faudrait peut-être travailler avec les Api's pour avoir accès à tous les modes possibles (et je ne pense pas qu'ils soient documentés). Mais ce sera un sacré boulot, surtout qu'il faudrait aussi tester le changement de mode entre chaque ordre graphique...
    ... si seulement j'avais accès au code de la méthode Polyline ou de Polygon pour voir comment il y est géré les changement de mode dans les zones de croisement ça m'éclairerait la lanterne ... le sacré boulot je m'en ferais volontiers mon affaire.

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  11. #11
    Membre confirmé
    Homme Profil pro
    Santé
    Inscrit en
    Septembre 2010
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Santé
    Secteur : Santé

    Informations forums :
    Inscription : Septembre 2010
    Messages : 290
    Points : 534
    Points
    534
    Par défaut
    si seulement j'avais accès au code de la méthode Polyline ou de Polygon pour voir comment il y est géré les changement de mode dans les zones de croisement ça m'éclairerait la lanterne
    J'imagine qu'il utilise un algo qui ressemble à celui de tracé de segment de Bresenham et quelques opérations logiques de base.
    Mais, effectivement, il serait interressant d'en connaître les détails, et je n'ai encore rien trouvé pour le moment...

  12. #12
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Bonjour,

    J'imagine qu'il utilise un algo qui ressemble à celui de tracé de segment de Bresenham et quelques opérations logiques de base.
    Mais, effectivement, il serait interressant d'en connaître les détails, et je n'ai encore rien trouvé pour le moment...
    ... Je n'avais pas utilisé l'algo de Bresenheim pour le tracé je me suis débrouillé avec le tracé de y = ax + b si la droite est peu inclinée sur l'horizontale et x:= (y - b)/a dans le cas inverse et quand aux opérations de logique voici le code avec lequel j'ai obtenu à ce jour les résultats les meilleurs pour ce qui est des combinaisons de couleurs pour Afficher/Effacer en mode NotXor avec le code suivant qui marche avec Scanline ... mais qui n'est pas encore parfait : il marche sur des zones où peu de droites se croisent au même endroit mais dans des zones où plusieurs droites consécutives se croisent il reste des petites traces lors de l'effacement.

    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
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    type tTraceMode = (tmAffiche,tmEfface,tmCopy);
     
    procedure TracerDroite( BMP : TBitMap; xo,yo,xe,ye, epTrait : integer;
                                  CoulPen : TColor; TraceMode : tTraceMode);
    //        Tracer/Effacer une droite en mode NotXor lorsque TraceMode = tmAffiche/tmEfface
    var       Theta,miEp,si,co,mis,mic,sinco,cosco,
              ep,x,y,xo1,yo1,xe1,ye1,xo2,yo2,xe2,ye2,dx,dy,a,b,xorMin,xerMax,yorMin,yerMax,rr,d,u,dt : Extended;
              iy,ix,yoMin,yeMax,xoMin,xeMax,r,i,j : integer;
              Scan1: Integer;        // Valeur de la 1ère adresse de ScanLine.
              MemLineSize: Integer;  // Taille d'une ligne de pixels en mémoire (en octets).
              BytesPerPix: Integer;  // Taille d'un pixel (en octets)
              CurrentScan: Integer;  // valeur de pointeur courant
              clEcran    : tColor;   // Couleur arrière-plan
              RPen,GPen,BPen : byte; // Composantes de CoulPen
              CoulDec    : tColor;   // Couleur légèrement décalée de CoulPen
              RDec,GDec,BDec : byte; // Composantes de CoulPen
              clPNX,clDNX : TColor;  // NotXor de CoulPen et de clEcran, et NotXor de Coul-décalée et de clEcran
     
              procedure InitCouleurs;
              const     D = 2;
              begin     RPen:=GetRValue(CoulPen); GPen:=GetGValue(CoulPen); BPen:=GetBValue(CoulPen);
                        if RPen>127 then RDec:=RPen-D else RDec:=RPen+D;
                        if GPen>127 then GDec:=GPen-D else GDec:=GPen+D;
                        if BPen>127 then BDec:=BPen-D else BDec:=BPen+D;
                        CoulDec:=RGB(RDec,GDec,BDec);
              end;
     
              function clNotXor(clPen,clEcran : TColor) : TColor;
              //       Renvoie couleur NotXor = not (pen.color xor clEcran)
              var      R,G,B, RP,GP,BP, RE,GE,BE : byte;
              begin    RP:=getRvalue(clPen);   GP:=getGvalue(clPen);   BP:=getBvalue(clPen);
                       RE:=getRvalue(clEcran); GE:=getGvalue(clEcran); BE:=getBvalue(clEcran);
                       R:=not (RP xor RE);     G:=not (GP xor GE);     B:=not (BP xor BE);
                       Result:=RGB(R,G,B);
              end;
     
              procedure GSPixel; // Gère les modifs de couleurs
              begin if (ix>0) and (ix<BMP.Width-1) and (iy>0) and (iy<BMP.height-1) then begin
                       CurrentScan:=Scan1 + iy * MemLineSize + ix * BytesPerPix;
                       with PRGBQuad(CurrentScan)^ do begin
                            case TraceMode of
                                 tmAffiche,
                                 tmEfface : begin clEcran:=RGB(rgbRed,rgbGreen,rgbBlue);
                                                  clPNX:=clNotXor(CoulPen,clEcran);
                                                  clDNX:=clNotXor(CoulDec,clEcran);
                                                  if TraceMode=tmAffiche then
                                                  begin if clEcran=CoulPen then
                                                        begin rgbRed  := RDec;  // Coul Pen décalée
                                                              rgbGreen:= GDec;
                                                              rgbBlue := BDec;
                                                        end else //clEcran <> CoulPen alors NotXor avec Coul Pen
                                                        begin rgbRed  := GetRValue(clPNX);
                                                              rgbGreen:= GetGValue(clPNX);
                                                              rgbBlue := GetBValue(clPNX);
                                                        end;
                                                  end else // mode efface :
                                                  if TraceMode=tmEfface then
                                                  begin if clEcran=CoulDec then
                                                        begin rgbRed  :=not (GetRValue(clDNX) xor RPen);
                                                              rgbGreen:=not (GetGValue(clDNX) xor GPen);
                                                              rgbBlue :=not (GetBValue(clDNX) xor BPen);
                                                        end  else // clEcran <> CoulDec alors NotXor avec Coul Pen
                                                        begin rgbRed  := GetRValue(clPNX);
                                                              rgbGreen:= GetGValue(clPNX);
                                                              rgbBlue := GetBValue(clPNX);
                                                        end;
                                                  end;
                                            end;
                                 else begin rgbRed   := RPen;  // pmCopy (utilisé uniquement lors d'un appel pour un tracé de finition serré)
                                            rgbGreen := GPen;
                                            rgbBlue  := BPen;
                                      end;
                            end;
                       end;
                    end;
              end;
     
    begin     BMP.PixelFormat:=pf24bit;
              Scan1 := Integer(BMP.ScanLine[0]); //Pointe sur la 1ère ligne du Bitmap.
              MemLineSize := Integer(BMP.ScanLine[1]) - Scan1;
              BytesPerPix := Abs(MemLineSize div BMP.Width);
     
              InitCouleurs;
              miep:=epTrait/2; rr:=miEp; ep:=0;
              if xe=xo then // Verticale
              begin xo1:=xo - miep; xo2:=xo + miep; yo1:=min(yo,ye); ye1:=max(yo,ye);
                    for ix:=round(xo1) to round(xo2) do begin
                        // Embouts arrondis :
                        d:=abs(rr-ep); u:=sqrt(sqr(rr)-sqr(d));
                        yoMin:=round(yo1-u); yeMax:=round(ye1+u);
                        for iy:=yoMin to yeMax do GSPixel;
                        ep:=ep+1;
                    end;
                    EXIT;
              end;
              if ye=yo then // Horizontale
              begin yo1:=yo - miep; yo2:=yo + miep; xo1:=min(xo,xe); xe1:=max(xo,xe);
                    for iy:=round(yo1) to round(yo2) do begin
                        // Embouts arrondis :
                        d:=abs(rr-ep); u:=sqrt(sqr(rr)-sqr(d));
                        xoMin:=round(xo1-u); xeMax:=round(xe1+u);
                        for ix:=xoMin to xeMax do GSPixel;
                        ep:=ep+1;
                    end;
                    EXIT;
              end;
              // Droites inclinées
              Theta:=arcTan2(ye-yo,xe-xo);
              a:=tan(Theta);
              b:=yo - a*xo;
              si:=sin(Theta);   co:=cos(Theta); mis:=miep*si;  mic:=miep*co;
              xo1:=xo + mis;    yo1:=yo - mic;  xo2:=xo - mis; yo2:=yo + mic;
              xe1:=xe + mis;    ye1:=ye - mic;  xe2:=xe - mis; ye2:=ye + mic;
              sinco:=sin(Pi/2-theta);
              cosco:=cos(Pi/2-theta);
              dy:=abs(ye-yo); dx:=abs(xe-xo);
              if dy>=dx then // "y = a.x + b" --> x:= (y - b)/a
              begin yorMin:=min(yo1,ye1); yerMax:=max(yo1,ye1);
                    b:=ye1 - a*xe1; ep:=0;
                    repeat // Embouts arrondis :
                           d:=abs(rr-ep); u:=sqrt(sqr(rr)-sqr(d)); u:=abs(u*si);
                           // Suite du tracé
                           for iy:=round(yorMin-u) to round(yerMax+u) do
                           begin x:= (iy - b)/a; ix:=round(x); GSPixel; end;
                           if TraceMode<>tmCopy then begin
                               ep:=ep+1;
                               b:=b+1/sinco;
                               yorMin:=yorMin+sinco;
                               yerMax:=yerMax+sinco;
                           end else begin // si appel avec tmCopy alors passe de finition resserrée avec un pas de 0.5
                               ep:=ep+0.5;
                               b:=b+0.5/sinco;
                               yorMin:=yorMin+0.5*sinco;
                               yerMax:=yerMax+0.5*sinco;
                           end;
                    until (ep>=epTrait);
                    EXIT;
              end else // dy < dx
              begin b:=yo1 - a*xo1; ep:=0;
                    xo2:=min(xo1,xe1); xe2:=max(xo1,xe1); xorMin:=xo2; xerMax:=xe2;
                    repeat // Embouts arrondis :
                           d:=abs(rr-ep); u:=sqrt(sqr(rr)-sqr(d)); u:=abs(u*co);
                           // Suite de la droite
                           for ix:=round(xorMin-u) to round(xerMax+u) do
                           begin y:= a*ix + b; iy:=round(y); GSPixel; end;
                           if TraceMode<>tmCopy then begin
                               ep:=ep+1;
                               b:=b+1/sinco;
                               xorMin:=xorMin-cosco;
                               xerMax:=xerMax-cosco;
                           end else begin // si appel avec tmCopy alors passe de finition resserrée avec un pas de 0.5
                               ep:=ep+0.5;
                               b:=b+0.5/sinco;
                               xorMin:=xorMin-0.5*cosco;
                               xerMax:=xerMax-0.5*cosco;
                           end;
                    until (ep>=epTrait);
              end;
    end; // TracerDroite
    Reste plus qu'à trouver pourquoi il reste des traces dans les zones de croisements multiples cela me permettrait de résoudre un inconvénient lié à l'utilisation de Polyline car avec Polyline tous les tronçons élémentaires du même tracé d'une courbe par exemple ont la même couleur alors qu'avec ma bidouille je pourrais faire varier la couleur d'un tronçon au suivant ... et si j'utilise plusieurs fois Polyline pour un tel changement de couleurs je me retrouve à la case départ des "losanges blancs" dans les zones de recouvrement des extémités des tronçons élémentaires.

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  13. #13
    Membre confirmé
    Homme Profil pro
    Santé
    Inscrit en
    Septembre 2010
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Santé
    Secteur : Santé

    Informations forums :
    Inscription : Septembre 2010
    Messages : 290
    Points : 534
    Points
    534
    Par défaut ALGORITHME DE TRACE DE SEGMENT DE BRESENHAM
    re-Salut,

    On ne peut pas dire que cela donne un beau code. Mais, heureusement, côté performances, il est très efficace .

    J'ai aussi utilisé Scanline. Donc on travaille directement dans l'espace mémoire du Bitmap: un simple refresh à la fin des opérations suffit à afficher le résultat.

    Ca tourne sur pf24bit et pf32bit.
    Il n'y a que des Integer's et aucune trigo !
    Ca fonctionne de façon incrémentale, ce qui peut servir à tracer aussi des segments dégradés .

    Ce n'est pas commenté car ça ne sert à rien sur un tel code, mais on trouve toutes les explications ICI.

    Reste à implémenter la largeur de ligne et les croisements avec opérateurs logiques. L'ayant déjà fait, tu devrais coder ça en deux coups de cuillère à pot


    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
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
     
    procedure DrawSegment(const BMP: TBitMap; x1,y1,x2,y2,Col: Integer);
    	var
              e,dx,dy : Integer;       //Erreur, variation en X et en Y.
              Scan0   : Integer;      //Valeur du pointeur d'entrée dans le Bitmap.
              Scan    : Integer;     //Pointeur temporaire destiné à être incrémenté.
              Bpp     : Integer;    //Byte per pixel du Bitmap.
              pCol    : pRGBTriple;//Pointe sur la couleur.
              MLS     : Integer;  //Memory Line Size (en bytes) du Bitmap.
              W,H     : Integer; //Hauteur et largeur du Bitmap.
    	begin
      {INITIALISATION DES VARIABLES :
       NB: Ceci peut être fait ailleurs dans le code, cependant le tampon mémoire n'est pas garanti
       comme étant cohérent (opérations GDI récentes, par exemple). Il est donc conseillé d'appeler
       la méthode ScanLine[] après chaque opération à risque, ou avant chaque série d'accès à la
       mémoire afin de synchronisé le tampon.}
      Scan0 := Integer(BMP.ScanLine[0]);
      MLS   := Integer(BMP.ScanLine[1]) - Scan0; //Memory Line Size
      W     := BMP.Width ;
      H     := BMP.Height;
      Bpp   := Abs(MLS div W);
    	New(pCol);
    	with pCol^ do begin
      	rgbtBlue  := GetBValue(Col);
      	rgbtGreen := GetGValue(Col);
      	rgbtRed   := GetRValue(Col);
    	end;
      try
    		{DEBUT DE L'ALGO}
      	dx:= x2-x1;
      	if dx<>0 then begin
      		if dx>0 then begin
        		dy:= y2-y1;
          	if dy<>0 then begin
          		if dy>0 then begin
              	if dx>=dy then begin
                	e:= dx;
                	dx:= e  shl 1;
                	dy:= dy shl 1;
                	repeat
                    if (x1>=0) and (x1<W) and (y1>=0) and (y1<H) then begin
                  		Scan := Scan0;              //Si on se trouve dans le BMP ...
                  		Inc(Scan, y1*MLS + x1*Bpp);//(Peut être omis s'il n'y a pas le risque)
                  		pRGBTriple(Scan)^:= pCol^;//Display.
                    end;
                  	Inc(x1);
                  	e  := e - dy;
                  	if e<0 then begin
                  		Inc(y1);
                    	Inc(e,dx);
                  	end;
                	until x1=x2;   end
              	else begin
                	e  := dy;
                	dy := e  shl 1;
                	dx := dx shl 1;
                	repeat
                  	if (x1>=0) and (x1<W) and (y1>=0) and (y1<H) then begin
                  		Scan := Scan0;              //Si on se trouve dans le BMP ...
                  		Inc(Scan, y1*MLS + x1*Bpp);//(Peut être omis s'il n'y a pas le risque)
                  		pRGBTriple(Scan)^:= pCol^;//Display.
                    end;
                  	Inc(y1);
                  	Dec(e,dx);
                  	if e < 0 then begin
                  		Inc(x1);
                    	Inc(e,dy)
                  	end;
                	until y1 = y2;
              	end; end
            	else begin
              	if dx >= -dy then begin
                	e  := dx;
                	dx := e  shl 1;
                	dy := dy shl 1;
                	repeat
                  	if (x1>=0) and (x1<W) and (y1>=0) and (y1<H) then begin
                  		Scan := Scan0;              //Si on se trouve dans le BMP ...
                  		Inc(Scan, y1*MLS + x1*Bpp);//(Peut être omis s'il n'y a pas le risque)
                  		pRGBTriple(Scan)^:= pCol^;//Display.
                    end;
                  	Inc(x1);
                  	Inc(e,dy);
                  	if e < 0 then begin
                  		Dec(y1);
                    	Inc(e,dx);
                  	end;
                	until x1 = x2; end
              	else begin
              		e  := dy;
                	dy := e  shl 1;
                	dx := dx shl 1;
                	repeat
                  	if (x1>=0) and (x1<W) and (y1>=0) and (y1<H) then begin
                  		Scan := Scan0;              //Si on se trouve dans le BMP ...
                  		Inc(Scan, y1*MLS + x1*Bpp);//(Peut être omis s'il n'y a pas le risque)
                  		pRGBTriple(Scan)^:= pCol^;//Display.
                    end;
                  	Dec(y1);
                  	Inc(e,dx);
                  	if e > 0 then begin
                  		Inc(x1);
                    	Inc(e,dy);
                  	end;
                	until y1 = y2;
              	end;
            	end;   end
          	else begin
            	repeat
              	if (x1>=0) and (x1<W) and (y1>=0) and (y1<H) then begin
                	Scan := Scan0;              //Si on se trouve dans le BMP ...
                  Inc(Scan, y1*MLS + x1*Bpp);//(Peut être omis s'il n'y a pas le risque)
                  pRGBTriple(Scan)^:= pCol^;//Display.
                end;
              	Inc(x1);
            	until x1 = x2 ;
          	end;  end
        	else begin
        		dy := y2 - y1;
          	if dy <> 0 then begin
          		if dy > 0 then begin
              	if -dx >= dy then begin
                	e  := dx;
                	dx := e  shl 1;
                	dy := dy shl 1;
                	repeat
                  	if (x1>=0) and (x1<W) and (y1>=0) and (y1<H) then begin
                  		Scan := Scan0;              //Si on se trouve dans le BMP ...
                  		Inc(Scan, y1*MLS + x1*Bpp);//(Peut être omis s'il n'y a pas le risque)
                  		pRGBTriple(Scan)^:= pCol^;//Display.
                    end;
                  	Dec(x1);
                  	Inc(e,dy);
                  	if e >= 0 then begin
                  		Inc(y1);
                    	Inc(e,dx);
                  	end;
                	until x1 = x2;   end
              	else begin
                	e  := dy;
                	dy := e  shl 1;
                	dx := dx shl 1;
                	repeat
                  	if (x1>=0) and (x1<W) and (y1>=0) and (y1<H) then begin
                  		Scan := Scan0;              //Si on se trouve dans le BMP ...
                  		Inc(Scan, y1*MLS + x1*Bpp);//(Peut être omis s'il n'y a pas le risque)
                  		pRGBTriple(Scan)^:= pCol^;//Display.
                    end;
                  	Inc(y1);
                  	Inc(e,dx);
                  	if e <= 0 then begin
                  		Dec(x1);
                    	Inc(e,dy);
                  	end;
                	until y1 = y2;
              	end;   end
            	else begin
              	if dx <= dy then begin
                	e  := dx;
                	dx := e  shl 1;
                	dy := dy shl 1;
                	repeat
                  	if (x1>=0) and (x1<W) and (y1>=0) and (y1<H) then begin
                  		Scan := Scan0;              //Si on se trouve dans le BMP ...
                  		Inc(Scan, y1*MLS + x1*Bpp);//(Peut être omis s'il n'y a pas le risque)
                  		pRGBTriple(Scan)^:= pCol^;//Display.
                    end;
                  	Dec(x1);
                  	Dec(e,dy);
                  	if e >= 0 then begin
                  		Dec(y1);
                    	Inc(e,dx);
                  	end;
                	until x1 = x2;   end
              	else begin
              		e  := dy;
                	dy := e  shl 1;
                	dx := dx shl 1;
                	repeat
                  	if (x1>=0) and (x1<W) and (y1>=0) and (y1<H) then begin
                  		Scan := Scan0;              //Si on se trouve dans le BMP ...
                  		Inc(Scan, y1*MLS + x1*Bpp);//(Peut être omis s'il n'y a pas le risque)
                  		pRGBTriple(Scan)^:= pCol^;//Display.
                    end;
                  	Dec(y1);
                  	Dec(e,dx);
                  	if e >= 0 then begin
                  		Dec(x1);
                    	Inc(e,dy);
                  	end;
                	until y1 = y2;
              	end;
            	end;   end
          	else begin
            	repeat
              	if (x1>=0) and (x1<W) and (y1>=0) and (y1<H) then begin
                	Scan := Scan0;              //Si on se trouve dans le BMP ...
                  Inc(Scan, y1*MLS + x1*Bpp);//(Peut être omis s'il n'y a pas le risque)
                  pRGBTriple(Scan)^:= pCol^;//Display.
                end;
              	Dec(x1);
            	until x1 = x2 ;
          	end;
        	end;   end
      	else begin
      		dy := y2 - y1;
        	if dy  <> 0 then begin
        		if dy > 0 then begin
            	repeat
              	if (x1>=0) and (x1<W) and (y1>=0) and (y1<H) then begin
                	Scan := Scan0;              //Si on se trouve dans le BMP ...
                  Inc(Scan, y1*MLS + x1*Bpp);//(Peut être omis s'il n'y a pas le risque)
                  pRGBTriple(Scan)^:= pCol^;//Display.
                end;
              	Inc(y1);
            	until y1 = y2 ;   end
          	else begin
          		repeat
              	if (x1>=0) and (x1<W) and (y1>=0) and (y1<H) then begin
                	Scan := Scan0;              //Si on se trouve dans le BMP ...
                  Inc(Scan, y1*MLS + x1*Bpp);//(Peut être omis s'il n'y a pas le risque)
                  pRGBTriple(Scan)^:= pCol^;//Display.
                end;
              	Dec(y1);
            	until y1 = y2 ;
          	end;
      		end;
      	end;
        if (x2>=0) and (x2<W) and (y2>=0) and (y2<H) then begin
        	Scan := Scan0;              //Si on se trouve dans le BMP ...
          Inc(Scan, y2*MLS + x2*Bpp);//(Peut être omis s'il n'y a pas le risque)
          pRGBTriple(Scan)^:= pCol^;//Display du dernier point.
        end;
      finally   Dispose(pCol);   end;
    end;
    Cordialement,
    Cari

  14. #14
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 448
    Points
    28 448
    Par défaut
    Citation Envoyé par Caribensila Voir le message
    J'imagine qu'il utilise un algo qui ressemble à celui de tracé de segment de Bresenham et quelques opérations logiques de base.
    Mais, effectivement, il serait interressant d'en connaître les détails, et je n'ai encore rien trouvé pour le moment...
    il y a une méthode bête et méchante qui consiste à utiliser un tableau de boolean de la taille du bitmap...False au départ, True sur le premier pixel ce qui interdit de le mettre à jour deux fois
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  15. #15
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Bonjour,

    A Caribensila : Merci pour ton code, je le testerai lundi.

    Il n'y a que des Integer's et aucune trigo !
    : Bien joué. Par contre il faut aussi que je pige le fonctionnement de l'algo pour voir comment je peux y ajouter les extrémités arrondies.

    Reste à implémenter la largeur de ligne et les croisements avec opérateurs logiques.
    ... j'ai du pain sur la planche.

    A Paul TOTH :
    il y a une méthode bête et méchante qui consiste à utiliser un tableau de boolean de la taille du bitmap...False au départ, True sur le premier pixel ce qui interdit de le mettre à jour deux fois
    ... Ah ça m'intéresse : je suppose que cette astuce concerne la logique de base pour gèrer le problème du NotXor dans les zones des croisements ??? Pourrais-je en savoir un peu plus ? S.V.P

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  16. #16
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 448
    Points
    28 448
    Par défaut
    Citation Envoyé par Gilbert Geyer Voir le message
    Bonjour,

    A Caribensila : Merci pour ton code, je le testerai lundi.

    : Bien joué. Par contre il faut aussi que je pige le fonctionnement de l'algo pour voir comment je peux y ajouter les extrémités arrondies.


    ... j'ai du pain sur la planche.

    A Paul TOTH :

    ... Ah ça m'intéresse : je suppose que cette astuce concerne la logique de base pour gèrer le problème du NotXor dans les zones des croisements ??? Pourrais-je en savoir un peu plus ? S.V.P

    A+.
    ben c'est tout bête

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
      if flags[x,y] = False then
      begin
       flags[x,y] := True;
       pixels[x,y] := pixels[x,y] xor color;
      end;
    en y repensant, il y a encore plus simple, tu crées une copie du bitmap et tu te sert de l'original pour chaque pixel
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    // en résumé...
      Bmp2.Pixels[x, y] := Bmp1.Pixels[x, y] XOR color;
    // mais en ScanLine évidemment
    du coup c'est toujours la couleur d'origine qui est prise en compte et tu peux passer autant de fois que tu veux sur le même point, ça ne change rien

    ça double l'occupation mémoire, mais ça présente l'avantage de pouvoir effacer rapidement le dessin XOR en reprenant Bmp1 tout simplement au lieu de repasser un coup de XOR
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  17. #17
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 745
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 745
    Points : 13 306
    Points
    13 306
    Par défaut
    Citation Envoyé par Gilbert Geyer Voir le message
    ...mais en réalité il s'agit d'une série de dessins déplaçables tracés en mode vectoriel sur un BitMap unique
    Passer par un tableau de booléen ou une image de base fonctionnera toujours pour l'ajout, mais jamais pour la suppression (Déplacement d'un seul dessin)

    Il n'y a pas d'autres moyens que de passer par des images temporaires

  18. #18
    Membre confirmé
    Homme Profil pro
    Santé
    Inscrit en
    Septembre 2010
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Santé
    Secteur : Santé

    Informations forums :
    Inscription : Septembre 2010
    Messages : 290
    Points : 534
    Points
    534
    Par défaut
    @Gilbert Geyer,

    Je ne suis pas sûr d'avoir bien compris ce que tu voulais faire mais, de toute façon, je crois bien que Andnotor a raison et que ce serait plus facile de passer par des layers.

    Je te donne quand même l'algo pour dessiner les extrémités arrondies, ça peut toujours servir. Cet algo optimisé permet de paver entièrement le plan par des cercles concentriques et dessine donc des cercles ou des disques. Il permet aussi de faire des dégradés circulaires originaux.

    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
              {Optimisé pour Bitmap pf24bit et pf32bit}
    procedure DrawCircle(const BMP: TBitMap; Cx,Cy,Radius,Col: Integer);
    	var
              dx,dy : Integer;         //Variation en X et en Y.
              X,Y   : Integer;        //Coordonnées des points du cercle.
              Dtmnt : Integer;       //Le déterminant de l'algo.
              Scan0 : Integer;      //Valeur du pointeur d'entrée dans le Bitmap.
              Scan  : Integer;     //Pointeur temporaire destiné à être incrémenté.
              BPP   : Integer;    //Byte per pixel du Bitmap.
              pCol  : pRGBTriple;//Pointe sur la couleur.
              MLS   : Integer;  //Memory Line Size (en bytes) du Bitmap.
              W,H   : Integer; //Hauteur et largeur du Bitmap.
      begin
      Scan0         := Integer(BMP.ScanLine[0]);
      MLS           := Integer(BMP.ScanLine[1]) - Scan0; //Memory Line Size
      W             := BMP.Width ;
      H             := BMP.Height;
      Bpp           := Abs(MLS div W);
      New(pCol);
      try
      	with pCol^ do begin
      		rgbtBlue  := GetBValue(Col);
        	rgbtGreen := GetGValue(Col);
        	rgbtRed   := GetRValue(Col);
      	end;
        {DEBUT DE L'ALGO}
      	dx       := 0;
    		dy       := Radius;
    		Dtmnt    := Radius-1;
      	while dy >= dx do begin
        	X      := Cx+dy;
          Y      := Cy-dx;
          if (X>=0) and (X<W) and (Y>=0) and (Y<H) then begin
         		Scan := Scan0;
          	Inc(Scan, Y*MLS + X*Bpp);
         		pRGBTriple(Scan)^ := pCol^; //1er octant
          end;
          X      := Cx+dx;
          Y      := Cy-dy;
          if (X>=0) and (X<W) and (Y>=0) and (Y<H) then begin
         		Scan := Scan0;
          	Inc(Scan, Y*MLS + X*Bpp);
         		pRGBTriple(Scan)^ := pCol^; //2ème octant
          end;
    			X      := Cx-dx;
          Y      := Cy-dy;
          if (X>=0) and (X<W) and (Y>=0) and (Y<H) then begin
          	Scan := Scan0;
          	Inc(Scan, Y*MLS + X*Bpp);
          	pRGBTriple(Scan)^ := pCol^; //3ème octant
          end;
          X      := Cx-dy;
          Y      := Cy-dx;
          if (X>=0) and (X<W) and (Y>=0) and (Y<H) then begin
         		Scan := Scan0;
          	Inc(Scan, Y*MLS + X*Bpp);
         		pRGBTriple(Scan)^ := pCol^; //4ème octant
          end;
          X      := Cx-dy;
          Y      := Cy+dx;
          if (X>=0) and (X<W) and (Y>=0) and (Y<H) then begin
         		Scan := Scan0;
          	Inc(Scan, Y*MLS + X*Bpp);
        		pRGBTriple(Scan)^ := pCol^; //5ème octant
          end;
          X      := Cx-dx;
          Y      := Cy+dy;
          if (X>=0) and (X<W) and (Y>=0) and (Y<H) then begin
          	Scan := Scan0;
          	Inc(Scan, Y*MLS + X*Bpp);
         		pRGBTriple(Scan)^ := pCol^; //6ème octant
          end;
          X      := Cx+dx;
          Y      := Cy+dy;
          if (X>=0) and (X<W) and (Y>=0) and (Y<H) then begin
         		Scan := Scan0;
          	Inc(Scan, Y*MLS + X*Bpp);
         		pRGBTriple(Scan)^ := pCol^; //7ème Octant
          end;
         	X      := Cx+dy;
          Y      := Cy+dx;
          if (X>=0) and (X<W) and (Y>=0) and (Y<H) then begin
         		Scan := Scan0;
          	Inc(Scan, Y*MLS + X*Bpp);
         		pRGBTriple(Scan)^ := pCol^; //8ème octant
          end;
     
          if Dtmnt >= dx shl 1 then begin
    					Dec(Dtmnt,dx shl 1+1);
    					Inc(dx);   end
          else	if Dtmnt <= (Radius-dy) shl 1 then begin
           					Inc(Dtmnt,dy shl 1-1);
           					Dec(dy); end
          			else begin
           					Inc(Dtmnt,(dy-dx-1) shl 1);
           					Dec(dy);
           					Inc(dx);
                end;
    		end;
      finally   Dispose(pCol);   end;
    end;

  19. #19
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Re-bonjour,

    A Paul TOTH : Merci pour ces explications je vais méditer là-dessus.

    A Andnotor :
    Passer par un tableau de booléen ou une image de base fonctionnera toujours pour l'ajout, mais jamais pour la suppression (Déplacement d'un seul dessin)
    ... et pourquoi cela ne fonctionnerait-il pas pour l'effacement d'un dessin ???
    (bien entendu je ne déplace qu'un seul dessin à la fois)

    A Caribensila :
    Je ne suis pas sûr d'avoir bien compris ce que tu voulais faire ...
    ... je trace un premier trait (ou dessin) avec sa couleur sur un arrière-plan qui peut comporter déjà des zones colorées,
    ... je trace un deuxième trait dans une autre couleur et qui croise le premier trait et dans la zone de leur croisement je veux que la couleur du 2ième reste inchangée.
    ... ensuite j'agrippe l'un des deux traits ou dessins avec la souris pour le déplacer ce qui nécessite :
    - d'abord de l'affacer en rétablissant les couleurs d'arrière-plan et de la zone du croisement
    - et ensuite de le re-tracer dans sa nouvelle position de déplacement.

    Pour ce qui est du tracé d'affichage et de l'effacement en mode NotXor bidouillé de mon code du 29/09/2010 14h54 cela marche assez bien sauf que si je croise beaucoup de traits dans la même zone de croisement il reste des traces lors de l'effacement c'est pourquoi je cherche à faire mieux.

    En tous cas merci pour ta procedure DrawCircle ... également sans trigo : chapeau !

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  20. #20
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 745
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 745
    Points : 13 306
    Points
    13 306
    Par défaut
    Citation Envoyé par Gilbert Geyer Voir le message
    ... et pourquoi cela ne fonctionnerait-il pas pour l'effacement d'un dessin ???
    (bien entendu je ne déplace qu'un seul dessin à la fois)
    Raison de plus
    Comment savoir avec un booléen qu'il y avait un croisement ?

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 4 1234 DernièreDernière

Discussions similaires

  1. Réponses: 0
    Dernier message: 03/10/2007, 13h11
  2. form en mode continu et detail couleur
    Par lolothom dans le forum VBA Access
    Réponses: 5
    Dernier message: 20/07/2007, 10h31
  3. Problème "ON_CONTROL_RANGE" mode release
    Par BoyzInDaProject dans le forum MFC
    Réponses: 5
    Dernier message: 11/05/2007, 17h24
  4. Problèmes en mode Debug
    Par pracede2005 dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 03/05/2007, 16h29
  5. problème en mode release
    Par Polux95 dans le forum Qt
    Réponses: 20
    Dernier message: 25/04/2007, 09h58

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