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 :

Dessin et vecteur


Sujet :

Langage Delphi

  1. #1
    Membre confirmé

    Inscrit en
    Novembre 2002
    Messages
    743
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 743
    Points : 500
    Points
    500
    Par défaut Dessin et vecteur
    bonjour a tous ,

    Je dessine des lignes dans un Timage.. et je dois pouvoir les déplacer.
    Actuellement je sélectionne ma ligne en lisant sa couleur et je la déplace.
    Cela marche tant que j'ai qu'une ligne, puisque je connais bien sur ces coordonnées de départs et d'arrivées. Mais plus si j'ai plusieurs lignes!!

    je suis donc à la recherche d'idées, de méthodes... pour récupérer les coordonnées d'une ligne que j'aurai préalablement tracé sur dans un Timage et sur la laquelle j'aurai cliqué. ( a savoir que les lignes on toute la même couleur)

    Le but serait de déterminer les coordonnées d'extrémités du segment sur lequel je clique ..

    merci pour votre aide ..
    Bye et bon code...

    Ce n'est pas tant l'aide de nos amis qui nous aide , mais notre confiance dans cette aide .

  2. #2
    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 430
    Points
    28 430
    Par défaut
    tu peux regarder MetaDraw ou encore SodaPlay
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2003
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 560
    Points : 576
    Points
    576
    Par défaut
    Bonjour,

    Une ligne droite est caractérisé par 2 points.
    Si vous ne dessinez pas une lignes mais une figure constitué de n segment de lignes (avec n > 0), votre figure est un ensemble de n' points (avec n' > 1).

    Donc si vous faite une liste d'objet ou de record contenant des ensembles de points, vous pouvez calculer les droites comprise entre ces points (voir au delà de ces points si c'est un droite et non un segment de droite).

    Vous pouvez aussi vous servir de cette liste d'ensemble de point pour recréer votre nouvelle image.

  4. #4
    Membre confirmé

    Inscrit en
    Novembre 2002
    Messages
    743
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 743
    Points : 500
    Points
    500
    Par défaut
    rebonjour a tous et merci pour vos idées..

    je suis aller voir les sites de Paul TOTH ils sont pas mal , SodaPlay était justement ce que je voulais l même en plus simple , mais je dessine sur un Image transparente pour avoir une image de fond et là c'est pas top ( rafraichissement de l'image trop lente ) !

    Tardiff Jean-François, Pour le tableau de coordonnée de mes lignes j'y avais pensé, mais comment déterminer que le "pixel" sur lequel le clique avec ma souris , fait partie d'une ligne donc je posséde les coordonnée ?

    bye a tous
    Bye et bon code...

    Ce n'est pas tant l'aide de nos amis qui nous aide , mais notre confiance dans cette aide .

  5. #5
    Expert éminent
    Avatar de Qwazerty
    Homme Profil pro
    La très haute tension :D
    Inscrit en
    Avril 2002
    Messages
    3 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations professionnelles :
    Activité : La très haute tension :D
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 898
    Points : 8 529
    Points
    8 529
    Par défaut
    SAlut
    Peut etre devrais tu mettre Form1.DoubleBuffering a true au chargement de ta form pour evité le sintillement.
    Je te proposerais bien mon propre travail sur les dessins de vecteur mais il n'est pas finalisé et tu risque d'avoir du bug :s
    A++
    Qwaz

    MagicQwaz := Harry Potter la baguette en moins
    Le monde dans lequel on vit
    Ma page perso DVP
    Dernier et Seul Tutoriel : VBA & Internet Explorer
    Dernière contribution : Lien Tableau Structuré et UserForm
    L'utilisation de l’éditeur de message

  6. #6
    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 430
    Points
    28 430
    Par défaut
    Citation Envoyé par petitcoucou31 Voir le message
    rebonjour a tous et merci pour vos idées..

    je suis aller voir les sites de Paul TOTH ils sont pas mal , SodaPlay était justement ce que je voulais l même en plus simple , mais je dessine sur un Image transparente pour avoir une image de fond et là c'est pas top ( rafraichissement de l'image trop lente ) !
    soit tu passes par le DoubleBuffering, soit tu travailles sur un Bitmap à part que tu viens afficher à l'écran sur le OnPaint. c'est exactement ce que fait le double buffer, sauf que du coup l'image est recalculée à chaque OnPaint, si tu gères toi même cette image, elle est recalculée uniquement quand tu le désires.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  7. #7
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2007
    Messages
    102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ardèche (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2007
    Messages : 102
    Points : 87
    Points
    87
    Par défaut
    a mon ( humble ) avis, tu fais fausse route.

    il faut pas détecter le pixel, mais détecter si la souris est proche d'une ligne ( avec des maths ). Ce qui suppose que les lignes tracées sont mémorisées dans une liste...( d'objet ligne par exemple )

    Ce qui permet alors de traiter les lignes, de les dessiner, de les enregistrer...bref de faire " un vrai petit logiciel de dessin ".

    Pascal 07

  8. #8
    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 430
    Points
    28 430
    Par défaut
    oui c'est ce type de code là
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  9. #9
    Membre chevronné
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Points : 1 975
    Points
    1 975
    Par défaut
    Peut-être qu'il faudrait repèrer tes lignes par une référence, un point.
    stocker toutes ses références dans un tableau de points et comparer les coordonnées de ses points de référence aux coordonnées de ta souris.
    en t'inspirant du code ci-joint, tu peux faire identifier la ligne par un test qui
    pourrait mesurer la distance entre les coords souris et les points de réf, la + petite distance identifie ta ligne ou quelque chose comme ça car là c'est un peu réducteur si deux lignes sont très proches, ça ne collera pas . Après, le déplacement, j'ai essayé sur une ligne...(tu le fais sur la couleur)voici le code pas le temps d'appprofondir. Si ça peut aider...

    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
     
    type
      TForm1 = class(TForm)
        PaintBox1: TPaintBox;
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
        procedure PaintBox1Paint(Sender: TObject);
        procedure PaintBox1MouseUp(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
          Y: Integer);
        procedure PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure FormCreate(Sender: TObject);
      private
        { Déclarations privées }
        autorisation:boolean;
        xo,yo:integer;
        pt,pti:Tpoint;
        espace:Tbitmap;
        procedure dessiner;
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
    pt:=point(paintbox1.ClientWidth div 2,paintbox1.ClientHeight div 2);
    espace:=Tbitmap.Create;
     
    with espace do begin
    width:=Paintbox1.ClientWidth;
    height:=paintbox1.ClientHeight;
    end;
     
    end;
     
    procedure Tform1.dessiner;
    begin
    with espace.Canvas do begin
    brush.Color:=clwhite;
    fillrect(paintbox1.clientrect);
    pen.Width:=4;
    moveto(pt.X-50,pt.Y-50);
    lineto(pt.X+10,pt.Y+60);
    end;
    paintbox1.Canvas.Draw(0,0,espace);
    end;
     
     
    procedure TForm1.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
    if espace.Canvas.Pixels[x,y]=clblack then begin
    autorisation:=true;
    xo:=x;
    yo:=y;
    pti:=pt;
    end;
    end;
     
    procedure TForm1.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    begin
    if autorisation then begin
    pt.X:=pti.X+x-xo;
    pt.Y:=pti.Y+y-yo;
    dessiner;
    end;
    end;
     
    procedure TForm1.PaintBox1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
    autorisation:=false;
    end;
     
    procedure TForm1.PaintBox1Paint(Sender: TObject);
    begin
    dessiner;
    end;
     
    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
    espace.Free;
    end;
     
    end.

  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 263
    Points
    3 263
    Par défaut
    Salut,

    ... si deux lignes sont très proches, ça ne collera pas
    Lors du tracé de la 1ère ligne je placerais les coordonnées xo,yo du point-origine et du point d'extrémite (se,ye) dans un tableau (et idem pour les lignes suivantes) et au-lieu d'utiliser le "if espace.Canvas.Pixels[x,y]=clblack then begin autorisation:=true;" je ferais appel à un "if PointEstIlSurLigne(X,Y, xo,yo,xe,ye) then" où la fonction PointEstIlSurLigne détemine par calcul si oui/non le point X,Y se trouve rigoureusement (à Epsilon près) aligné sur la droite y = a.x + b qui passe par les points d'extrémité d'une des lignes recensées dans le tableau ... de toutes façons deux lignes tellement proches au point que leurs pixels se touchent sur une certaine distance c'est forcément des parallèles et si elles ne sont pas parrallèles suffit de cliquer à un endroit où elles sont séparées d'au moins un pixel.

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

  11. #11
    Expert éminent
    Avatar de Qwazerty
    Homme Profil pro
    La très haute tension :D
    Inscrit en
    Avril 2002
    Messages
    3 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations professionnelles :
    Activité : La très haute tension :D
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 898
    Points : 8 529
    Points
    8 529
    Par défaut
    SAlut
    Moi j'ai utilisé les regions pour reperer si la souris est sur un vecteur, l'avantage avec les region c'est que tu fais PtInRegion et hop tu sais si le point representé par la position de ta souris fait partie du vecteur
    A++
    Qwaz

    MagicQwaz := Harry Potter la baguette en moins
    Le monde dans lequel on vit
    Ma page perso DVP
    Dernier et Seul Tutoriel : VBA & Internet Explorer
    Dernière contribution : Lien Tableau Structuré et UserForm
    L'utilisation de l’éditeur de message

  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 263
    Points
    3 263
    Par défaut
    Salut,

    tu fais PtInRegion et hop tu sais si le point representé par la position de ta souris fait partie du vecteur
    ... Eh ben oui, je l'avais oublié ce PtInRegion,
    ... Bigre, j'étais parti pour réinventer le fil à couper le beurre !.

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

  13. #13
    Membre chevronné
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Points : 1 975
    Points
    1 975
    Par défaut
    illustration de mes propos:

    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
     
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ExtCtrls;
     
    type
      TForm1 = class(TForm)
        PaintBox1: TPaintBox;
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
        procedure PaintBox1Paint(Sender: TObject);
        procedure PaintBox1MouseUp(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
          Y: Integer);
        procedure PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure FormCreate(Sender: TObject);
      private
        { Déclarations privées }
        autorisation:boolean;
        xo,yo,indice:integer;
        coulfond:Tcolor;
        pti:Tpoint;
        pt:array[0..3] of Tpoint;
        espace:Tbitmap;
        Function test(x,y:integer):integer;
        procedure dessiner;
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.FormCreate(Sender: TObject);
    var l,h:integer;
    begin
    l:=paintbox1.ClientWidth;
    h:=paintbox1.clientheight;
    coulfond:=clwhite;
    pt[0]:=point(l div 2,10);
    pt[1]:=point(10,h div 2);
    pt[2]:=point(l div 2 ,h-10);
    pt[3]:=point(l-10,h div 2);
    espace:=Tbitmap.Create;
     
    with espace do begin
    width:=Paintbox1.ClientWidth;
    height:=paintbox1.ClientHeight;
    end;
     
    end;
     
    procedure Tform1.dessiner;
    begin
    with espace.Canvas do begin
    brush.Color:=coulfond;
    fillrect(paintbox1.clientrect);
    pen.Width:=4;
    pen.Color:=clred;
    moveto(pt[0].x-50,pt[0].y);
    lineto(pt[0].x+50,pt[0].y);
    pen.Color:=clgreen;
    moveto(pt[1].x,pt[1].y-50);
    lineto(pt[1].x,pt[1].y+50);
    pen.Color:=clyellow;
    moveto(pt[2].x-50,pt[2].y);
    lineto(pt[2].x+50,pt[2].y);
    pen.Color:=clblue;
    moveto(pt[3].x,pt[3].y-50);
    lineto(pt[3].x,pt[3].y+50);
    end;
    paintbox1.Canvas.Draw(0,0,espace);
    end;
     
     
    procedure TForm1.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
    if espace.Canvas.Pixels[x,y]<>coulfond then begin
    autorisation:=true;
    xo:=x;
    yo:=y;
    indice:=test(x,y);
    pti:=pt[indice];
    screen.Cursor:=crhandpoint;
    end;
    end;
     
    procedure TForm1.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    begin
    if autorisation then begin
    pt[indice]:=point(pti.x+x-xo,pti.y+y-yo);
    dessiner;
    end;
    end;
     
    procedure TForm1.PaintBox1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
    autorisation:=false;
    screen.Cursor:=crdefault;
    end;
     
    procedure TForm1.PaintBox1Paint(Sender: TObject);
    begin
    dessiner;
    end;
     
    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
    espace.Free;
    end;
     
    function Tform1.test(x,y:integer):integer;
    var i,min,val,ind:integer;
        d:array[0..3]of integer;
    begin
    val:=1000;
    min:=1000;   //volontairement grand au départ
    for i:=0 to 3 do begin
    d[i]:=round(sqrt(sqr(x-pt[i].x)+sqr(y-pt[i].y)));
    if d[i]<=val then  val:=d[i];
    if val<min then begin min:=val;
                           ind:=i;
                         end;
    end;
    result:=ind;
    end;
     
    end.
    ça a l'air de marcher... voire avec les régions bonne idée...

  14. #14
    Membre chevronné
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Points : 1 975
    Points
    1 975
    Par défaut
    avec les régions ou ptinrect, on risque d'accentuer les conflits en cas de rapprochement des lignes.
    Il faudrait se lancer...à voir.
    avis aux amateurs.
    Ceci dit une amélioration de mon code avec la méthode de gilbert Geyer, ça devient très interessant. Pour les lignes très fines, c'est pas top...les régions l'emportent...( à peser le pour et le contre)

  15. #15
    Expert éminent
    Avatar de Qwazerty
    Homme Profil pro
    La très haute tension :D
    Inscrit en
    Avril 2002
    Messages
    3 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations professionnelles :
    Activité : La très haute tension :D
    Secteur : Service public

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 898
    Points : 8 529
    Points
    8 529
    Par défaut
    SAlut
    Comme je l'ai dis mon compo est pas terminé, je met ici la methode que j'ai utilisé, sachant que moi c'est des vecteurs et pas juste un trait.

    Il y a aussi une partie qui tient compte de cercle que je met aux extremités du vecteur pour visualiser les poignées de deplacement.

    En se qui concerne la precision pour ma part je cherche pas un truc super super precis, meais en affinant mon code je pense pouvoir avoir un resultat satisfaisant (l'espoire fait vivre non )

    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
    function TVecteur.PtInVecteur(APoint : TPoint): TZoneEtape;
    var
        PtFleche : Array [0..6] of TPoint;
        RgnFleche, RgnFE, RgnFO, RgnCercle, RgnCadenas : Hrgn;
        IDelta : Integer;
    begin
         //Utiliser InvRgn pour inverser les couleur lors du passage sur un element
     
     
         //créer des regions recouvrant les etapes(une par une) est tester si le Point est dessus
         result.Zone := Ze_out; //Initialisation des valeur
         result.Index := -1;    //On se trouve dans aucune des zones
     
         If FUsed And FVisible Then
              {//La region de la fleche
              PtFleche[0] := Etapes[I].Fleche.Extremite;
              PtFleche[1] := Etapes[I].Fleche.PointeB;
              PtFleche[2] := Etapes[I].Fleche.PointeA;
              PtFleche[3] := Etapes[I].Fleche.Extremite;
              PtFleche[4] := Etapes[I].Fleche.Origine;
              if Etapes[I].Fleche.Angle > 180 Then Delta = 2 Else Delta = -2;
              PtFleche[5].x := Etapes[I].Fleche.Origine.x + Delta;
              PtFleche[5].y := Etapes[I].Fleche.Origine.y + Delta;
              PtFleche[6].x := Etapes[I].Fleche.Extremite.x + Delta;
              PtFleche[6].y := Etapes[I].Fleche.Extremite.y + Delta;}
     
              //Code suivant a tester
              IDelta := FPen.Width Div 2 // Fonction de l'epaisseur du trait (moitier du trait)
              If IDelta < 1 Then IDelta := 1;
              PtFleche[0] := FExtremite;
              PtFleche[1] := FPointeB;
              PtFleche[2] := FPointeA;
              PtFleche[3] := FExtremite;
              OffsetPoint(PtFleche[3],-IDelta,-IDelta);
              PtFleche[4] := FOrigine;
              OffsetPoint(PtFleche[4],-IDelta,-IDelta);
              PtFleche[5] := FOrigine;
              OffsetPoint(PtFleche[5],IDelta,IDelta);
              PtFleche[6] := FExtremite;
              OffsetPoint(PtFleche[6],IDelta,IDelta);
     
     
     
              RgnFleche := CreatePolygonRgn(PtFleche,6,WINDING);
     
              If (PtInRegion(RgnFleche,APoint.X, APoint.Y)) Then
              begin
                   result.Zone := Ze_Fleche;
                   result.Index := I;                                        v//a pas il faut un N° d'index pris chez le parent GetIndex ou un truc du genre
              end;
              //On purge la memoire
              DeleteObject(RgnFleche);
     
              If ((FParent Is TImageEtape).Mode = M_Modify) Then
              begin
                   //Gestion des poignées
                   RgnFE := CreateEllipticRgnIndirect(CreateRect(FExtremite,FTaillePoigne));
                   RgnFO := CreateEllipticRgnIndirect(CreateRect(FOrigine,FTaillePoigne));
     
                   FindExit := True;
                   If PtInRegion(RgnFO,APoint.X,APoint.Y) Then
                   begin
                        result.Zone := Ze_FlechePOri;
                        result.Index := I;                                   v//a pas il faut un N° d'index pris chez le parent GetIndex ou un truc du genre
                   end
                   Else If PtInRegion(RgnFE,APoint.X,APoint.Y) Then
                   begin
                        result.Zone := Ze_FlechePExt;
                        result.Index := I;                                   v//a pas il faut un N° d'index pris chez le parent GetIndex ou un truc du genre
                   end;
                   //On purge la memoire
                   DeleteObject(RgnFO);
                   DeleteObject(RgnFE);
              end;
    end;
    A++
    Qwaz

    MagicQwaz := Harry Potter la baguette en moins
    Le monde dans lequel on vit
    Ma page perso DVP
    Dernier et Seul Tutoriel : VBA & Internet Explorer
    Dernière contribution : Lien Tableau Structuré et UserForm
    L'utilisation de l’éditeur de message

  16. #16
    Membre confirmé

    Inscrit en
    Novembre 2002
    Messages
    743
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 743
    Points : 500
    Points
    500
    Par défaut
    Salut,

    Oula bcp de chose se sont passées depuis mon dernier passage ...

    Alors ou en suis je depuis ma dernière visite ?!

    Toutes les extrémités de mes segment de droite sont sauvés dans un record.
    Je ne selectionne plus ma ligne en fonction de la couleur di pixels !

    et depuis quelque temps je galère avec les équations du type y = a.x + b et bien d'autre... qui en me donne pas un résultat satisfaisant.

    je vais donc me pencher sur les régions.. comme me dit Archimede ( ah ! toujours de bonne idées celui là !lol ).

    allez je vais voir ces regions ... merci pour vos aides !!


    et et je galere pour selectionner ma droite
    Bye et bon code...

    Ce n'est pas tant l'aide de nos amis qui nous aide , mais notre confiance dans cette aide .

  17. #17
    Membre chevronné
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Points : 1 975
    Points
    1 975
    Par défaut
    Salut,

    je vais donc me pencher sur les régions.. comme me dit Archimede ( ah ! toujours de bonne idées celui là !lol ).
    merci c'est sympa, mais c'est qwazerty qui a eu l'idée des régions lol. On fait souvent la bonne paire sur ce genre de questions.
    Et puis les connaissances et la pertinence de gilbert Geyer sont toujours très utiles. Il affine et mesure le truc. L'union fait la force.
    sans compter sur paul Toth qui nous fait le plaisir de s'impliquer sur le forum.
    Quand on voit son niveau, on se sent tout petit petit

    a+

  18. #18
    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 263
    Points
    3 263
    Par défaut
    Salut,

    Il y a de fortes chances que if PtInRegion() effectue des calculs similaires à celle d'un if MontPointXYSurDroiteYEgalAXPlusB() lorsque la région en question se réduit à la droite y = a.x + b d'épaisseur suffisante,
    ... reste à savoir si on peut réduire une région à un rectangle incliné dont le petit côté est large de seulement 1 pixel c'est à dire dont les deux côtés les plus longs sont superposés
    ... ou bien si la région minimale doit être large d'au moins 2 pixels pour permettre à la function PtInRegion de marcher.
    ... mais ceci se remarquera forcément lors des tests ... suffit de commencer avec une largeur de 4 pixels, de tester, puis de réduire à 3 et ainsi de suite.
    ... avec un rectangle incliné large d'1 seul pixel et les effets d'escalier dûs à l'inclinaison cela risque de ne pas fonctionner mais avec 2 ou 3 pixels cela devrait être bon, mais tant mieux si ça marchait avec un 1 seul pixel comme avec if Pixels[x,y]=CouleurCible.

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

  19. #19
    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 430
    Points
    28 430
    Par défaut
    ça me parait compliqué votre histoire de région

    voici la fonction que j'utilise dans SodaPlay

    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
     
    // fLink est une liste de TLink qui définissent des segments de droite
      for i:=0 to fLink.Count-1 do
     // un TLink défini deux points a et b
       with Link[i]^ do begin
      // on prend le point d'origine et les deltas x et y
        x:=a.mx; dx:=b.mx-x;
        y:=a.my; dy:=b.my-y;
      // par défaut, on est "loin"
        t:=5;
      // si la ligne est plutôt horizontale (dx>dy)
        if abs(dx)>abs(dy) then begin
       // on vérifie qu'on ne dépasse pas en X
         if ((MouseX>x)and(MouseX<x+dx))or((MouseX<x)and(MouseX>x+dx)) then begin
       // calcul de la valeur de Y=f(x) sur la ligne, et en prend la différence avec le Y de la souris
          f:=MouseY-(y+(dy*(MouseX-x))/dx);
          t:=abs(Trunc(f));
         end;
        end else begin
     // sinon c'est pareil mais avec X=f(y)
         if ((MouseY>y)and(MouseY<y+dy))or((MouseY<y)and(MouseY>y+dy)) then begin
          if dy=0 then
           t:=abs(MouseX-X)
          else begin
           f:=MouseX-(x+(dx*(MouseY-y))/dy);
           t:=abs(Trunc(f));
          end;
         end;
        end;
      // on regarde si on est assez proche
        if t<4 then begin
         Result:=Link[i];
         exit;
        end;
       end;
     // sinon la souris n'est sur aucun TLink
      Result:=nil;
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  20. #20
    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 263
    Points
    3 263
    Par défaut
    Bonjour,

    N'ayant pas le type TLink sous Delphi-5 et vu que la piste des régions est explorée par d'autres je me suis amusé à tester la détection d'un MouseDown sur des tronçons de droite du style y= a*x + b tracés directement sur le canvas de la Form qui contient un Bouton pour les tracer et un Label-Témoin qui prend la couleur de la droite épaisse de seulement 1 Pixel sur laquelle on a cliqué (faut viser juste avec 1 seul Pixel) mais ça marche :
    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
     
    // pour détection de droites épaisses d'1 seul pixel
     
    type TDroite = record
                      xo,yo,           // coordonnées d'origine
                      xe,ye : integer; // coordonnées d'extrémité
                      coulTrait : TColor;
                   end;
     
         TDroites = array [0..4] of TDroite;
     
    var  MesDroites : TDroites;
     
    procedure TForm1.FormShow(Sender: TObject);
    begin     with MesDroites[0] do
              begin xo:=50; yo:=50; xe:=200; ye:=100; coulTrait:=clRed; end;
              with MesDroites[1] do // parallèle à la précédente et en contact avec celle-ci
              begin xo:=50; yo:=51; xe:=200; ye:=101; coulTrait:=clLime; end;
              with MesDroites[2] do
              begin xo:=50; yo:=100; xe:=200; ye:=50; coulTrait:=clNavy; end;
              with MesDroites[3] do // verticale
              begin xo:=100; yo:=100; xe:=100; ye:=150; coulTrait:=clGreen; end;
              with MesDroites[4] do // horizontale
              begin xo:=100; yo:=100; xe:=50; ye:=100; coulTrait:=clYellow; end;
    end;
     
    procedure TForm1.btnTracerDroitesClick(Sender: TObject);
    var       i : integer;
    begin     for i:=Low(MesDroites) to High(MesDroites) do
              begin with canvas do
                    begin pen.Width:=1;
                          pen.mode:=pmCopy;
                          pen.style:=psSolid;
                          pen.color:=MesDroites[i].coulTrait;
                          moveTo(MesDroites[i].xo, MesDroites[i].yo);
                          LineTo(MesDroites[i].xe, MesDroites[i].ye);
                    end;
              end;
    end;
     
    function PointDansTronconDroite(xs,ys : integer; Droite : TDroite) : boolean;
    var      a, b : Extended; dx,dy,yc : integer; okx,oky : boolean;
    begin    Result:=False;
             dx:=Droite.xe - Droite.xo;
             dy:=Droite.ye - Droite.yo;
             if (dx=0) and (dy=0) then // Droite réduite à 1 seul point
             begin if (xs=Droite.xo) and (ys=Droite.yo) then Result:=True;
                   EXIT;
             end;
             okx:=False; oky:=False;
             if ((dy<0) and (ys<=Droite.yo) and (ys>=Droite.ye))
             or ((dy>0) and (ys<=Droite.ye) and (ys>=Droite.yo)) then oky:=True;
             if ((dx>0) and (xs<=Droite.xe) and (xs>=Droite.xo))
             or ((dx<0) and (xs<=Droite.xo) and (xs>=Droite.xe)) then okx:=True;
     
             if (dx=0) then // Droite verticale
             begin if (xs=Droite.xo) and oky then Result:=True;
                   EXIT;
             end else
             if (dy=0) then // Droite horizontale
             begin if (ys=Droite.yo) and okx then Result:=True;
                   EXIT;
             end else // Droite inclinée y = a.x + b
             begin a:=dy/dx; // pente
                   b:=Droite.yo - a*Droite.xo;
                   yc:=round(a*xs + b);
                   if (yc=ys) and okx and oky then Result:=True;
             end;
    end;
     
    procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    var       i : integer; ok : boolean;
    begin     i:=-1;
              repeat inc(i); ok:=PointDansTronconDroite(X,Y, MesDroites[i])
              until ok or (i=High(MesDroites));
              if ok then labelTemoin.color:=MesDroites[i].coulTrait
                    else labelTemoin.color:=clBtnFace;
    end;
    ... Pour ce test les droites d'indice 0 et 1 sont deux parallèles inclinées et en contact bord-à-bord pour tester la finesse de la détection de lignes très fines et le test est satisfasant.
    ... La function PointDansTronconDroite(xs,ys : integer; Droite : TDroite) : boolean marche également lorsque le tracé des traits est épais de plusieurs Pixels mais dans ce cas il encore plus difficile de viser juste avec la souris car il faut viser pile l'axe du tracé.
    ... et comme il faut viser la droite quelle que soit le code, il apparaît que la détection avec if Pixels[x,y]=CouleurTrait présente au moins l'avantage de faciliter cette visée lorsque les traits sont épais de plusieurs pixels, mais dans le cas de lignes très fines cette difficulé est la même qu'avec PointDansTronconDroite.

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

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

Discussions similaires

  1. dessiner vecteur 3D
    Par zaffef dans le forum MATLAB
    Réponses: 3
    Dernier message: 19/06/2015, 12h36
  2. Dessiner les vecteurs de flux optique
    Par nesnes2011 dans le forum OpenCV
    Réponses: 1
    Dernier message: 16/06/2015, 15h31
  3. dessiner un vecteur 3D
    Par sdecorme dans le forum MATLAB
    Réponses: 1
    Dernier message: 06/11/2013, 11h54
  4. [vecteurs] dessiner les courbes de Bezier
    Par luta dans le forum Flash
    Réponses: 4
    Dernier message: 03/07/2006, 10h58
  5. Réponses: 3
    Dernier message: 12/06/2002, 20h03

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