Dessins [Résolu]

Messages postés
51
Date d'inscription
lundi 13 juin 2005
Dernière intervention
25 juillet 2006
- - Dernière réponse : ThWilliam
Messages postés
424
Date d'inscription
mardi 3 janvier 2006
Dernière intervention
26 novembre 2013
- 3 mai 2006 à 18:11
Bonjour,


mon appli propose à l'utilisateur de positionner des images (genre
triangle) sur une carte (image bmp ou jpg). Certains de ces triangles
seront reliés entre eux par une double flèche qui peut changer de
couleur.


Après maintes lecture de tutoriel et sujets de forum, est-ce que
quelqu'un pourrait m'aider à découvrir le graphisme sous DELPHI.


Ma situation actuelle : j'ai suivi ce tutoriel
c'est à dire placer un paintbox, puis dessiner des formes dans des
"rect". je relies ces formes avec "Lineto". Or lorsque je bouges mes
triangles, les lignes précédemment tracées s'effacent et ne relient plus les triangles. De plus, je ne
peux plus modifier la couleur des lignes une fois celles ci tracées (j'aimerai pour voir les identifier).
Enfin, je ne sais pas comment dessiner sur une carte (image bmp ou
jpg). pour l'instant, je me fais la main sur du fond blanc (paintbox)


Merci pour tout aide

Seb, 23 ans, Toulouse
débutant en delphi
Afficher la suite 

Votre réponse

6 réponses

Meilleure réponse
Messages postés
424
Date d'inscription
mardi 3 janvier 2006
Dernière intervention
26 novembre 2013
3
Merci
var ArrayImages: array of TMyImages;
Tu emploies donc un tableau dynamique. A la déclaration, ce tableau n'a aucune longueur donc appeler ArrayImages[0] ou [1]... va provoquer une violation d'accès. A mon avis, le problème est là pcq "centre:= point(X,Y)" = no problem.
Avant d'appeler un tableau dynamique, tu dois assigner sa longueur par SetLength
exemple : SetLength(ArrayImages, 10)
ce qui alloue 10 indices pour le tableau. Attention, le premier indice d'un tableau dynamique est toujours 0. Donc ici tu peux aller de [0] à [9].
L'intérêt d'un tableau dynamique est de pouvoir par après changer sa longueur.
SetLength(ArrayImages, 20) : te garde les valeurs des 10 premiers indices et t'en rajoute 10 tous neufs.
Dans ton cas, je partirais d'un tableau vide et je mettrais dans la procedure d'ajout de triangles :
SetLength(ArrayImages, Length(ArrayImages) + 1);
ainsi à chaque passage tu alloues un indice de plus.
Tant que j'y suis, je te renseigne la fonction High qui te donne le dernier indice du tableau
for i: = 0 to high(arrayimages)...
N'oublie pas de vider ton tableau quand tu n'en as plus besoin (p.ex. dans événement OnClose) :
SetLength(arrayimages,0);

Une remarque : pourquoi utiliser une structure Record qui ne comprend qu'un seul champ (centre) ?

A +
Thierry

Merci ThWilliam 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources a aidé 101 internautes ce mois-ci

Commenter la réponse de ThWilliam
Messages postés
459
Date d'inscription
lundi 19 avril 2004
Dernière intervention
8 avril 2009
0
Merci
En gros, dès que tu commences a bouger tes objects, faut effacer la ligne, et la retracer, donc tu le devines, va y avoir du code a mettre dans le OnPaint de ta form, ainsi que dans les evenement lié à la souris.


Allez, y a pas si longtemps, y a GuruCoder (merci Delphiprog) ici qui m'a filé un lien vers un truc puissantissime, qui me semble coller impec à ta demande.

http://castelain.developpez.com/sources/Bouboules/
Commenter la réponse de DeltaFX
Messages postés
424
Date d'inscription
mardi 3 janvier 2006
Dernière intervention
26 novembre 2013
0
Merci
Salut seba31stien.
Pour dessiner sur une image (carte), je te propose de placer un TImage avec propriété AutoSize = true. Tes formes et lignes seront dessinées sur le Canvas de ce TImage. Mais comme tu veux pouvoir déplacer les formes, il faut garder dans un bitmap en mémoire l'image originale.
Voici un aperçu de code dessinant des carrés lorsqu'on bouge la souris sur l'image. Code sommaire, simplement pour te montrer le principe.

...
var
   OrigBmp: TBitmap;  // bitmap mémoire
 
procedure TForm1.FormCreate(Sender: TObject);
begin
   OrigBmp:= TBitmap.Create;
   OrigBmp.PixelFormat:= pf24bit;
   OrigBmp.LoadFromFile('ton fichier.bmp'); // chargement de la carte dans OrigBmp
   Image1.Picture.Bitmap.Assign(OrigBmp);  // on l'affiche dans Image1
end;

procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
   with Image1 do
   begin
     Canvas.Draw(0,0,OrigBmp);  // on redessine toute l'image originale
     Canvas.Brush.Color:= clRed;
     Canvas.FrameRect(Rect(X - 30, Y - 30, X + 30, Y + 30));
   end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
   OrigBmp.Free;  // ne pas oublier de libérer le bitmap créé
end;

Ceci ne vaut que dans le cas où ton image originale est de taille raisonnable. Si tu emploies une image de plusieurs millions de pixels, la redessiner entièrement va prendre beaucoup trop de temps. Il faut alors mémoriser l'emplacement de la forme à déplacer dans un TRect pour redessiner uniquement cette partie.

var
  ...
  MemRect: TRect;

procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
   with Image1 do
   begin
     // redessin de la partie image originale
     Canvas.CopyRect(MemRect, OrigBmp.Canvas, MemRect);
     // mémorisation de l'emplacement nouvelle forme
     MemRect:= Rect(X-30, Y-30, X+30, Y+30);
     Canvas.Brush.Color:= clRed;
     Canvas.FrameRect(Rect(X - 30, Y - 30, X + 30, Y + 30));
   end;
end;

A +
Commenter la réponse de ThWilliam
Messages postés
51
Date d'inscription
lundi 13 juin 2005
Dernière intervention
25 juillet 2006
0
Merci
Je te remercie ThWilliam pour cette réponse. Je souhaiterai désormais
identifier par un numéro (j'ai pensé à un tableau) chaque triangle que
je positionnerai sur l'image, sans qu'il ne soit effacé dès qu'un
nouveau triangle est positionné ou déplacé, afin de pouvoir tracer des
flèches entre le triangle n°2 et la n°3 par exemple.

Seb, 23 ans, Toulouse
débutant en delphi
Commenter la réponse de seba31stien
Messages postés
424
Date d'inscription
mardi 3 janvier 2006
Dernière intervention
26 novembre 2013
0
Merci
Si tu n'emploies que des triangles et ayant la même couleur, tu peux simplement employer un tableau de TPoint ou de TRect pour mémoriser les positions. Je suppose que dans ton cas, le nombre de triangles n'est pas fixe; donc je te conseille d'utiliser un tableau dynamique. 

Si tu veux avoir une couleur propre à chaque triangle, ou dessiner aussi des rectangles, cercles... je te suggère ceci :

type
   ...
   TMyImagesStyles = (stTriangle, stRectangle, stCircle);
   TMyImages = record
         Style : TMyImagesStyles;
         Position : TRect;
         Color : TColor;
   end;

var
   ArrayImages: array of TMyImages;

dans ta procédure de redessin des images :

      with ArrayImages[I] do
      begin
         Image1.Canvas.Pen.Color : = clBlack;
         Image1.Canvas.Brush.Color := Color;
         case Style of
               stTriangle : ... //dessin en employant les coordonnées de Position
               stRectangle : ...
               stCircle : ... 
         end;
      end;

J'espère avoir répondu à ta question.
Si tu en a d'autres, n'hésite pas à les poser.
A +
Thierry
Commenter la réponse de ThWilliam
Messages postés
51
Date d'inscription
lundi 13 juin 2005
Dernière intervention
25 juillet 2006
0
Merci
Merci pour ton aide, j'avance petit à petit. Pourrais tu m'aider à
comprendre pourquoi j'ai violation d'accès lorsque je mémorise les
coordonnées du point où je lache la souris ?


type

   TMyImages = record

              centre : TPoint;

   end;

var

...

   ArrayImages: array of TMyImages;


procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;

  Shift: TShiftState; X, Y: Integer);

begin

  if drawing

  then begin

         drawing:=not drawing ;

         with ArrayImages[numero_courant] do

         begin

           centre:=point(X,Y); //  => provoque violation d'accès ....

         end;

       end;

end;


procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,

  Y: Integer);

var

  A,B,C,D,E,F,G : TPoint;

begin

 
A:=Point(X-10+0,                      
Y-15+(30));

......

  G:=Point(X-10+(20),            Y-15+(30));


 if drawing

 then with ArrayImages[numero_courant] do

      begin


         Image1.Picture.Bitmap.Assign(OrigBmp);  // on l'affiche dans Image1

                                                
// il faudra redessiner tous les autres sites

         ....

         Image1.Canvas.Polyline([A, F, C, D, E, B, G, F, B, C, E, F, B, A, G]);

      end;

Seb, 23 ans, Toulouse
débutant en delphi
Commenter la réponse de seba31stien

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.