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

Composants VCL Delphi Discussion :

Un bitmap ou canvas qui travaille directement en coordonnées mathématiques


Sujet :

Composants VCL Delphi

  1. #1
    Membre expérimenté
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    avril 2005
    Messages
    1 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : avril 2005
    Messages : 1 496
    Points : 1 670
    Points
    1 670
    Par défaut Un bitmap ou canvas qui travaille directement en coordonnées mathématiques
    Un truc sympa est de réaliser un composant qui dérive d'un bitmap et qui permet de raisonner directement en coordonnées mathématiques plutôt qu'en coordonnées informatiques.

    Par exemple, Monbitmap:=Tmonbitmap.create(monwidth,monheight,-10,10,-15,15)

    ainsi, c'est comme si je réalisais un repérage mathématique en extended
    avec minx,maxx,miny et maxy.

    dans mon exemple, on va de -10 à +10 en abscisse et j'ai redéfini toutes les méthodes de dessin de mon composant...
    exemple un line(rpoint1,rpoint2) pour tracer une ligne ou rpoint est un record
    type Trpoint
    x,y:extended;
    end;

    comme ça, c'est nickel, il suffit de faire son dessin sur une feuille quadrillée en
    coords mathématiques et de pondre une application graphique en 3 coups de click.
    Puis pour se faire des graphiques, c'est parfait.
    Avec ça, on raisonne directement en coordonnées réelles.

    @+

  2. #2
    Membre éprouvé
    Avatar de CapJack
    Homme Profil pro
    Prof, développeur amateur vaguement éclairé...
    Inscrit en
    mars 2004
    Messages
    622
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Prof, développeur amateur vaguement éclairé...
    Secteur : Enseignement

    Informations forums :
    Inscription : mars 2004
    Messages : 622
    Points : 984
    Points
    984
    Par défaut
    Tu as trouvé une méthode pour le faire simplement, Archimède ? Faudrait que tu nous donnes ton code...

  3. #3
    Membre expérimenté
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    avril 2005
    Messages
    1 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : avril 2005
    Messages : 1 496
    Points : 1 670
    Points
    1 670
    Par défaut
    cadeau... si tu veux un exemple, tu me le dis...

  4. #4
    Membre éprouvé
    Avatar de CapJack
    Homme Profil pro
    Prof, développeur amateur vaguement éclairé...
    Inscrit en
    mars 2004
    Messages
    622
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Prof, développeur amateur vaguement éclairé...
    Secteur : Enseignement

    Informations forums :
    Inscription : mars 2004
    Messages : 622
    Points : 984
    Points
    984
    Par défaut
    Hmm.. tu redéfinis toutes les fonctions dont tu as besoin. C'est loin d'être "simple".

  5. #5
    Membre expérimenté
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    avril 2005
    Messages
    1 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : avril 2005
    Messages : 1 496
    Points : 1 670
    Points
    1 670
    Par défaut
    oui, c'est vrai. J'ai pris une ugraphique comme ça...
    J'en ai fait d'autres suivant les besoins.
    Là, c'est encore en construction puisqu'il faut la compléter.
    Sinon, l'utilisation en est très simple...
    Ce qu'il faut comprendre, c'est déjà la fonction transfo et ce que j'ai mis dans le constructor create.
    Tu te fais un petit schéma... essaie de voir comment passer des coords mathématiques aux coordonnées informatique et tu pigeras mes formules :

    Gx:=width/(xmax-xmin);
    Gy:=height/(ymax-ymin);
    O:=pt(-xmin*Gx,ymax*Gy);

    result:=point(round(O.x+x*Gx),round(O.y-y*Gy));

    après, je pense, tu sauras faire...

    @+

  6. #6
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : juin 2005
    Messages : 1 756
    Points : 4 150
    Points
    4 150
    Par défaut
    Citation Envoyé par Archimède Voir le message
    oui, c'est vrai. J'ai pris une ugraphique comme ça...
    J'en ai fait d'autres suivant les besoins.
    Là, c'est encore en construction puisqu'il faut la compléter.
    Sinon, l'utilisation en est très simple...
    Ce qu'il faut comprendre, c'est déjà la fonction transfo et ce que j'ai mis dans le constructor create.
    Tu te fais un petit schéma... essaie de voir comment passer des coords mathématiques aux coordonnées informatique et tu pigeras mes formules :

    Gx:=width/(xmax-xmin);
    Gy:=height/(ymax-ymin);
    O:=pt(-xmin*Gx,ymax*Gy);

    result:=point(round(O.x+x*Gx),round(O.y-y*Gy));

    après, je pense, tu sauras faire...

    @+
    Vous connaissez SetWindowOrgEx ? C'est une fonction du GDI qui permet de déplacer l'origine du repère. Après on peut continuer à dessiner avec les fonctions standards, il suffit de faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
      SetWindowOrgEx(Canvas.Handle, -Width div 2 , -height div 2, nil);
      Canvas.MoveTo(0, 0);
      Canvas.LineTo(Width div 2, 0);
      Canvas.MoveTo(0, 0);
      Canvas.LineTo(0, height div 2);
    Et on dessine les axes du repère, avec le 0 centré au milieu de la zone.

    A partir de NT4, on peut utiliser SetWorldTransform pour définir une transformation linéaire à appliquer au repère.
    Ainsi avec :

    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
     
    var
      xFrm : XFORM;
    begin
      xFrm.eM11 := 1;
      xFrm.eM12 := 0;
      xFrm.eM21 := 0;
      xFrm.eM22 := -1; // Retourne l'axe des y
      xFrm.eDx := width div 2; // changement d'origine X
      xFrm.eDy := height div 2; // changement d'origine Y
      SetGraphicsMode(Canvas.Handle, GM_ADVANCED);
      SetWorldTransform(Canvas.Handle, xFrm);
     
      Canvas.MoveTo(0, 0);
      Canvas.LineTo(Width div 2, 0);
      Canvas.MoveTo(0, 0);
      Canvas.LineTo(0, height div 2);
    On déplace à la fois le centre du repère, et on retourne l'axe des Y. C'est directement le GDI qui calculera toutes les transformations nécessaires : On applique une matrice de transformation aux coordonnées indiquées à chaque fonction de dessin.
    Ainsi, avec une seule fonction on peut réaliser la plupart des transformations : Symétrie, rotation, homotéthie, changement d'origine...

  7. #7
    Membre expérimenté
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    avril 2005
    Messages
    1 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : avril 2005
    Messages : 1 496
    Points : 1 670
    Points
    1 670
    Par défaut
    L'intérêt est de travailler directement avec des réels .
    Vos tranformations, changement d'origine, d'axes etc se font avec de entiers relatifs puisque vous raisonnez sur des pixels.
    les width div 2 etc, c'est rédibitoire lors d'une représentation graphique.
    => décalages...
    Moi, tous les calculs sont d'abord faits en réels et le round arrive au moment de l'affichage.

    @+

  8. #8
    Membre expérimenté
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    avril 2005
    Messages
    1 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : avril 2005
    Messages : 1 496
    Points : 1 670
    Points
    1 670
    Par défaut
    exemple basique d'utilisation :

    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
     
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs,Ugraphique,Uoutil;
     
    type
      TForm1 = class(TForm)
        procedure FormPaint(Sender: TObject);
        procedure FormCreate(Sender: TObject);
      private
        { Déclarations privées }
        graphique:Tgraphique;
        macourbe:TTrajectoire;
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.FormCreate(Sender: TObject);
    var i:integer;
    begin
    width:=screen.Width div 2;
    height:=width;
    position:=poscreencenter;
     
    setlength(macourbe,201);
     
    for i:=0 to 200 do begin
    macourbe[i].x:=(i-100)/10;
    if i<>100 then
    macourbe[i].y:=sqr(sin(macourbe[i].x)/macourbe[i].x) else macourbe[i].y:=1;
    end;
     
     
    graphique:=Tgraphique.create(clientwidth,clientheight,-10,10,-0.2,1.1);
    end;
     
    procedure TForm1.FormPaint(Sender: TObject);
    begin
    with graphique do begin
    obturation(clblack);
    canvas.pen.color:=clcream;
    tracerepere;
    canvas.pen.Width:=3;
    canvas.pen.color:=clred;
    tracecourbe(macourbe);
    canvas.pen.Width:=2;
    canvas.pen.color:=clcream;
    vecteur(-3,0.5,-0.5,sqr(sin(0.5)/0.5));
    font('arial',clcream,[fsbold],14);
    textout('sinus cardinal carré',-10,0.5);
    end;
    canvas.Draw(0,0,graphique);
    end;
     
     
    end.
    @+

  9. #9
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : juin 2005
    Messages : 1 756
    Points : 4 150
    Points
    4 150
    Par défaut
    C'est une erreur de croire que le GDI travaille sur des pixels.

    On exprime certe, les coordonnées avec des entiers, mais vous pouvez très bien configurer vos unités pour que ces dernières représentent des microns.
    Vous voulez tracer sin(x) ? Il suffit de tracer sin(x)*1000000 par exemple, puis d'ajuster l'échelle du device pour que la trace fasse à l'écran la dimension que vous voulez. C'est d'ailleurs comme ça qu'on dessine sur une imprimante.

    En fait le principe, c'est plutôt d'accorder l'unité utilisée pour définir les coordonnées à la résolution du device sur lequel on veut dessiner.
    L'intérêt de travailler avec des entiers pour les coordonnées, c'est d'avoir une précision constante, que l'on peut adapter en fonction du device sur lequel on va dessiner.

  10. #10
    Membre expérimenté
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    avril 2005
    Messages
    1 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : avril 2005
    Messages : 1 496
    Points : 1 670
    Points
    1 670
    Par défaut
    Ok, reprends mon exemple avec ta méthode et on compare.

  11. #11
    Membre expérimenté
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    avril 2005
    Messages
    1 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : avril 2005
    Messages : 1 496
    Points : 1 670
    Points
    1 670
    Par défaut
    pour s'amuser... avec un tchart, on ne peut pas faire ça :
    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
     
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs,Ugraphique,Uoutil;
     
    type
      TForm1 = class(TForm)
        procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
        procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
          Shift: TShiftState; X, Y: Integer);
        procedure FormMouseWheelUp(Sender: TObject; Shift: TShiftState;
          MousePos: TPoint; var Handled: Boolean);
        procedure FormMouseWheelDown(Sender: TObject; Shift: TShiftState;
          MousePos: TPoint; var Handled: Boolean);
        procedure FormPaint(Sender: TObject);
        procedure FormCreate(Sender: TObject);
      private
        { Déclarations privées }
        graphique:Tgraphique;
        macourbe:TTrajectoire;
        press:boolean;
         oldx,oldy:integer;
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    procedure TForm1.FormCreate(Sender: TObject);
    var i:integer;
    begin
    width:=screen.Width div 2;
    height:=width;
    position:=poscreencenter;
    setlength(macourbe,201);
    for i:=0 to 200 do begin
    macourbe[i].x:=(i-100)/10;
    if i<>100 then
    macourbe[i].y:=sqr(3*sin(macourbe[i].x)/macourbe[i].x) else macourbe[i].y:=9;
    end;
     
     
    graphique:=Tgraphique.create(clientwidth,clientheight,-10,10,-1,10);
    end;
     
    procedure TForm1.FormPaint(Sender: TObject);
    begin
    with graphique do begin
    obturation(clblack);
    canvas.pen.color:=clcream;
    tracerepere;
    canvas.pen.Width:=3;
    canvas.pen.color:=clred;
    tracecourbe(macourbe);
    canvas.pen.Width:=2;
    canvas.pen.color:=clcream;
    graduation;
    end;
    canvas.Draw(0,0,graphique);
    end;
     
     
    procedure TForm1.FormMouseWheelDown(Sender: TObject; Shift: TShiftState;
      MousePos: TPoint; var Handled: Boolean);
    begin
    graphique.zoom(1.1);
    formpaint(self);
    end;
     
    procedure TForm1.FormMouseWheelUp(Sender: TObject; Shift: TShiftState;
      MousePos: TPoint; var Handled: Boolean);
      begin
    graphique.zoom(0.9);
    formpaint(self);
    end;
     
    procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
    oldx:=x;
    oldy:=y;
    press:=true;
    screen.Cursor:=crhandpoint;
    end;
     
    procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
     
    begin
    if press then begin
                   graphique.depX(x-oldx);
                   graphique.depY(y-oldy);
                   formpaint(self);
                   end;
    oldx:=x;
    oldy:=y;
    end;
     
    procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    begin
    press:=false;
    screen.Cursor:=crdefault;
    end;
     
    end.
    le zoom, il faut le brider pour éviter les bugs...
    On peut même rajouter une mire avec les coordonnées etc

    après, on peut toujours améliorer suivant les besoins.

  12. #12
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : juin 2005
    Messages : 1 756
    Points : 4 150
    Points
    4 150
    Par défaut
    Citation Envoyé par Archimède Voir le message
    Ok, reprends mon exemple avec ta méthode et on compare.
    Aller, je suis joueur

    A gauche ta méthode, à droite la mienne. J'ai enlevé l'épaisseur des traits pour qu'on puisse bien aprécier la finesse du tracé...

    Comme tu peux le voir, ça revient exactement au même. Je dis juste qu'on peut se passer de réécrire toutes les fonctions du GDI pour appliquer automatiquement une transformation que le GDI est capable de faire tout seul.

    Mais bon, on commence à être franchement hors sujet.
    Fichiers attachés Fichiers attachés

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

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : avril 2005
    Messages : 1 496
    Points : 1 670
    Points
    1 670
    Par défaut
    Je te remercie... Je n'ai pas eu le temps de regarder, because le boulot...
    C'est sans doute très intéressant.
    Excuse, je n'avais pas l'impression d'être hors sujet vu l'évolution du compteur
    pour cette discussion.
    Je regarde et je m'en inspire pour améliorer mes unités graphiques.
    @+

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

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : avril 2005
    Messages : 1 496
    Points : 1 670
    Points
    1 670
    Par défaut
    Citation Envoyé par Franck SORIANO Voir le message
    Aller, je suis joueur

    A gauche ta méthode, à droite la mienne. J'ai enlevé l'épaisseur des traits pour qu'on puisse bien aprécier la finesse du tracé...

    Comme tu peux le voir, ça revient exactement au même. Je dis juste qu'on peut se passer de réécrire toutes les fonctions du GDI pour appliquer automatiquement une transformation que le GDI est capable de faire tout seul.

    Mais bon, on commence à être franchement hors sujet.
    Simplement un grand merci à toi avec beaucoup de retard...
    Le rendu est effectivement de meilleure qualité. Je m'incline lol.
    Je n'ai pas eu trop le temps de regarder avant...
    ça me donne beaucoup d'idées maintenant...

  15. #15
    Membre expérimenté
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    avril 2005
    Messages
    1 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : avril 2005
    Messages : 1 496
    Points : 1 670
    Points
    1 670
    Par défaut petit soucis
    Comment faire pour appliquer ces transfos là avec le canvas d'un bitmap ?
    Apparemment, ça ne fonctionne pas...

    Et là, pour moi, ça ne présente plus beaucoup d'intérêt...


  16. #16
    Membre expérimenté
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    avril 2005
    Messages
    1 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : avril 2005
    Messages : 1 496
    Points : 1 670
    Points
    1 670
    Par défaut + de précision...
    voilà, je me suis penché sur la question. J'ai essayé de construire une nouvelle unité graphique dont voici le début pour montrer le soucis :

    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
     
    unit Ugraphisme;
     
    interface
    uses Windows,graphics,Extctrls,types,classes,controls,math;
     
    type reel=extended;
     
    type Trpoint=record
    x,y:reel;
    end;
     
     
    type Tgraphique=class(Tbitmap)
    private
    r:Trect;
    xo,yo,xmin,ymin,xmax,ymax:reel;
    public
    constructor Create(w,h:integer;x1,x2,y1,y2:reel);reintroduce;overload;
    procedure line(x1,y1,x2,y2:reel);
    procedure obturation(cl:Tcolor);
    end;
     
    implementation
     
    const M:integer=1000000;
     
    constructor Tgraphique.Create(w,h:integer;x1,x2,y1,y2:reel);
    var XFrm:XForm;
    begin
    inherited create;
    width:=w;
    height:=h;
    //------------------------------
    xmin:=x1;
    xmax:=x2;
    ymin:=y1;
    ymax:=y2;
    //-------------------------------
    xFrm.eM11 :=w/(M*(xmax-xmin));
    xFrm.eM22 := -h/(M*(ymax-ymin));
    xFrm.eM12 := 0;
    xFrm.eM21 := 0;
    //--------------------------------
    xFrm.eDx :=-w*xmin/(xmax-xmin);
    xFrm.eDy :=ymax*h/(ymax-ymin);
    //--------------------------------
    SetGraphicsMode(Canvas.Handle, GM_ADVANCED);
    setworldtransform(canvas.handle,xFrm);
    //--------------------------------
     with r do begin
               left:=round(M*xmin);
               top:=-round(M*ymax);
               right:=round(M*xmax);
               bottom:=-round(M*ymin);
               end;
    end;
     
    procedure TGraphique.line(x1,y1,x2,y2:reel);
     
    begin
    with canvas do
                 begin
                 moveto(round(x1*M),round(y1*M));
                 lineto(round(x2*M),round(y2*M));
                 end;
    end;
     
    procedure Tgraphique.obturation(cl:Tcolor);
    begin
    with canvas do begin
                   brush.Color:=cl;
                   fillrect(r);
                   end;
    end;
     
     
    end.
    un essai tout simple :

    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
     
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ExtCtrls,Ugraphisme;
     
    type Trcourbe=array of Trpoint;
     
    type
      TForm1 = class(TForm)
        PaintBox1: TPaintBox;
        procedure FormCreate(Sender: TObject);
        procedure PaintBox1Paint(Sender: TObject);
      private
        { Déclarations privées }
    graphique:Tgraphique;
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
     
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
    graphique:=Tgraphique.Create(paintbox1.ClientWidth,paintbox1.clientheight,-10,10,-10,10);
     
    With graphique do
                    begin
                    obturation(clblack);
                    canvas.pen.Color:=clred;
                    line(-10,0,10,0);
                    line(0,-10,0,10);
                    end;
    end;
     
    procedure TForm1.PaintBox1Paint(Sender: TObject);
    begin
    paintbox1.Canvas.Draw(0,0,graphique);
    end;
     
    end.
    là pas de soucis;

    En revanche, si je fais ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    procedure TForm1.PaintBox1Paint(Sender: TObject);
    begin
    With graphique do
                    begin
                    obturation(clblack);
                    canvas.pen.Color:=clred;
                    line(-10,0,10,0);
                    line(0,-10,0,10);
                    end;
    paintbox1.Canvas.Draw(0,0,graphique);
    Et bien ça plante !

    Donc pas de possibilité de faire un graphique dynamique, utiliser un timer pour une animation, déplacer le graphe à la souris...

    on ne peut pas appliquer ces transformations en continu apparemment.

    C'est quoi la solution ?

  17. #17
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : juin 2005
    Messages : 1 756
    Points : 4 150
    Points
    4 150
    Par défaut
    Et bien ça plante !
    Question bête : Dans le cas qui "plante" tu as bien fait le create de graphique ?

    Deuxième question : Ca veut dire quoi "ça plante" ? Tu as un access violation ? Un message d'erreur particulier, ou simplement ça ne fait pas ce que tu attends ?

  18. #18
    Membre chevronné

    Profil pro
    Inscrit en
    août 2002
    Messages
    1 286
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : août 2002
    Messages : 1 286
    Points : 1 871
    Points
    1 871
    Par défaut
    Dans son cas les lignes rouges (LineTo) ne sont pas tracées.

    Je n'ai que le temps de faire des tests.

    En mettant un Pen.Width à 10 par exemple, on voit que les lignes sont affichées en 0,0 et non au milieu.

    Il a l'air de perdre la transformation de repère.
    Delphi 7/XE2/XE3
    C#
    Oracle 9i à 12c
    SQL Server 2008 à 2014

  19. #19
    Membre expérimenté
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    avril 2005
    Messages
    1 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : avril 2005
    Messages : 1 496
    Points : 1 670
    Points
    1 670
    Par défaut
    Citation Envoyé par Franck SORIANO Voir le message
    Question bête : Dans le cas qui "plante" tu as bien fait le create de graphique ?

    Deuxième question : Ca veut dire quoi "ça plante" ? Tu as un access violation ? Un message d'erreur particulier, ou simplement ça ne fait pas ce que tu attends ?

    Regarde mon code... le create de graphique est fait !

    Ce qui plante, c'est que les lignes devant être affichées au centre sont dessinées à 0,0 (coords info) donc sans prise en compte du changement d'origine...
    Gros soucis pour ta méthode, ça ne marche pas !

    reprends mon code, tu verras ...

    @+

  20. #20
    Membre expérimenté
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    avril 2005
    Messages
    1 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : avril 2005
    Messages : 1 496
    Points : 1 670
    Points
    1 670
    Par défaut
    Citation Envoyé par Linkin Voir le message

    Il a l'air de perdre la transformation de repère.
    exactement

Discussions similaires

  1. Travailler sur les Bitmap, ou sur les loaders directement
    Par minimolo dans le forum ActionScript 3
    Réponses: 4
    Dernier message: 14/12/2008, 13h08
  2. Programme qui travaille mais ne se termine jamais
    Par nialcen dans le forum Prolog
    Réponses: 3
    Dernier message: 20/11/2008, 09h41
  3. [PHP-JS] Script qui travaille dans le vide
    Par bsc-concept dans le forum Langage
    Réponses: 5
    Dernier message: 30/01/2007, 16h04
  4. pc qui "travaille", pourquoi ?
    Par lavazavio dans le forum Windows XP
    Réponses: 11
    Dernier message: 11/01/2007, 00h20
  5. Réponses: 4
    Dernier message: 07/10/2005, 19h34

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